Skip to content

Commit e05e72d

Browse files
authored
Update musl to v1.2.2 (#13006)
The changes here mostly come from running the update_musl.py script against the following commit: https://github.com/emscripten-core/musl/tree/merge_v1.2.2 Notes: - `weak` is defined in musl-internal headers so some of our usage of `__attribute__((weak))` was switched to `__weak__` (which is a synonym). - Quite a few changes needed in library_pthread.js due to changes to the internal representation of __pthread struct in C. - removal of emscripten-specific threadStatus field. This can can be fully replaced with the updated `detach_state` that was added to musl (along with enum values for states!) along with the existing `cancel` bit. - `attr` is no longer stored on `__pthread`; it was only duplicating other fields anyway. We now include `pthread_getattr_np.c` which can pull those field out on demand into at attr structure.
1 parent a872af6 commit e05e72d

File tree

911 files changed

+17687
-9902
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

911 files changed

+17687
-9902
lines changed

ChangeLog.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ to browse the changes between the tags.
1818

1919
See docs/process.md for more on how version tagging works.
2020

21-
2.0.35
21+
3.0.0
2222
------
23+
- The version of musl libc used by emscripten was upgraded from v1.1.15 to
24+
v1.2.2. There could be some minor size regressions (or gains) due to changes
25+
in upstream musl code but we don't expect anything major. Since this fairly
26+
change (at least internally) we are bumping the major version of emscripten
27+
to 3. (#13006)
2328

2429
2.0.34 - 11/04/2021
2530
-------------------

emscripten-version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.35-git
1+
3.0.0-git

src/library.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,9 @@ LibraryManager.library = {
594594
__localtime_r: 'localtime_r',
595595

596596
// musl-internal function used to implement both `asctime` and `asctime_r`
597-
__asctime__deps: ['mktime'],
598-
__asctime__sig: 'iii',
599-
__asctime: function(tmPtr, buf) {
597+
__asctime_r__deps: ['mktime'],
598+
__asctime_r__sig: 'iii',
599+
__asctime_r: function(tmPtr, buf) {
600600
var date = {
601601
tm_sec: {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'i32') }}},
602602
tm_min: {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_min, 'i32') }}},
@@ -632,11 +632,11 @@ LibraryManager.library = {
632632
return ret;
633633
},
634634

635-
ctime_r__deps: ['localtime_r', '__asctime', '$withStackSave'],
635+
ctime_r__deps: ['localtime_r', '__asctime_r', '$withStackSave'],
636636
ctime_r__sig: 'iii',
637637
ctime_r: function(time, buf) {
638638
return withStackSave(function() {
639-
return ___asctime(_localtime_r(time, stackAlloc({{{ C_STRUCTS.tm.__size__ }}})), buf);
639+
return ___asctime_r(_localtime_r(time, stackAlloc({{{ C_STRUCTS.tm.__size__ }}})), buf);
640640
});
641641
},
642642

src/library_pthread.js

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ var LibraryPThread = {
125125
},
126126
#endif
127127

128+
#if PTHREADS_DEBUG
129+
detachStateToString: function(state) {
130+
if (state === {{{ cDefine('DT_EXITED') }}}) return 'DT_EXITED';
131+
if (state === {{{ cDefine('DT_EXITING') }}}) return 'DT_EXITING';
132+
if (state === {{{ cDefine('DT_JOINABLE') }}}) return 'DT_JOINABLE';
133+
if (state === {{{ cDefine('DT_DETACHED') }}}) return 'DT_DETACHED';
134+
assert(false);
135+
},
136+
#endif
137+
138+
setDetachState: function(thread, newstate) {
139+
#if PTHREADS_DEBUG
140+
var oldstate = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detach_state }}}) >> 2);
141+
var oldname = PThread.detachStateToString(oldstate);
142+
var newname = PThread.detachStateToString(newstate);
143+
console.log('thread 0x' + thread.toString(16) + ' state change: ' + oldname + ' -> ' + newname);
144+
#endif
145+
Atomics.store(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detach_state }}}) >> 2, newstate);
146+
},
147+
128148
terminateAllThreads: function() {
129149
#if ASSERTIONS
130150
assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! terminateAllThreads() can only ever be called from main application thread!');
@@ -278,8 +298,8 @@ var LibraryPThread = {
278298
} else if (cmd === 'detachedExit') {
279299
#if ASSERTIONS
280300
assert(worker.pthread);
281-
var detached = Atomics.load(HEAPU32, (worker.pthread.threadInfoStruct + {{{ C_STRUCTS.pthread.detached }}}) >> 2);
282-
assert(detached);
301+
var detach_state = Atomics.load(HEAPU32, (worker.pthread.threadInfoStruct + {{{ C_STRUCTS.pthread.detach_state }}}) >> 2);
302+
assert(detach_state == {{{ cDefine('DT_EXITED') }}});
283303
#endif
284304
PThread.returnWorkerToPool(worker);
285305
} else if (cmd === 'cancelDone') {
@@ -570,19 +590,17 @@ var LibraryPThread = {
570590
worker: worker,
571591
stackBase: threadParams.stackBase,
572592
stackSize: threadParams.stackSize,
593+
initialState: {{{ cDefine('DT_JOINABLE') }}},
573594
allocatedOwnStack: threadParams.allocatedOwnStack,
574595
// Info area for this thread in Emscripten HEAP (shared)
575596
threadInfoStruct: threadParams.pthread_ptr
576597
};
577598
var tis = pthread.threadInfoStruct >> 2;
578599
// spawnThread is always called with a zero-initialized thread struct so
579600
// no need to set any valudes to zero here.
580-
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.detached }}} >> 2), threadParams.detached);
601+
PThread.setDetachState(pthread.threadInfoStruct, threadParams.initialState);
581602
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.stack_size }}} >> 2), threadParams.stackSize);
582603
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.stack }}} >> 2), stackHigh);
583-
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.attr }}} + 0/*_a_stacksize*/ >> 2), threadParams.stackSize);
584-
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.attr }}} + 8/*_a_stackaddr*/ >> 2), stackHigh);
585-
Atomics.store(HEAPU32, tis + ({{{ C_STRUCTS.pthread.attr }}} + 12/*_a_detach*/ >> 2), threadParams.detached);
586604

