Skip to content

Commit b1830cd

Browse files
committed
[Memory64] pthread libc changes for 64-bit
1 parent 0d8929f commit b1830cd

File tree

11 files changed

+53
-27
lines changed

11 files changed

+53
-27
lines changed

src/library_pthread.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ var LibraryPThread = {
666666
// Deduce which WebGL canvases (HTMLCanvasElements or OffscreenCanvases) should be passed over to the
667667
// Worker that hosts the spawned pthread.
668668
// Comma-delimited list of CSS selectors that must identify canvases by IDs: "#canvas1, #canvas2, ..."
669-
var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 36, 'i32') }}} : 0;
669+
var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 40, POINTER_TYPE) }}} : 0;
670670
#if OFFSCREENCANVASES_TO_PTHREAD
671671
// Proxied canvases string pointer -1 is used as a special token to fetch
672672
// whatever canvases were passed to build in -s

system/lib/libc/musl/arch/emscripten/bits/alltypes.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,18 @@ typedef long suseconds_t;
8383

8484

8585
#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
86+
typedef struct {
87+
union {
88+
int __i[10];
89+
volatile int __vi[10];
90+
unsigned __s[10];
91+
} __u;
8692
#ifdef __EMSCRIPTEN__
87-
// For canvas transfer implementation in Emscripten, use an extra 11th control field
88-
// to pass a pointer to a string denoting the WebGL canvases to transfer.
89-
typedef struct { union { int __i[11]; volatile int __vi[11]; unsigned __s[11]; } __u; } pthread_attr_t;
90-
#else
91-
typedef struct { union { int __i[10]; volatile int __vi[10]; unsigned __s[10]; } __u; } pthread_attr_t;
93+
// For canvas transfer implementation in Emscripten, use an extra control field
94+
// to pass a pointer to a string denoting the WebGL canvases to transfer.
95+
const char *_a_transferredcanvases;
9296
#endif
97+
} pthread_attr_t;
9398
#define __DEFINED_pthread_attr_t
9499
#endif
95100

@@ -114,7 +119,7 @@ typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __
114119
#endif
115120

116121
#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
117-
typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
122+
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;
118123
#define __DEFINED_pthread_rwlock_t
119124
#endif
120125

system/lib/libc/musl/arch/emscripten/bits/limits.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
#define LONG_BIT 32
55
#endif
66

7+
#if __LP64__
8+
#define LONG_MAX 0x7fffffffffffffffL
9+
#else
710
#define LONG_MAX 0x7fffffffL
11+
#endif
812
#define LLONG_MAX 0x7fffffffffffffffLL

system/lib/libc/musl/arch/emscripten/bits/stdint.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,22 @@ typedef uint32_t uint_fast32_t;
1212
#define UINT_FAST16_MAX UINT32_MAX
1313
#define UINT_FAST32_MAX UINT32_MAX
1414

15+
#if __LP64__
16+
17+
#define INTPTR_MIN INT64_MIN
18+
#define INTPTR_MAX INT64_MAX
19+
#define UINTPTR_MAX UINT64_MAX
20+
#define PTRDIFF_MIN INT64_MIN
21+
#define PTRDIFF_MAX INT64_MAX
22+
#define SIZE_MAX UINT64_MAX
23+
24+
#else
25+
1526
#define INTPTR_MIN INT32_MIN
1627
#define INTPTR_MAX INT32_MAX
1728
#define UINTPTR_MAX UINT32_MAX
1829
#define PTRDIFF_MIN INT32_MIN
1930
#define PTRDIFF_MAX INT32_MAX
2031
#define SIZE_MAX UINT32_MAX
32+
33+
#endif

system/lib/libc/musl/src/internal/pthread_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ struct __timer {
112112
// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, so use an extra field
113113
// _rw_wr_owner to record which thread owns the write lock in order to avoid hangs.
114114
// Points to the pthread that currently has the write lock.
115-
#define _rw_wr_owner __u.__vi[3]
115+
#define _rw_wr_owner __u.__p[3]
116116
#endif
117117
#define _b_lock __u.__vi[0]
118118
#define _b_waiters __u.__vi[1]

system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct times
55
#ifdef __EMSCRIPTEN__
66
/// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs.
77
/// If attempting to lock the write lock that we already own, error out.
8-
if (rw->_rw_wr_owner == (int)pthread_self()) return EDEADLK;
8+
if (rw->_rw_wr_owner == (int)(long)pthread_self()) return EDEADLK;
99
#endif
1010
int r, t;
11-
11+
1212
r = pthread_rwlock_trywrlock(rw);
1313
if (r != EBUSY) return r;
14-
14+
1515
int spins = 100;
1616
while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
1717

@@ -27,7 +27,7 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct times
2727
#ifdef __EMSCRIPTEN__
2828
/// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs.
2929
/// Mark this thread as the owner of this write lock.
30-
rw->_rw_wr_owner = (int)pthread_self();
30+
rw->_rw_wr_owner = (int)(long)pthread_self();
3131
#endif
3232
return r;
3333
}

