6 #define PGMASK (PGSIZE - 1)
8 #define MSETLEN (1 << 15)
15 static struct mset
*pool
;
17 static int mk_pool(void)
19 if (pool
&& !pool
->refs
) {
20 pool
->size
= sizeof(*pool
);
23 pool
= mmap(NULL
, MSETLEN
, PROT_READ
| PROT_WRITE
,
24 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
25 if (pool
== MAP_FAILED
) {
29 pool
->size
= sizeof(*pool
);
38 m
= mmap(NULL
, n
+ PGSIZE
, PROT_READ
| PROT_WRITE
,
39 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
42 *(long *) m
= n
+ PGSIZE
; /* store length in the first page */
45 if (!pool
|| MSETLEN
- pool
->size
< n
+ sizeof(void *))
48 m
= (void *) pool
+ pool
->size
;
49 *(void **) m
= pool
; /* the address of the owning mset */
51 pool
->size
+= (n
+ sizeof(void *) + 7) & ~7;
52 if (!((unsigned long) (pool
+ pool
->size
+ sizeof(void *)) & PGMASK
))
53 pool
->size
+= sizeof(long);
54 return m
+ sizeof(void *);
57 void *calloc(long n
, long sz
)
59 void *r
= malloc(n
* sz
);
69 if ((unsigned long) v
& PGMASK
) {
70 struct mset
*mset
= *(void **) (v
- sizeof(void *));
72 if (!mset
->refs
&& mset
!= pool
)
73 munmap(mset
, mset
->size
);
75 munmap(v
- PGSIZE
, *(long *) (v
- PGSIZE
));