diff --git a/.gitignore b/.gitignore index 8043b6b6..68fa3dd3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ config.mak lib/musl-gcc.specs /obj/ +.idea/* diff --git a/arch/wasm32/atomic_arch.h b/arch/wasm32/atomic_arch.h index 78b183cb..0f3c5478 100644 --- a/arch/wasm32/atomic_arch.h +++ b/arch/wasm32/atomic_arch.h @@ -4,7 +4,7 @@ #include -#define a_barrier() syscall(__NR_membarrier) +#define a_barrier() (0) #define a_cas a_cas static inline int a_cas(volatile int *p, int t, int s) diff --git a/arch/wasm32/pthread_arch.h b/arch/wasm32/pthread_arch.h index 212f4e12..6c5a7161 100644 --- a/arch/wasm32/pthread_arch.h +++ b/arch/wasm32/pthread_arch.h @@ -7,3 +7,13 @@ static inline struct pthread *__pthread_self(void) { #define CANCEL_REG_IP 16 #define MC_PC gregs[REG_EIP] + +#define __wait __wait +static inline void __wait(volatile int *addr, volatile int *waiters, int cnt, int priv) {} +static inline void __wake(volatile void *addr, int cnt, int priv) {} +static inline void __futexwait(volatile void *addr, int val, int priv) {} + +#define __block_all_sigs __block_all_sigs +static inline void __block_all_sigs(void *set) {} +static inline void __block_app_sigs(void *set) {} +static inline void __restore_sigs(void *set) {} diff --git a/src/internal/malloc_impl.h b/src/internal/malloc_impl.h index 5d025b06..8039ee82 100644 --- a/src/internal/malloc_impl.h +++ b/src/internal/malloc_impl.h @@ -34,7 +34,13 @@ struct bin { #define C_INUSE ((size_t)1) +#ifndef __wasm__ #define IS_MMAPPED(c) !((c)->csize & (C_INUSE)) +#else +#undef MMAP_THRESHOLD +#define MMAP_THRESHOLD ((size_t)-1) +#define IS_MMAPPED(c) (0) +#endif __attribute__((__visibility__("hidden"))) void __bin_chunk(struct chunk *); diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index c2deffb9..cece1953 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -150,6 +150,8 @@ void __vm_unlock(void); int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int); int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int); + +#ifndef __wait void __wait(volatile int *, volatile int *, int, int); static inline void __wake(volatile void *addr, int cnt, int priv) { @@ -164,14 +166,17 @@ static inline void __futexwait(volatile void *addr, int val, int priv) __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAIT, val); } +#endif void __acquire_ptc(void); void __release_ptc(void); void __inhibit_ptc(void); +#ifndef __block_all_sigs void __block_all_sigs(void *); void __block_app_sigs(void *); void __restore_sigs(void *); +#endif #define DEFAULT_STACK_SIZE 81920 #define DEFAULT_GUARD_SIZE 4096 diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index d72883e1..74a23afb 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -99,6 +99,7 @@ static int bin_index_up(size_t x) if (x <= 32) return x; x--; if (x < 512) return bin_tab[x/8-4] + 1; + if (x > 0x1c00) return 64; return bin_tab[x/128-4] + 17; } @@ -283,6 +284,34 @@ static void trim(struct chunk *self, size_t n) __bin_chunk(split); } +// returns chunk which size is more then given n from the 63-th unsorted bin +// if there is no suitable chunk returns 0 +static struct chunk *get_chunk_from_unsorted_bin(size_t n) +{ + const int unsorted_bin_id = 63; + struct chunk *current = 0; + + lock_bin(unsorted_bin_id); + current = mal.bins[unsorted_bin_id].head; + + while(current != 0 && current != mal.bins[unsorted_bin_id].tail) { + // use the simple first-fit strategy + if(current->csize >= n) { + if (!pretrim(current, n, unsorted_bin_id, unsorted_bin_id)) { + unbin(current, unsorted_bin_id); + } + + unlock_bin(unsorted_bin_id); + return current; + } + + current = current->next; + } + + unlock_bin(unsorted_bin_id); + return 0; +} + void *malloc(size_t n) { struct chunk *c; @@ -293,7 +322,7 @@ void *malloc(size_t n) if (n > MMAP_THRESHOLD) { size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE; char *base = __mmap(0, len, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (base == (void *)-1) return 0; c = (void *)(base + SIZE_ALIGN - OVERHEAD); c->csize = len - (SIZE_ALIGN - OVERHEAD); @@ -304,17 +333,25 @@ void *malloc(size_t n) i = bin_index_up(n); for (;;) { uint64_t mask = mal.binmap & -(1ULL<psize = c->csize = - x->csize + CHUNK_SIZE(c); + x->csize + CHUNK_SIZE(c); } break; } + j = first_set(mask); lock_bin(j); c = mal.bins[j].head; diff --git a/src/malloc/wasm32/expand_heap.c b/src/malloc/wasm32/expand_heap.c new file mode 100644 index 00000000..8c22c63d --- /dev/null +++ b/src/malloc/wasm32/expand_heap.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include "libc.h" +#include "syscall.h" + +#define WASM_PAGE_SIZE 65536 + +/* Expand the heap in-place use WebAssembly grow_memory operators. + * The caller is responsible for locking to prevent concurrent calls. */ + +void *__expand_heap(size_t *pn) +{ + size_t n = *pn; + n += -n & WASM_PAGE_SIZE-1; + unsigned delta = n / WASM_PAGE_SIZE; + + unsigned res = __builtin_wasm_memory_grow(0, delta); + if (res == (unsigned)-1) { + errno = ENOMEM; + return 0; + } + + void *area = (void*)(WASM_PAGE_SIZE * res); + *pn = n; + return area; +} diff --git a/src/mman/wasm32/madvise.c b/src/mman/wasm32/madvise.c new file mode 100644 index 00000000..8d8869d9 --- /dev/null +++ b/src/mman/wasm32/madvise.c @@ -0,0 +1,6 @@ +#include +#include "libc.h" + +int __madvise(void *addr, size_t len, int advice) { return 0; } + +weak_alias(__madvise, madvise); diff --git a/src/signal/wasm32/block.c b/src/signal/wasm32/block.c new file mode 100644 index 00000000..620c5fa1 --- /dev/null +++ b/src/signal/wasm32/block.c @@ -0,0 +1 @@ +#include "pthread_impl.h" diff --git a/src/signal/wasm32/raise.c b/src/signal/wasm32/raise.c new file mode 100644 index 00000000..81e69cf8 --- /dev/null +++ b/src/signal/wasm32/raise.c @@ -0,0 +1,3 @@ +#include + +int raise(int sig) { } diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c index a7cd0923..af66379a 100644 --- a/src/stdio/vfwscanf.c +++ b/src/stdio/vfwscanf.c @@ -215,7 +215,8 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) if (t == 'c') { if (width<1) width = 1; invert = 1; - set = L""; + static const wchar_t empty[] = { 0 }; + set = empty; } else if (t == 's') { invert = 1; static const wchar_t spaces[] = { diff --git a/src/stdlib/wcstod.c b/src/stdlib/wcstod.c index 26fe9af8..bd1ef040 100644 --- a/src/stdlib/wcstod.c +++ b/src/stdlib/wcstod.c @@ -12,8 +12,9 @@ static size_t do_read(FILE *f, unsigned char *buf, size_t len) { size_t i; const wchar_t *wcs = f->cookie; + static const wchar_t strudel[] = { '@', 0 }; - if (!wcs[0]) wcs=L"@"; + if (!wcs[0]) wcs=strudel; for (i=0; ibuf_size && wcs[i]; i++) f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; f->rpos = f->buf; diff --git a/src/stdlib/wcstol.c b/src/stdlib/wcstol.c index 4443f577..4744910e 100644 --- a/src/stdlib/wcstol.c +++ b/src/stdlib/wcstol.c @@ -14,8 +14,9 @@ static size_t do_read(FILE *f, unsigned char *buf, size_t len) { size_t i; const wchar_t *wcs = f->cookie; + static const wchar_t strudel[] = { '@', 0 }; - if (!wcs[0]) wcs=L"@"; + if (!wcs[0]) wcs=strudel; for (i=0; ibuf_size && wcs[i]; i++) f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; f->rpos = f->buf; diff --git a/src/thread/wasm32/__wait.c b/src/thread/wasm32/__wait.c new file mode 100644 index 00000000..d7ebd15a --- /dev/null +++ b/src/thread/wasm32/__wait.c @@ -0,0 +1,2 @@ +#include "pthread_impl.h" +