system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
66
#ifdef __EMSCRIPTEN__
77
/// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs.
88
/// Mark this thread to own the write lock, to ignore multiple attempts to lock.
9-
rw->_rw_wr_owner = (int)pthread_self();
9+
rw->_rw_wr_owner = (int)(long)pthread_self();
1010
#endif
1111
return 0;
1212
}

system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rw)
77
#ifdef __EMSCRIPTEN__
88
/// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs.
99
/// Mark this thread to not own the write lock anymore.
10-
if (rw->_rw_wr_owner == (int)pthread_self()) rw->_rw_wr_owner = 0;
10+
if (rw->_rw_wr_owner == (int)(long)pthread_self()) rw->_rw_wr_owner = 0;
1111
#endif
1212

1313
do {

system/lib/pthread/emscripten_thread_state.s renamed to system/lib/pthread/emscripten_thread_state.S

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
.globaltype __tls_base, i32
1+
#ifdef __wasm64__
2+
#define PTR i64
3+
#else
4+
#define PTR i32
5+
#endif
6+
7+
.globaltype __tls_base, PTR
8+
.globaltype thread_id, PTR
29

3-
.globaltype thread_id, i32
410
thread_id:
511

612
.globaltype is_main_thread, i32
@@ -11,13 +17,13 @@ is_runtime_thread:
1117

1218
.globl __pthread_self
1319
__pthread_self:
14-
.functype __pthread_self () -> (i32)
20+
.functype __pthread_self () -> (PTR)
1521
global.get thread_id
1622
end_function
1723

1824
.globl _emscripten_thread_init
1925
_emscripten_thread_init:
20-
.functype _emscripten_thread_init (i32, i32, i32) -> ()
26+
.functype _emscripten_thread_init (PTR, i32, i32) -> ()
2127
local.get 0
2228
global.set thread_id
2329
local.get 1
@@ -30,7 +36,7 @@ _emscripten_thread_init:
3036
# accessible from C/C++.
3137
.globl _emscripten_tls_base
3238
_emscripten_tls_base:
33-
.functype _emscripten_tls_base () -> (i32)
39+
.functype _emscripten_tls_base () -> (PTR)
3440
global.get __tls_base
3541
end_function
3642

system/lib/pthread/library_pthread.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,15 @@
3333
#include <emscripten.h>
3434
#include <emscripten/threading.h>
3535

36-
// Extra pthread_attr_t field:
37-
#define _a_transferredcanvases __u.__s[9]
38-
3936
void __pthread_testcancel();
4037

4138
int emscripten_pthread_attr_gettransferredcanvases(const pthread_attr_t* a, const char** str) {
42-
*str = (const char*)a->_a_transferredcanvases;
39+
*str = a->_a_transferredcanvases;
4340
return 0;
4441
}
4542

4643
int emscripten_pthread_attr_settransferredcanvases(pthread_attr_t* a, const char* str) {
47-
a->_a_transferredcanvases = (int)str;
44+
a->_a_transferredcanvases = str;
4845
return 0;
4946
}
5047

@@ -163,7 +160,7 @@ static void _do_call(em_queued_call* q) {
163160
break;
164161
case EM_PROXIED_JS_FUNCTION:
165162
q->returnValue.d =
166-
emscripten_receive_on_main_thread_js((int)q->functionPtr, q->args[0].i, &q->args[1].d);
163+
emscripten_receive_on_main_thread_js((int)(size_t)q->functionPtr, q->args[0].i, &q->args[1].d);
167164
break;
168165
case EM_FUNC_SIG_V:
169166
((em_func_v)q->functionPtr)();
@@ -654,7 +651,8 @@ double emscripten_run_in_main_runtime_thread_js(int index, int num_args, int64_t
654651
}
655652
c->calleeDelete = 1-sync;
656653
c->functionEnum = EM_PROXIED_JS_FUNCTION;
657-
c->functionPtr = (void*)index;
654+
// Index not needed to ever be more than 32-bit.
655+
c->functionPtr = (void*)(size_t)index;
658656
assert(num_args+1 <= EM_QUEUED_JS_CALL_MAX_ARGS);
659657
// The types are only known at runtime in these calls, so we store values that
660658
// must be able to contain any valid JS value, including a 64-bit BigInt if

tools/system_libs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ def get_files(self):
742742
'pthread_join.c',
743743
'pthread_testcancel.c',
744744
'emscripten_proxy_main.c',
745-
'emscripten_thread_state.s',
745+
'emscripten_thread_state.S',
746746
])
747747
else:
748748
ignore += ['thread']

0 commit comments

Comments
 (0)