587605
#if PTHREADS_PROFILING
588606
PThread.createProfilerBlock(pthread.threadInfoStruct);
@@ -772,23 +790,16 @@ var LibraryPThread = {
772790

773791
var stackSize = 0;
774792
var stackBase = 0;
775-
// Default thread attr is PTHREAD_CREATE_JOINABLE, i.e. start as not detached.
776-
var detached = 0;
793+
// Default thread state is DT_JOINABLE, i.e. start as not detached.
794+
var initialState = {{{ cDefine('DT_JOINABLE') }}};
777795
// When musl creates C11 threads it passes __ATTRP_C11_THREAD (-1) which
778796
// treat as if it was NULL.
779797
if (attr && attr != {{{ cDefine('__ATTRP_C11_THREAD') }}}) {
780798
stackSize = {{{ makeGetValue('attr', 0/*_a_stacksize*/, 'i32') }}};
781-
// Musl has a convention that the stack size that is stored to the pthread
782-
// attribute structure is always musl's #define DEFAULT_STACK_SIZE
783-
// smaller than the actual created stack size. That is, stored stack size
784-
// of 0 would mean a stack of DEFAULT_STACK_SIZE in size. All musl
785-
// functions hide this impl detail, and offset the size transparently, so
786-
// pthread_*() API user does not see this offset when operating with
787-
// the pthread API. When reading the structure directly on JS side
788-
// however, we need to offset the size manually here.
789-
stackSize += {{{ cDefine('DEFAULT_STACK_SIZE') }}};
790799
stackBase = {{{ makeGetValue('attr', 8/*_a_stackaddr*/, 'i32') }}};
791-
detached = {{{ makeGetValue('attr', 12/*_a_detach*/, 'i32') }}} !== 0/*PTHREAD_CREATE_JOINABLE*/;
800+
if ({{{ makeGetValue('attr', 12/*_a_detach*/, 'i32') }}}) {
801+
initialState = {{{ cDefine('DT_DETACHED') }}};
802+
}
792803
} else {
793804
// According to
794805
// http://man7.org/linux/man-pages/man3/pthread_create.3.html, default
@@ -822,7 +833,7 @@ var LibraryPThread = {
822833
stackBase: stackBase,
823834
stackSize: stackSize,
824835
allocatedOwnStack: allocatedOwnStack,
825-
detached: detached,
836+
initialState: initialState,
826837
startRoutine: start_routine,
827838
pthread_ptr: pthread_ptr,
828839
arg: arg,
@@ -880,14 +891,19 @@ var LibraryPThread = {
880891
}
881892
var self = {{{ makeGetValue('thread', C_STRUCTS.pthread.self, 'i32') }}};
882893
if (self !== thread) {
883-
err('pthread_join attempted on thread ' + thread + ', which does not point to a valid thread, or does not exist anymore!');
894+
err('pthread_join attempted on thread 0x' + thread.toString(16) + ', which does not point to a valid thread, or does not exist anymore!');
884895
return {{{ cDefine('ESRCH') }}};
885896
}
886-
var detached = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detached }}} ) >> 2);
887-
if (detached) {
888-
err('Attempted to join thread ' + thread + ', which was already detached!');
897+
var detach_state = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detach_state }}}) >> 2);
898+
if (detach_state == {{{ cDefine('DT_DETACHED') }}}) {
899+
err('Attempted to join thread 0x' + thread.toString(16) + ', which was already detached!');
889900
return {{{ cDefine('EINVAL') }}}; // The thread is already detached, can no longer join it!
890901
}
902+
903+
if (detach_state == {{{ cDefine('DT_EXITED') }}}) {
904+
err('Attempted to join thread 0x' + thread.toString(16) + ', which was already joined!');
905+
return {{{ cDefine('EINVAL') }}};
906+
}
891907
if (ENVIRONMENT_IS_PTHREAD && _pthread_self() == thread) {
892908
err('PThread ' + thread + ' is attempting to join to itself!');
893909
return {{{ cDefine('EDEADLK') }}};
@@ -904,14 +920,14 @@ var LibraryPThread = {
904920
#endif
905921

906922
for (;;) {
907-
var threadStatus = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2);
908-
if (threadStatus == 1) { // Exited?
923+
var detach_state = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detach_state }}} ) >> 2);
924+
if (detach_state == {{{ cDefine('DT_EXITING') }}}) { // Exiting?
909925
if (status) {
910926
var result = Atomics.load(HEAPU32, (thread + {{{ C_STRUCTS.pthread.result }}} ) >> 2);
911927
{{{ makeSetValue('status', 0, 'result', 'i32') }}};
912928
}
913-
// Mark the thread as detached.
914-
Atomics.store(HEAPU32, (thread + {{{ C_STRUCTS.pthread.detached }}} ) >> 2, 1);
929+
// Mark the thread as exited.
930+
PThread.setDetachState(thread, {{{ cDefine('DT_EXITED') }}});
915931
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread);
916932
else postMessage({ 'cmd': 'cleanupThread', 'thread': thread });
917933
return 0;
@@ -924,7 +940,7 @@ var LibraryPThread = {
924940
// runtime and launched main()), assist pthreads in performing operations
925941
// that they need to access the Emscripten main runtime for.
926942
if (!ENVIRONMENT_IS_PTHREAD) _emscripten_main_thread_process_queued_calls();
927-
_emscripten_futex_wait(thread + {{{ C_STRUCTS.pthread.threadStatus }}}, threadStatus, ENVIRONMENT_IS_PTHREAD ? 100 : 1);
943+
_emscripten_futex_wait(thread + {{{ C_STRUCTS.pthread.detach_state }}}, detach_state, ENVIRONMENT_IS_PTHREAD ? 100 : 1);
928944
}
929945
},
930946

