git diff 2b74315d8a31ad8fbcd369116c82e055e0ec3fb7...b9b2db2f374bce907fa5015c9cf63205054f2356 diff --git a/arch/microblaze/syscall_arch.h b/arch/microblaze/syscall_arch.h index 70217ff..cab4607 100644 --- a/arch/microblaze/syscall_arch.h +++ b/arch/microblaze/syscall_arch.h @@ -13,7 +13,7 @@ static __inline long __syscall0(long n) register unsigned long r3 __asm__("r3"); __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12) - : "memory"); + : "memory", "r4"); return r3; } @@ -24,7 +24,7 @@ static inline long __syscall1(long n, long a) register unsigned long r5 __asm__("r5") = a; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5) - : "memory"); + : "memory", "r4"); return r3; } @@ -36,7 +36,7 @@ static inline long __syscall2(long n, long a, long b) register unsigned long r6 __asm__("r6") = b; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5), "r"(r6) - : "memory"); + : "memory", "r4"); return r3; } @@ -49,7 +49,7 @@ static inline long __syscall3(long n, long a, long b, long c) register unsigned long r7 __asm__("r7") = c; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5), "r"(r6), "r"(r7) - : "memory"); + : "memory", "r4"); return r3; } @@ -63,7 +63,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d) register unsigned long r8 __asm__("r8") = d; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8) - : "memory"); + : "memory", "r4"); return r3; } @@ -78,7 +78,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) register unsigned long r9 __asm__("r9") = e; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8), "r"(r9) - : "memory"); + : "memory", "r4"); return r3; } @@ -94,7 +94,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo register unsigned long r10 __asm__("r10") = f; __asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3) : "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8), "r"(r9), "r"(r10) - : "memory"); + : "memory", "r4"); return r3; } diff --git a/include/search.h b/include/search.h index 27f6107..02e407e 100644 --- a/include/search.h +++ b/include/search.h @@ -22,6 +22,18 @@ int hcreate(size_t); void hdestroy(void); ENTRY *hsearch(ENTRY, ACTION); +#ifdef _GNU_SOURCE +struct hsearch_data { + struct __tab *__tab; + unsigned int __unused1; + unsigned int __unused2; +}; + +int hcreate_r(size_t, struct hsearch_data *); +void hdestroy_r(struct hsearch_data *); +int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); +#endif + void insque(void *, void *); void remque(void *); diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index d6ad904..7932a97 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -37,6 +37,7 @@ static struct { struct bin bins[64]; int brk_lock[2]; int free_lock[2]; + unsigned mmap_step; } mal; @@ -162,7 +163,28 @@ static struct chunk *expand_heap(size_t n) new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE; n = new - mal.brk; - if (__brk(new) != new) goto fail; + if (__brk(new) != new) { + size_t min = (size_t)PAGE_SIZE << mal.mmap_step/2; + n += -n & PAGE_SIZE-1; + if (n < min) n = min; + void *area = __mmap(0, n, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (area == MAP_FAILED) goto fail; + + mal.mmap_step++; + area = (char *)area + SIZE_ALIGN - OVERHEAD; + w = area; + n -= SIZE_ALIGN; + w->psize = 0 | C_INUSE; + w->csize = n | C_INUSE; + w = NEXT_CHUNK(w); + w->psize = n | C_INUSE; + w->csize = 0 | C_INUSE; + + unlock(mal.brk_lock); + + return area; + } w = MEM_TO_CHUNK(new); w->psize = n | C_INUSE; diff --git a/src/search/hsearch.c b/src/search/hsearch.c index 6fe5ced..5c89651 100644 --- a/src/search/hsearch.c +++ b/src/search/hsearch.c @@ -1,6 +1,8 @@ +#define _GNU_SOURCE #include #include #include +#include "libc.h" /* open addressing hash table with 2^n table size @@ -14,14 +16,17 @@ with the posix api items cannot be iterated and length cannot be queried #define MINSIZE 8 #define MAXSIZE ((size_t)-1/2 + 1) -struct elem { - ENTRY item; - size_t hash; +struct __tab { + ENTRY *entries; + size_t mask; + size_t used; }; -static size_t mask; -static size_t used; -static struct elem *tab; +static struct hsearch_data htab; + +int __hcreate_r(size_t, struct hsearch_data *); +void __hdestroy_r(struct hsearch_data *); +int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); static size_t keyhash(char *k) { @@ -33,30 +38,30 @@ static size_t keyhash(char *k) return h; } -static int resize(size_t nel) +static int resize(size_t nel, struct hsearch_data *htab) { size_t newsize; size_t i, j; - struct elem *e, *newe; - struct elem *oldtab = tab; - struct elem *oldend = tab + mask + 1; + ENTRY *e, *newe; + ENTRY *oldtab = htab->__tab->entries; + ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1; if (nel > MAXSIZE) nel = MAXSIZE; for (newsize = MINSIZE; newsize < nel; newsize *= 2); - tab = calloc(newsize, sizeof *tab); - if (!tab) { - tab = oldtab; + htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries); + if (!htab->__tab->entries) { + htab->__tab->entries = oldtab; return 0; } - mask = newsize - 1; + htab->__tab->mask = newsize - 1; if (!oldtab) return 1; for (e = oldtab; e < oldend; e++) - if (e->item.key) { - for (i=e->hash,j=1; ; i+=j++) { - newe = tab + (i & mask); - if (!newe->item.key) + if (e->key) { + for (i=keyhash(e->key),j=1; ; i+=j++) { + newe = htab->__tab->entries + (i & htab->__tab->mask); + if (!newe->key) break; } *newe = *e; @@ -67,29 +72,22 @@ static int resize(size_t nel) int hcreate(size_t nel) { - mask = 0; - used = 0; - tab = 0; - return resize(nel); + return __hcreate_r(nel, &htab); } void hdestroy(void) { - free(tab); - tab = 0; - mask = 0; - used = 0; + __hdestroy_r(&htab); } -static struct elem *lookup(char *key, size_t hash) +static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab) { size_t i, j; - struct elem *e; + ENTRY *e; for (i=hash,j=1; ; i+=j++) { - e = tab + (i & mask); - if (!e->item.key || - (e->hash==hash && strcmp(e->item.key, key)==0)) + e = htab->__tab->entries + (i & htab->__tab->mask); + if (!e->key || strcmp(e->key, key) == 0) break; } return e; @@ -97,22 +95,60 @@ static struct elem *lookup(char *key, size_t hash) ENTRY *hsearch(ENTRY item, ACTION action) { + ENTRY *e; + + __hsearch_r(item, action, &e, &htab); + return e; +} + +int __hcreate_r(size_t nel, struct hsearch_data *htab) +{ + int r; + + htab->__tab = calloc(1, sizeof *htab->__tab); + if (!htab->__tab) + return 0; + r = resize(nel, htab); + if (r == 0) { + free(htab->__tab); + htab->__tab = 0; + } + return r; +} +weak_alias(__hcreate_r, hcreate_r); + +void __hdestroy_r(struct hsearch_data *htab) +{ + if (htab->__tab) free(htab->__tab->entries); + free(htab->__tab); + htab->__tab = 0; +} +weak_alias(__hdestroy_r, hdestroy_r); + +int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab) +{ size_t hash = keyhash(item.key); - struct elem *e = lookup(item.key, hash); + ENTRY *e = lookup(item.key, hash, htab); - if (e->item.key) - return &e->item; - if (action == FIND) + if (e->key) { + *retval = e; + return 1; + } + if (action == FIND) { + *retval = 0; return 0; - e->item = item; - e->hash = hash; - if (++used > mask - mask/4) { - if (!resize(2*used)) { - used--; - e->item.key = 0; + } + *e = item; + if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) { + if (!resize(2*htab->__tab->used, htab)) { + htab->__tab->used--; + e->key = 0; + *retval = 0; return 0; } - e = lookup(item.key, hash); + e = lookup(item.key, hash, htab); } - return &e->item; + *retval = e; + return 1; } +weak_alias(__hsearch_r, hsearch_r); diff --git a/src/signal/arm/sigsetjmp.s b/src/signal/arm/sigsetjmp.s index acb0301..0e7bcd4 100644 --- a/src/signal/arm/sigsetjmp.s +++ b/src/signal/arm/sigsetjmp.s @@ -1,6 +1,9 @@ .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,%function +.type __sigsetjmp,%function sigsetjmp: +__sigsetjmp: str a2,[a1,#256] tst a2,a2 beq setjmp diff --git a/src/signal/i386/sigsetjmp.s b/src/signal/i386/sigsetjmp.s index 06e0a61..91c8c04 100644 --- a/src/signal/i386/sigsetjmp.s +++ b/src/signal/i386/sigsetjmp.s @@ -1,6 +1,9 @@ .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: mov 4(%esp),%eax mov 8(%esp),%ecx mov %ecx,24(%eax) diff --git a/src/signal/microblaze/sigsetjmp.s b/src/signal/microblaze/sigsetjmp.s index be869d6..2a23d14 100644 --- a/src/signal/microblaze/sigsetjmp.s +++ b/src/signal/microblaze/sigsetjmp.s @@ -1,6 +1,9 @@ .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: swi r6, r5, 72 beqi r6, setjmp@PLT diff --git a/src/signal/mips/sigsetjmp.s b/src/signal/mips/sigsetjmp.s index 502e079..133ca77 100644 --- a/src/signal/mips/sigsetjmp.s +++ b/src/signal/mips/sigsetjmp.s @@ -1,8 +1,11 @@ .set noreorder .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: lui $gp, %hi(_gp_disp) addiu $gp, %lo(_gp_disp) beq $5, $0, 1f diff --git a/src/signal/powerpc/sigsetjmp.s b/src/signal/powerpc/sigsetjmp.s index d7d1af3..461b737 100644 --- a/src/signal/powerpc/sigsetjmp.s +++ b/src/signal/powerpc/sigsetjmp.s @@ -1,6 +1,9 @@ .global sigsetjmp + .global __sigsetjmp .type sigsetjmp,%function + .type __sigsetjmp,%function sigsetjmp: +__sigsetjmp: #int sigsetjmp(sigjmp_buf buf, int save) # r3 r4 #0) store save into buf->__fl diff --git a/src/signal/sh/sigsetjmp.s b/src/signal/sh/sigsetjmp.s index f6cae80..7951f07 100644 --- a/src/signal/sh/sigsetjmp.s +++ b/src/signal/sh/sigsetjmp.s @@ -1,6 +1,9 @@ .global sigsetjmp -.type sigsetjmp, @function +.global __sigsetjmp +.type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: mov.l r5, @(36,r4) tst r5, r5 bf 2f diff --git a/src/signal/sigsetjmp.c b/src/signal/sigsetjmp.c index cb2257f..1bbe1a0 100644 --- a/src/signal/sigsetjmp.c +++ b/src/signal/sigsetjmp.c @@ -1,5 +1,6 @@ #include #include +#include "libc.h" /* !!! This function will not work unless the compiler performs * tail call optimization. Machine-specific asm versions should @@ -12,3 +13,5 @@ int sigsetjmp(sigjmp_buf buf, int save) pthread_sigmask(SIG_SETMASK, 0, (sigset_t *)buf->__ss); return setjmp(buf); } + +weak_alias(sigsetjmp, __sigsetjmp); diff --git a/src/signal/x32/sigsetjmp.s b/src/signal/x32/sigsetjmp.s index dc38f03..17436f0 100644 --- a/src/signal/x32/sigsetjmp.s +++ b/src/signal/x32/sigsetjmp.s @@ -1,7 +1,10 @@ /* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: andl %esi,%esi movq %rsi,64(%rdi) jz 1f diff --git a/src/signal/x86_64/sigsetjmp.s b/src/signal/x86_64/sigsetjmp.s index dc38f03..17436f0 100644 --- a/src/signal/x86_64/sigsetjmp.s +++ b/src/signal/x86_64/sigsetjmp.s @@ -1,7 +1,10 @@ /* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ .global sigsetjmp +.global __sigsetjmp .type sigsetjmp,@function +.type __sigsetjmp,@function sigsetjmp: +__sigsetjmp: andl %esi,%esi movq %rsi,64(%rdi) jz 1f