diff --git a/src/library_pthread.js b/src/library_pthread.js index 1dee7b13e7422..01187cb417947 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -666,7 +666,7 @@ var LibraryPThread = { // Deduce which WebGL canvases (HTMLCanvasElements or OffscreenCanvases) should be passed over to the // Worker that hosts the spawned pthread. // Comma-delimited list of CSS selectors that must identify canvases by IDs: "#canvas1, #canvas2, ..." - var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 36, 'i32') }}} : 0; + var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 40, POINTER_TYPE) }}} : 0; #if OFFSCREENCANVASES_TO_PTHREAD // Proxied canvases string pointer -1 is used as a special token to fetch // whatever canvases were passed to build in -s diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h index c3768afec640b..64ebb875e168b 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h +++ b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h @@ -83,13 +83,18 @@ typedef long suseconds_t; #if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { + union { + int __i[10]; + volatile int __vi[10]; + unsigned __s[10]; + } __u; #ifdef __EMSCRIPTEN__ -// For canvas transfer implementation in Emscripten, use an extra 11th control field -// to pass a pointer to a string denoting the WebGL canvases to transfer. -typedef struct { union { int __i[11]; volatile int __vi[11]; unsigned __s[11]; } __u; } pthread_attr_t; -#else -typedef struct { union { int __i[10]; volatile int __vi[10]; unsigned __s[10]; } __u; } pthread_attr_t; + // For canvas transfer implementation in Emscripten, use an extra control field + // to pass a pointer to a string denoting the WebGL canvases to transfer. + const char *_a_transferredcanvases; #endif +} pthread_attr_t; #define __DEFINED_pthread_attr_t #endif @@ -114,7 +119,7 @@ typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __ #endif #if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) -typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t; +typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t; #define __DEFINED_pthread_rwlock_t #endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/limits.h b/system/lib/libc/musl/arch/emscripten/bits/limits.h index e688c35c65342..338b2f2ebe3bf 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/limits.h +++ b/system/lib/libc/musl/arch/emscripten/bits/limits.h @@ -4,5 +4,9 @@ #define LONG_BIT 32 #endif +#if __LP64__ +#define LONG_MAX 0x7fffffffffffffffL +#else #define LONG_MAX 0x7fffffffL +#endif #define LLONG_MAX 0x7fffffffffffffffLL diff --git a/system/lib/libc/musl/arch/emscripten/bits/stdint.h b/system/lib/libc/musl/arch/emscripten/bits/stdint.h index d1b2712199aca..2621b613fa189 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/stdint.h +++ b/system/lib/libc/musl/arch/emscripten/bits/stdint.h @@ -12,9 +12,22 @@ typedef uint32_t uint_fast32_t; #define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX +#if __LP64__ + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#define SIZE_MAX UINT64_MAX + +#else + #define INTPTR_MIN INT32_MIN #define INTPTR_MAX INT32_MAX #define UINTPTR_MAX UINT32_MAX #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX #define SIZE_MAX UINT32_MAX + +#endif diff --git a/system/lib/libc/musl/src/internal/pthread_impl.h b/system/lib/libc/musl/src/internal/pthread_impl.h index 1987c6037ecce..5d673f4c4a11c 100644 --- a/system/lib/libc/musl/src/internal/pthread_impl.h +++ b/system/lib/libc/musl/src/internal/pthread_impl.h @@ -112,7 +112,7 @@ struct __timer { // XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, so use an extra field // _rw_wr_owner to record which thread owns the write lock in order to avoid hangs. // Points to the pthread that currently has the write lock. -#define _rw_wr_owner __u.__vi[3] +#define _rw_wr_owner __u.__p[3] #endif #define _b_lock __u.__vi[0] #define _b_waiters __u.__vi[1] diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c index e1d6162f3b1d6..15a8acc1cacf1 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c @@ -5,13 +5,13 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct times #ifdef __EMSCRIPTEN__ /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. /// If attempting to lock the write lock that we already own, error out. - if (rw->_rw_wr_owner == (int)pthread_self()) return EDEADLK; + if (rw->_rw_wr_owner == (void *)pthread_self()) return EDEADLK; #endif int r, t; - + r = pthread_rwlock_trywrlock(rw); if (r != EBUSY) return r; - + int spins = 100; while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin(); @@ -27,7 +27,7 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct times #ifdef __EMSCRIPTEN__ /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. /// Mark this thread as the owner of this write lock. - rw->_rw_wr_owner = (int)pthread_self(); + rw->_rw_wr_owner = (void *)pthread_self(); #endif return r; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c index fdd08d39dbcc4..cf0f2c648e386 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c @@ -6,7 +6,7 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t *rw) #ifdef __EMSCRIPTEN__ /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. /// Mark this thread to own the write lock, to ignore multiple attempts to lock. - rw->_rw_wr_owner = (int)pthread_self(); + rw->_rw_wr_owner = (void *)pthread_self(); #endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c index 61d5e38646255..15b363dcafc41 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c @@ -7,7 +7,7 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rw) #ifdef __EMSCRIPTEN__ /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. /// Mark this thread to not own the write lock anymore. - if (rw->_rw_wr_owner == (int)pthread_self()) rw->_rw_wr_owner = 0; + if (rw->_rw_wr_owner == (void *)pthread_self()) rw->_rw_wr_owner = 0; #endif do { diff --git a/system/lib/pthread/emscripten_thread_state.s b/system/lib/pthread/emscripten_thread_state.S similarity index 80% rename from system/lib/pthread/emscripten_thread_state.s rename to system/lib/pthread/emscripten_thread_state.S index 151d23f2bea0b..c7b2d8c3a9627 100644 --- a/system/lib/pthread/emscripten_thread_state.s +++ b/system/lib/pthread/emscripten_thread_state.S @@ -1,6 +1,12 @@ -.globaltype __tls_base, i32 +#ifdef __wasm64__ +#define PTR i64 +#else +#define PTR i32 +#endif + +.globaltype __tls_base, PTR +.globaltype thread_id, PTR -.globaltype thread_id, i32 thread_id: .globaltype is_main_thread, i32 @@ -11,13 +17,13 @@ is_runtime_thread: .globl __pthread_self __pthread_self: - .functype __pthread_self () -> (i32) + .functype __pthread_self () -> (PTR) global.get thread_id end_function .globl _emscripten_thread_init _emscripten_thread_init: - .functype _emscripten_thread_init (i32, i32, i32) -> () + .functype _emscripten_thread_init (PTR, i32, i32) -> () local.get 0 global.set thread_id local.get 1 @@ -30,7 +36,7 @@ _emscripten_thread_init: # accessible from C/C++. .globl _emscripten_tls_base _emscripten_tls_base: - .functype _emscripten_tls_base () -> (i32) + .functype _emscripten_tls_base () -> (PTR) global.get __tls_base end_function diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c index 51c4b890ddd5a..e2231a3fe0fe0 100644 --- a/system/lib/pthread/library_pthread.c +++ b/system/lib/pthread/library_pthread.c @@ -33,18 +33,15 @@ #include #include -// Extra pthread_attr_t field: -#define _a_transferredcanvases __u.__s[9] - void __pthread_testcancel(); int emscripten_pthread_attr_gettransferredcanvases(const pthread_attr_t* a, const char** str) { - *str = (const char*)a->_a_transferredcanvases; + *str = a->_a_transferredcanvases; return 0; } int emscripten_pthread_attr_settransferredcanvases(pthread_attr_t* a, const char* str) { - a->_a_transferredcanvases = (int)str; + a->_a_transferredcanvases = str; return 0; } @@ -163,7 +160,7 @@ static void _do_call(em_queued_call* q) { break; case EM_PROXIED_JS_FUNCTION: q->returnValue.d = - emscripten_receive_on_main_thread_js((int)q->functionPtr, q->args[0].i, &q->args[1].d); + emscripten_receive_on_main_thread_js((int)(size_t)q->functionPtr, q->args[0].i, &q->args[1].d); break; case EM_FUNC_SIG_V: ((em_func_v)q->functionPtr)(); @@ -654,7 +651,8 @@ double emscripten_run_in_main_runtime_thread_js(int index, int num_args, int64_t } c->calleeDelete = 1-sync; c->functionEnum = EM_PROXIED_JS_FUNCTION; - c->functionPtr = (void*)index; + // Index not needed to ever be more than 32-bit. + c->functionPtr = (void*)(size_t)index; assert(num_args+1 <= EM_QUEUED_JS_CALL_MAX_ARGS); // The types are only known at runtime in these calls, so we store values that // must be able to contain any valid JS value, including a 64-bit BigInt if diff --git a/tools/system_libs.py b/tools/system_libs.py index 9705bfbcf51d9..d8aad87ae8789 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -742,7 +742,7 @@ def get_files(self): 'pthread_join.c', 'pthread_testcancel.c', 'emscripten_proxy_main.c', - 'emscripten_thread_state.s', + 'emscripten_thread_state.S', ]) else: ignore += ['thread']