@@ -977,7 +993,8 @@ var LibraryPThread = {
977993
err('pthread_cancel attempted on thread ' + thread + ', which does not point to a valid thread, or does not exist anymore!');
978994
return {{{ cDefine('ESRCH') }}};
979995
}
980-
Atomics.compareExchange(HEAPU32, (thread + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 0, 2); // Signal the thread that it needs to cancel itself.
996+
// Signal the thread that it needs to cancel itself.
997+
Atomics.store(HEAPU32, (thread + {{{ C_STRUCTS.pthread.cancel }}}) >> 2, 1);
981998
if (!ENVIRONMENT_IS_PTHREAD) cancelThread(thread);
982999
else postMessage({ 'cmd': 'cancelThread', 'thread': thread});
9831000
return 0;

src/struct_info_internal.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@
66
"file": "pthread_impl.h",
77
"structs": {
88
"pthread": [
9-
"threadStatus",
109
"profilerBlock",
1110
"self",
12-
"detached",
11+
"tsd",
12+
"detach_state",
1313
"stack",
1414
"stack_size",
1515
"result",
16-
"attr"
16+
"robust_list",
17+
"tid",
18+
"cancel",
19+
"canceldisable",
20+
"cancelasync",
21+
"locale"
1722
],
1823
"pthread_attr_t#": [
1924
"_a_transferredcanvases"
@@ -26,9 +31,12 @@
2631
]
2732
},
2833
"defines": [
29-
"DEFAULT_STACK_SIZE",
3034
"__ATTRP_C11_THREAD",
31-
"EM_THREAD_NAME_MAX"
35+
"EM_THREAD_NAME_MAX",
36+
"DT_EXITED",
37+
"DT_EXITING",
38+
"DT_JOINABLE",
39+
"DT_DETACHED"
3240
]
3341
},
3442
{

system/include/compat/sys/random.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ extern "C" {
99
// syscall which is unnecessary indirection for us.
1010
int getentropy(void *buffer, size_t length);
1111

12+
#include_next <sys/random.h>
13+
1214
#ifdef __cplusplus
1315
}
1416
#endif

system/lib/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ extern struct ps_strings *__ps_strings;
104104
#endif
105105

106106
#if SANITIZER_EMSCRIPTEN
107+
#define weak __attribute__(__weak__)
108+
#define hidden __attribute__((__visibility__("hidden")))
107109
#include <syscall.h>
110+
#undef weak
111+
#undef hidden
108112
#include <emscripten/threading.h>
109113
#include <math.h>
110114
#include <wasi/api.h>

system/lib/dlmalloc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,10 @@ extern "C" {
867867
#ifndef USE_DL_PREFIX
868868
// XXX Emscripten XXX
869869
#if defined(__EMSCRIPTEN__)
870+
void* __libc_malloc(size_t) __attribute__((weak, alias("dlmalloc")));
871+
void __libc_free(void*) __attribute__((weak, alias("dlfree")));
872+
void* __libc_calloc(size_t) __attribute__((weak, alias("dlcalloc")));
873+
void* __libc_realloc(void*, size_t) __attribute__((weak, alias("dlrealloc")));
870874
void* malloc(size_t) __attribute__((weak, alias("dlmalloc")));
871875
void free(void*) __attribute__((weak, alias("dlfree")));
872876
void* calloc(size_t, size_t) __attribute__((weak, alias("dlcalloc")));

system/lib/emmalloc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ void *emmalloc_memalign(size_t alignment, size_t size)
793793
return ptr;
794794
}
795795
extern __typeof(emmalloc_memalign) emscripten_builtin_memalign __attribute__((alias("emmalloc_memalign")));
796+
extern __typeof(emmalloc_memalign) __libc_memalign __attribute__((alias("emmalloc_memalign")));
796797

797798
void * EMMALLOC_EXPORT memalign(size_t alignment, size_t size)
798799
{
@@ -811,6 +812,7 @@ void *emmalloc_malloc(size_t size)
811812
return emmalloc_memalign(MALLOC_ALIGNMENT, size);
812813
}
813814
extern __typeof(emmalloc_malloc) emscripten_builtin_malloc __attribute__((alias("emmalloc_malloc")));
815+
extern __typeof(emmalloc_malloc) __libc_malloc __attribute__((alias("emmalloc_malloc")));
814816

815817
void * EMMALLOC_EXPORT malloc(size_t size)
816818
{
@@ -912,6 +914,7 @@ void emmalloc_free(void *ptr)
912914
#endif
913915
}
914916
extern __typeof(emmalloc_free) emscripten_builtin_free __attribute__((alias("emmalloc_free")));
917+
extern __typeof(emmalloc_free) __libc_free __attribute__((alias("emmalloc_free")));
915918

916919
void EMMALLOC_EXPORT free(void *ptr)
917920
{
@@ -1132,6 +1135,7 @@ void *emmalloc_realloc(void *ptr, size_t size)
11321135
{
11331136
return emmalloc_aligned_realloc(ptr, MALLOC_ALIGNMENT, size);
11341137
}
1138+
extern __typeof(emmalloc_realloc) __libc_realloc __attribute__((alias("emmalloc_realloc")));
11351139

11361140
void * EMMALLOC_EXPORT realloc(void *ptr, size_t size)
11371141
{
@@ -1167,6 +1171,7 @@ void *emmalloc_calloc(size_t num, size_t size)
11671171
memset(ptr, 0, bytes);
11681172
return ptr;
11691173
}
1174+
extern __typeof(emmalloc_calloc) __libc_calloc __attribute__((alias("emmalloc_calloc")));
11701175

11711176
void * EMMALLOC_EXPORT calloc(size_t num, size_t size)
11721177
{

system/lib/libc/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/.
2-
Most of the source comes from musl 1.1.15, with some exceptions listed below.
1+
This folder contains the musl version of libc at `/musl`. The upstream version
2+
can be found at http://www.musl-libc.org/.
3+
4+
Most of the source comes from musl v1.2.2, with some exceptions listed below.
5+
We track these changes from upstream in https://github.com/emscripten-core/musl
6+
and use a script (`system/lib/update_musl.py`) to pull in updates.
37

48
Some changes have been made to the version that was taken from upstream, including:
59

system/lib/libc/compat/aligned_alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// Musl has an aligned_alloc routine, but that builds on top of standard malloc(). We are using dlmalloc, so
44
// can route to its implementation instead.
5-
void * __attribute__((weak)) aligned_alloc(size_t alignment, size_t size)
5+
void * weak aligned_alloc(size_t alignment, size_t size)
66
{
77
void *ptr;
88
if ((alignment % sizeof(void *) != 0) || (size % alignment) != 0)

system/lib/libc/crt1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <stdlib.h>
1313
#include <wasi/api.h>
1414

15-
__attribute__((weak)) void __wasm_call_ctors(void);
15+
__attribute__((__weak__)) void __wasm_call_ctors(void);
1616

1717
int __original_main(void);
1818

0 commit comments

Comments
 (0)