diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 14 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 102 |
2 files changed, 84 insertions, 32 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index e206245cc2..f5ab9d70d9 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 | |||
@@ -33,7 +33,7 @@ | |||
33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 33 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 | .\" SUCH DAMAGE. | 34 | .\" SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: malloc.3,v 1.4 1996/09/26 04:19:41 tholo Exp $ | 36 | .\" $OpenBSD: malloc.3,v 1.5 1997/05/31 08:47:55 tholo Exp $ |
37 | .\" | 37 | .\" |
38 | .Dd August 27, 1996 | 38 | .Dd August 27, 1996 |
39 | .Dt MALLOC 3 | 39 | .Dt MALLOC 3 |
@@ -160,6 +160,18 @@ This can substantially aid in compacting memory. | |||
160 | ``utrace'' generate entries for ktrace(1) for all operations. | 160 | ``utrace'' generate entries for ktrace(1) for all operations. |
161 | Consult the source for this one. | 161 | Consult the source for this one. |
162 | 162 | ||
163 | .It X | ||
164 | ``xmalloc'' | ||
165 | rather than return failure, | ||
166 | .Xr abort 3 | ||
167 | the program with a diagnostic message on stderr. | ||
168 | It is the intention that this option be set at compile time by | ||
169 | including in the source: | ||
170 | .Bd -literal -offset indent | ||
171 | extern char *malloc_options; | ||
172 | malloc_options = "X"; | ||
173 | .Ed | ||
174 | |||
163 | .It Z | 175 | .It Z |
164 | ``zero'' fill some junk into the area allocated (see ``J''), | 176 | ``zero'' fill some junk into the area allocated (see ``J''), |
165 | except for the exact length the user asked for, which is zeroed. | 177 | except for the exact length the user asked for, which is zeroed. |
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index ae88e068ff..94525adfa5 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #if defined(LIBC_SCCS) && !defined(lint) | 10 | #if defined(LIBC_SCCS) && !defined(lint) |
11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $"; | 11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.25 1997/05/31 08:47:56 tholo Exp $"; |
12 | #endif /* LIBC_SCCS and not lint */ | 12 | #endif /* LIBC_SCCS and not lint */ |
13 | 13 | ||
14 | /* | 14 | /* |
@@ -37,14 +37,11 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ | |||
37 | */ | 37 | */ |
38 | #define SOME_JUNK 0xd0 /* as in "Duh" :-) */ | 38 | #define SOME_JUNK 0xd0 /* as in "Duh" :-) */ |
39 | 39 | ||
40 | /* | ||
41 | * No user serviceable parts behind this point. | ||
42 | */ | ||
43 | |||
44 | #include <stdio.h> | 40 | #include <stdio.h> |
45 | #include <stdlib.h> | 41 | #include <stdlib.h> |
46 | #include <string.h> | 42 | #include <string.h> |
47 | #include <unistd.h> | 43 | #include <unistd.h> |
44 | #include <fcntl.h> | ||
48 | #include <errno.h> | 45 | #include <errno.h> |
49 | #include <sys/types.h> | 46 | #include <sys/types.h> |
50 | #include <sys/param.h> | 47 | #include <sys/param.h> |
@@ -64,6 +61,26 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ | |||
64 | * returned by malloc/realloc. | 61 | * returned by malloc/realloc. |
65 | * | 62 | * |
66 | */ | 63 | */ |
64 | |||
65 | #if defined(__i386__) && defined(__FreeBSD__) | ||
66 | # define malloc_pageshift 12U | ||
67 | # define malloc_minsize 16U | ||
68 | #endif /* __i386__ && __FreeBSD__ */ | ||
69 | |||
70 | #if defined(__sparc__) && !defined(__OpenBSD__) | ||
71 | # define malloc_pageshirt 12U | ||
72 | # define malloc_minsize 16U | ||
73 | # define MAP_ANON (0) | ||
74 | # define USE_DEV_ZERO | ||
75 | # define MADV_FREE MADV_DONTNEED | ||
76 | #endif /* __sparc__ */ | ||
77 | |||
78 | /* Insert your combination here... */ | ||
79 | #if defined(__FOOCPU__) && defined(__BAROS__) | ||
80 | # define malloc_pageshift 12U | ||
81 | # define malloc_minsize 16U | ||
82 | #endif /* __FOOCPU__ && __BAROS__ */ | ||
83 | |||
67 | #ifdef __OpenBSD__ | 84 | #ifdef __OpenBSD__ |
68 | # if defined(__alpha__) || defined(__m68k__) || defined(__mips__) || \ | 85 | # if defined(__alpha__) || defined(__m68k__) || defined(__mips__) || \ |
69 | defined(__i386__) || defined(__m88k__) || defined(__ns32k__) || \ | 86 | defined(__i386__) || defined(__m88k__) || defined(__ns32k__) || \ |
@@ -73,7 +90,21 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ | |||
73 | # endif /* __i386__ */ | 90 | # endif /* __i386__ */ |
74 | #endif /* __OpenBSD__ */ | 91 | #endif /* __OpenBSD__ */ |
75 | 92 | ||
93 | #ifdef _THREAD_SAFE | ||
94 | #include <pthread.h> | ||
95 | static pthread_mutex_t malloc_lock; | ||
96 | #define THREAD_LOCK() pthread_mutex_lock(&malloc_lock) | ||
97 | #define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock) | ||
98 | #define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0); | ||
99 | #else | ||
100 | #define THREAD_LOCK() | ||
101 | #define THREAD_UNLOCK() | ||
102 | #define THREAD_LOCK_INIT() | ||
103 | #endif | ||
104 | |||
76 | /* | 105 | /* |
106 | * No user serviceable parts behind this point. | ||
107 | * | ||
77 | * This structure describes a page worth of chunks. | 108 | * This structure describes a page worth of chunks. |
78 | */ | 109 | */ |
79 | 110 | ||
@@ -144,6 +175,18 @@ struct pgfree { | |||
144 | #define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask))) | 175 | #define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask))) |
145 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo) | 176 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo) |
146 | 177 | ||
178 | /* fd of /dev/zero */ | ||
179 | #ifdef USE_DEV_ZERO | ||
180 | static int fdzero; | ||
181 | #define MMAP_FD fdzero | ||
182 | #define INIT_MMAP() \ | ||
183 | { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \ | ||
184 | wrterror("open of /dev/zero"); } | ||
185 | #else | ||
186 | #define MMAP_FD (-1) | ||
187 | #define INIT_MMAP() | ||
188 | #endif | ||
189 | |||
147 | /* Set when initialization has been done */ | 190 | /* Set when initialization has been done */ |
148 | static unsigned malloc_started; | 191 | static unsigned malloc_started; |
149 | 192 | ||
@@ -184,6 +227,9 @@ static int malloc_realloc; | |||
184 | static int malloc_hint; | 227 | static int malloc_hint; |
185 | #endif | 228 | #endif |
186 | 229 | ||
230 | /* xmalloc behaviour ? */ | ||
231 | static int malloc_xmalloc; | ||
232 | |||
187 | /* zero fill ? */ | 233 | /* zero fill ? */ |
188 | static int malloc_zero; | 234 | static int malloc_zero; |
189 | 235 | ||
@@ -217,6 +263,11 @@ char *malloc_options; | |||
217 | /* Name of the current public function */ | 263 | /* Name of the current public function */ |
218 | static char *malloc_func; | 264 | static char *malloc_func; |
219 | 265 | ||
266 | /* Macro for mmap */ | ||
267 | #define MMAP(size) \ | ||
268 | mmap((caddr_t)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \ | ||
269 | MMAP_FD, (off_t)0); | ||
270 | |||
220 | /* | 271 | /* |
221 | * Necessary function declarations | 272 | * Necessary function declarations |
222 | */ | 273 | */ |
@@ -291,11 +342,11 @@ wrterror(p) | |||
291 | char *p; | 342 | char *p; |
292 | { | 343 | { |
293 | char *q = " error: "; | 344 | char *q = " error: "; |
294 | suicide = 1; | ||
295 | write(2, __progname, strlen(__progname)); | 345 | write(2, __progname, strlen(__progname)); |
296 | write(2, malloc_func, strlen(malloc_func)); | 346 | write(2, malloc_func, strlen(malloc_func)); |
297 | write(2, q, strlen(q)); | 347 | write(2, q, strlen(q)); |
298 | write(2, p, strlen(p)); | 348 | write(2, p, strlen(p)); |
349 | suicide = 1; | ||
299 | #ifdef MALLOC_STATS | 350 | #ifdef MALLOC_STATS |
300 | if (malloc_stats) | 351 | if (malloc_stats) |
301 | malloc_dump(stderr); | 352 | malloc_dump(stderr); |
@@ -393,8 +444,7 @@ extend_pgdir(index) | |||
393 | */ | 444 | */ |
394 | 445 | ||
395 | /* Get new pages */ | 446 | /* Get new pages */ |
396 | new = (struct pginfo**) mmap(0, i * malloc_pagesize, PROT_READ|PROT_WRITE, | 447 | new = (struct pginfo**) MMAP(i * malloc_pagesize); |
397 | MAP_ANON|MAP_PRIVATE, -1, (off_t)0); | ||
398 | if (new == (struct pginfo **)-1) | 448 | if (new == (struct pginfo **)-1) |
399 | return 0; | 449 | return 0; |
400 | 450 | ||
@@ -423,6 +473,10 @@ malloc_init () | |||
423 | char *p, b[64]; | 473 | char *p, b[64]; |
424 | int i, j; | 474 | int i, j; |
425 | 475 | ||
476 | THREAD_LOCK_INIT(); | ||
477 | |||
478 | INIT_MMAP(); | ||
479 | |||
426 | #ifdef EXTRA_SANITY | 480 | #ifdef EXTRA_SANITY |
427 | malloc_junk = 1; | 481 | malloc_junk = 1; |
428 | #endif /* EXTRA_SANITY */ | 482 | #endif /* EXTRA_SANITY */ |
@@ -464,6 +518,8 @@ malloc_init () | |||
464 | case 'u': malloc_utrace = 0; break; | 518 | case 'u': malloc_utrace = 0; break; |
465 | case 'U': malloc_utrace = 1; break; | 519 | case 'U': malloc_utrace = 1; break; |
466 | #endif /* __FreeBSD__ */ | 520 | #endif /* __FreeBSD__ */ |
521 | case 'x': malloc_xmalloc = 0; break; | ||
522 | case 'X': malloc_xmalloc = 1; break; | ||
467 | case 'z': malloc_zero = 0; break; | 523 | case 'z': malloc_zero = 0; break; |
468 | case 'Z': malloc_zero = 1; break; | 524 | case 'Z': malloc_zero = 1; break; |
469 | default: | 525 | default: |
@@ -491,8 +547,8 @@ malloc_init () | |||
491 | #endif /* MALLOC_STATS */ | 547 | #endif /* MALLOC_STATS */ |
492 | 548 | ||
493 | /* Allocate one page for the page directory */ | 549 | /* Allocate one page for the page directory */ |
494 | page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE, | 550 | page_dir = (struct pginfo **) MMAP(malloc_pagesize); |
495 | MAP_ANON|MAP_PRIVATE, -1, (off_t)0); | 551 | |
496 | if (page_dir == (struct pginfo **) -1) | 552 | if (page_dir == (struct pginfo **) -1) |
497 | wrterror("mmap(2) failed, check limits.\n"); | 553 | wrterror("mmap(2) failed, check limits.\n"); |
498 | 554 | ||
@@ -745,9 +801,6 @@ imalloc(size) | |||
745 | size_t size; | 801 | size_t size; |
746 | { | 802 | { |
747 | void *result; | 803 | void *result; |
748 | #ifdef _THREAD_SAFE | ||
749 | int status; | ||
750 | #endif | ||
751 | 804 | ||
752 | if (!malloc_started) | 805 | if (!malloc_started) |
753 | malloc_init(); | 806 | malloc_init(); |
@@ -783,12 +836,9 @@ irealloc(ptr, size) | |||
783 | u_long osize, index; | 836 | u_long osize, index; |
784 | struct pginfo **mp; | 837 | struct pginfo **mp; |
785 | int i; | 838 | int i; |
786 | #ifdef _THREAD_SAFE | ||
787 | int status; | ||
788 | #endif | ||
789 | 839 | ||
790 | if (suicide) | 840 | if (suicide) |
791 | return 0; | 841 | abort(); |
792 | 842 | ||
793 | if (!malloc_started) { | 843 | if (!malloc_started) { |
794 | wrtwarning("malloc() has never been called.\n"); | 844 | wrtwarning("malloc() has never been called.\n"); |
@@ -1082,9 +1132,6 @@ ifree(ptr) | |||
1082 | { | 1132 | { |
1083 | struct pginfo *info; | 1133 | struct pginfo *info; |
1084 | int index; | 1134 | int index; |
1085 | #ifdef _THREAD_SAFE | ||
1086 | int status; | ||
1087 | #endif | ||
1088 | 1135 | ||
1089 | /* This is legal */ | 1136 | /* This is legal */ |
1090 | if (!ptr) | 1137 | if (!ptr) |
@@ -1124,17 +1171,6 @@ ifree(ptr) | |||
1124 | * These are the public exported interface routines. | 1171 | * These are the public exported interface routines. |
1125 | */ | 1172 | */ |
1126 | 1173 | ||
1127 | #ifdef _THREAD_SAFE | ||
1128 | #include <pthread.h> | ||
1129 | #include "pthread_private.h" | ||
1130 | static int malloc_lock; | ||
1131 | #define THREAD_LOCK() _thread_kern_sig_block(&malloc_lock); | ||
1132 | #define THREAD_UNLOCK() _thread_kern_sig_unblock(malloc_lock); | ||
1133 | #else | ||
1134 | #define THREAD_LOCK() | ||
1135 | #define THREAD_UNLOCK() | ||
1136 | #endif | ||
1137 | |||
1138 | static int malloc_active; | 1174 | static int malloc_active; |
1139 | 1175 | ||
1140 | void * | 1176 | void * |
@@ -1153,6 +1189,8 @@ malloc(size_t size) | |||
1153 | UTRACE(0, size, r); | 1189 | UTRACE(0, size, r); |
1154 | malloc_active--; | 1190 | malloc_active--; |
1155 | THREAD_UNLOCK(); | 1191 | THREAD_UNLOCK(); |
1192 | if (malloc_xmalloc && !r) | ||
1193 | wrterror("out of memory.\n"); | ||
1156 | return (r); | 1194 | return (r); |
1157 | } | 1195 | } |
1158 | 1196 | ||
@@ -1196,5 +1234,7 @@ realloc(void *ptr, size_t size) | |||
1196 | UTRACE(ptr, size, r); | 1234 | UTRACE(ptr, size, r); |
1197 | malloc_active--; | 1235 | malloc_active--; |
1198 | THREAD_UNLOCK(); | 1236 | THREAD_UNLOCK(); |
1237 | if (malloc_xmalloc && !r) | ||
1238 | wrterror("out of memory.\n"); | ||
1199 | return (r); | 1239 | return (r); |
1200 | } | 1240 | } |