From 19296cd280bec49e1e542ce9db5f1bb921b3d7ae Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 27 Sep 2018 08:22:28 -0500 Subject: [PATCH 01/12] Native wasm32 expand_heap implementation --- src/malloc/wasm32/expand_heap.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/malloc/wasm32/expand_heap.c 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; +} From aba5aae061316f8f74a66245351edabd33207f87 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 27 Sep 2018 08:22:59 -0500 Subject: [PATCH 02/12] Stub __wait/__wake --- arch/wasm32/pthread_arch.h | 5 +++++ src/internal/pthread_impl.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/wasm32/pthread_arch.h b/arch/wasm32/pthread_arch.h index 212f4e12..1752ee8e 100644 --- a/arch/wasm32/pthread_arch.h +++ b/arch/wasm32/pthread_arch.h @@ -7,3 +7,8 @@ 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) {} diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index c2deffb9..8be15e0b 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,6 +166,7 @@ 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); From 82060f29f64f6b959f587ac44c8eb5e8a0046385 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 11 Oct 2018 14:59:37 -0500 Subject: [PATCH 03/12] noop a_barrier --- arch/wasm32/atomic_arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From 45757ea824a6ca894ddfb43479e8aa3b2c13d435 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 11 Oct 2018 15:02:17 -0500 Subject: [PATCH 04/12] Stub __block_all_sigs/__restore_sigs, and raise --- arch/wasm32/pthread_arch.h | 5 +++++ src/internal/pthread_impl.h | 2 ++ src/signal/wasm32/block.c | 1 + src/signal/wasm32/raise.c | 3 +++ src/thread/wasm32/__wait.c | 2 ++ 5 files changed, 13 insertions(+) create mode 100644 src/signal/wasm32/block.c create mode 100644 src/signal/wasm32/raise.c create mode 100644 src/thread/wasm32/__wait.c diff --git a/arch/wasm32/pthread_arch.h b/arch/wasm32/pthread_arch.h index 1752ee8e..6c5a7161 100644 --- a/arch/wasm32/pthread_arch.h +++ b/arch/wasm32/pthread_arch.h @@ -12,3 +12,8 @@ static inline struct pthread *__pthread_self(void) { 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/pthread_impl.h b/src/internal/pthread_impl.h index 8be15e0b..cece1953 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -172,9 +172,11 @@ 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/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/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" + From 5a0b0ec3aa5be6c541f82f61fe09e98420ca9cd7 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 11 Oct 2018 15:03:26 -0500 Subject: [PATCH 05/12] Disable MMAP in the malloc and stub madvise. --- src/internal/malloc_impl.h | 6 ++++++ src/mman/wasm32/madvise.c | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 src/mman/wasm32/madvise.c 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/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); From 2f9ae7b7a7f51487fb5c8cacc50050a25b56f7f3 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Tue, 23 Oct 2018 12:51:09 -0500 Subject: [PATCH 06/12] Fix bin_index_up --- src/malloc/malloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index d72883e1..b583c240 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 63; return bin_tab[x/128-4] + 17; } From 635de63a8afac4c5cf64265be6a4604e13033cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Mon, 8 Oct 2018 17:51:26 +0200 Subject: [PATCH 07/12] Fix pointer assignment errors Without this patch, the following error is emitted when compiling with the latest LLVM/Clang 8.x: ```text src/stdio/vfwscanf.c:218:9: error: assigning to 'const wchar_t *' (aka 'const unsigned int *') from 'int [1]' converts between pointers to integer types with different sign [-Werror,-Wpointer-sign] set = L""; ^ ~~~ 1 error generated. ``` --- src/stdio/vfwscanf.c | 3 ++- src/stdlib/wcstod.c | 3 ++- src/stdlib/wcstol.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) 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; From b6d60256a51417554bb2209a5dab20f8e5bb04f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Wed, 24 Oct 2018 13:42:00 +0200 Subject: [PATCH 08/12] Fix off-by-one error in bin_index_up --- src/malloc/malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index b583c240..74db51b7 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -99,7 +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 63; + if (x > 0x1c00) return 64; return bin_tab[x/128-4] + 17; } From 4d66a5607e5cd850d676f7eb7283183208a5eaa1 Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 2 Apr 2019 02:03:29 +0300 Subject: [PATCH 09/12] add idea dir to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) 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/* From 9cdf2f77d5f9e2ab40f2f3955301cdb4856cb7d1 Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 2 Apr 2019 02:04:15 +0300 Subject: [PATCH 10/12] fix unsorted bin problem --- src/malloc/malloc.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index 74db51b7..a8b93fbb 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -284,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 64-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) { + // it is a the 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; @@ -294,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); @@ -305,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; From 428d49984405d0b1fc1f487c26e799504a0228fd Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 2 Apr 2019 02:29:23 +0300 Subject: [PATCH 11/12] fix comment --- src/malloc/malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index a8b93fbb..20a94332 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -295,7 +295,7 @@ static struct chunk *get_chunk_from_unsorted_bin(size_t n) current = mal.bins[unsorted_bin_id].head; while(current != 0 && current != mal.bins[unsorted_bin_id].tail) { - // it is a the first-fit strategy + // 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); From 0ec2c066c3c068fb396bd1bd2588e6f57e14e3e8 Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 2 Apr 2019 13:58:16 +0300 Subject: [PATCH 12/12] fix cmt --- src/malloc/malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index 20a94332..74a23afb 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -284,7 +284,7 @@ static void trim(struct chunk *self, size_t n) __bin_chunk(split); } -// returns chunk which size is more then given n from the 64-th unsorted bin +// 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) {