summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/malloc.314
-rw-r--r--src/lib/libc/stdlib/malloc.c102
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.
161Consult the source for this one. 161Consult the source for this one.
162 162
163.It X
164``xmalloc''
165rather than return failure,
166.Xr abort 3
167the program with a diagnostic message on stderr.
168It is the intention that this option be set at compile time by
169including in the source:
170.Bd -literal -offset indent
171extern char *malloc_options;
172malloc_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''),
165except for the exact length the user asked for, which is zeroed. 177except 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)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $"; 11static 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>
95static 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
180static 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 */
148static unsigned malloc_started; 191static unsigned malloc_started;
149 192
@@ -184,6 +227,9 @@ static int malloc_realloc;
184static int malloc_hint; 227static int malloc_hint;
185#endif 228#endif
186 229
230/* xmalloc behaviour ? */
231static int malloc_xmalloc;
232
187/* zero fill ? */ 233/* zero fill ? */
188static int malloc_zero; 234static 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 */
218static char *malloc_func; 264static 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"
1130static 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
1138static int malloc_active; 1174static int malloc_active;
1139 1175
1140void * 1176void *
@@ -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}