Skip to content

Commit 785752a

Browse files
committed
add glue code for mallocng merge
this includes both an implementation of reclaimed-gap donation from ldso and a version of mallocng's glue.h with namespace-safe linkage to underlying syscalls, integration with AT_RANDOM initialization, and internal locking that's optimized out when the process is single-threaded.
1 parent fdf8b2a commit 785752a

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

src/malloc/mallocng/README.mallocng

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
This directory is a skeleton for upcoming merge of musl's new malloc
2+
implementation, mallocng. To use it, drop in copies of or symlinks to
3+
the following files from mallocng:
4+
5+
- meta.h
6+
- malloc.c
7+
- realloc.c
8+
- free.c
9+
- aligned_alloc.c
10+
- malloc_usable_size.c
11+
12+
and build with make variable MALLOC_DIR=mallocng in config.mak or on
13+
make command line.

src/malloc/mallocng/donate.c

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <stdlib.h>
2+
#include <stdint.h>
3+
#include <limits.h>
4+
#include <string.h>
5+
#include <sys/mman.h>
6+
#include <errno.h>
7+
8+
#include "meta.h"
9+
10+
static void donate(unsigned char *base, size_t len)
11+
{
12+
uintptr_t a = (uintptr_t)base;
13+
uintptr_t b = a + len;
14+
a += -a & (UNIT-1);
15+
b -= b & (UNIT-1);
16+
memset(base, 0, len);
17+
for (int sc=47; sc>0 && b>a; sc-=4) {
18+
if (b-a < (size_classes[sc]+1)*UNIT) continue;
19+
struct meta *m = alloc_meta();
20+
m->avail_mask = 0;
21+
m->freed_mask = 1;
22+
m->mem = (void *)a;
23+
m->mem->meta = m;
24+
m->last_idx = 0;
25+
m->freeable = 0;
26+
m->sizeclass = sc;
27+
m->maplen = 0;
28+
*((unsigned char *)m->mem+UNIT-4) = 0;
29+
*((unsigned char *)m->mem+UNIT-3) = 255;
30+
m->mem->storage[size_classes[sc]*UNIT-4] = 0;
31+
queue(&ctx.active[sc], m);
32+
a += (size_classes[sc]+1)*UNIT;
33+
}
34+
}
35+
36+
void __malloc_donate(char *start, char *end)
37+
{
38+
donate((void *)start, end-start);
39+
}

src/malloc/mallocng/glue.h

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#ifndef MALLOC_GLUE_H
2+
#define MALLOC_GLUE_H
3+
4+
#include <stdint.h>
5+
#include <sys/mman.h>
6+
#include <pthread.h>
7+
#include <unistd.h>
8+
#include <elf.h>
9+
#include <string.h>
10+
#include "atomic.h"
11+
#include "syscall.h"
12+
#include "libc.h"
13+
#include "lock.h"
14+
#include "dynlink.h"
15+
16+
// use macros to appropriately namespace these.
17+
#define size_classes __malloc_size_classes
18+
#define ctx __malloc_context
19+
#define alloc_meta __malloc_alloc_meta
20+
#define is_allzero __malloc_allzerop
21+
#define dump_heap __dump_heap
22+
23+
#if USE_REAL_ASSERT
24+
#include <assert.h>
25+
#else
26+
#undef assert
27+
#define assert(x) do { if (!(x)) a_crash(); } while(0)
28+
#endif
29+
30+
#define brk(p) ((uintptr_t)__syscall(SYS_brk, p))
31+
32+
#define mmap __mmap
33+
#define madvise __madvise
34+
#define mremap __mremap
35+
36+
#define DISABLE_ALIGNED_ALLOC (__malloc_replaced && !__aligned_alloc_replaced)
37+
38+
static inline uint64_t get_random_secret()
39+
{
40+
uint64_t secret = (uintptr_t)&secret * 1103515245;
41+
for (size_t i=0; libc.auxv[i]; i+=2)
42+
if (libc.auxv[i]==AT_RANDOM)
43+
memcpy(&secret, (char *)libc.auxv[i+1]+8, sizeof secret);
44+
return secret;
45+
}
46+
47+
#ifndef PAGESIZE
48+
#define PAGESIZE PAGE_SIZE
49+
#endif
50+
51+
#define MT (libc.need_locks)
52+
53+
#define RDLOCK_IS_EXCLUSIVE 1
54+
55+
__attribute__((__visibility__("hidden")))
56+
extern int __malloc_lock[1];
57+
58+
#define LOCK_OBJ_DEF \
59+
int __malloc_lock[1];
60+
61+
static inline void rdlock()
62+
{
63+
if (MT) LOCK(__malloc_lock);
64+
}
65+
static inline void wrlock()
66+
{
67+
if (MT) LOCK(__malloc_lock);
68+
}
69+
static inline void unlock()
70+
{
71+
UNLOCK(__malloc_lock);
72+
}
73+
static inline void upgradelock()
74+
{
75+
}
76+
77+
#endif

0 commit comments

Comments
 (0)