Skip to content

Commit

Permalink
Split the pthread library out of libc
Browse files Browse the repository at this point in the history
  • Loading branch information
sbc100 committed Oct 14, 2024
1 parent 97700f1 commit 09f48a0
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 108 deletions.
3 changes: 2 additions & 1 deletion embuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@
'crtbegin',
'libsanitizer_common_rt',
'libubsan_rt',
'libwasm_workers_stub-debug',
'libwasm_workers-debug-stub',
'libpthread-debug-stub',
'libfetch',
'libfetch-mt',
'libwasmfs',
Expand Down
6 changes: 3 additions & 3 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4625,10 +4625,10 @@ def test_dylink_postsets_chunking(self):

@with_dylink_reversed
@parameterized({
'libcxx': ('libc,libc++,libmalloc,libc++abi',),
'libcxx': ('libc,libpthread,libc++,libmalloc,libc++abi',),
'all': ('1',),
'missing': ('libc,libmalloc,libc++abi', False, False, False),
'missing_assertions': ('libc,libmalloc,libc++abi', False, False, True),
'missing': ('libc,libpthread,libmalloc,libc++abi', False, False, False),
'missing_assertions': ('libc,libpthread,libmalloc,libc++abi', False, False, True),
})
def test_dylink_syslibs(self, syslibs, expect_pass=True, with_reversed=True, assertions=True):
# one module uses libcxx, need to force its inclusion when it isn't the main
Expand Down
4 changes: 2 additions & 2 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -5995,9 +5995,9 @@ def test_bad_lookup(self):
# partial list, but ok since we grab them as needed
'parial': [{'EMCC_FORCE_STDLIBS': 'libc++'}, False],
# fail! not enough stdlibs
'partial_only': [{'EMCC_FORCE_STDLIBS': 'libc++,libc,libc++abi', 'EMCC_ONLY_FORCED_STDLIBS': '1'}, True],
'partial_only': [{'EMCC_FORCE_STDLIBS': 'libc++,libc,libpthread,libc++abi', 'EMCC_ONLY_FORCED_STDLIBS': '1'}, True],
# force all the needed stdlibs, so this works even though we ignore the input file
'full_only': [{'EMCC_FORCE_STDLIBS': 'libc,libc++abi,libc++,libmalloc', 'EMCC_ONLY_FORCED_STDLIBS': '1'}, False],
'full_only': [{'EMCC_FORCE_STDLIBS': 'libc,libpthread,libc++abi,libc++,libmalloc', 'EMCC_ONLY_FORCED_STDLIBS': '1'}, False],
})
def test_only_force_stdlibs(self, env, fail):
cmd = [EMXX, test_file('hello_libcxx.cpp')]
Expand Down
1 change: 0 additions & 1 deletion tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -2721,7 +2721,6 @@ def map_to_js_libs(library_name):
'dl': [],
'm': [],
'rt': [],
'pthread': [],
# This is the name of GNU's C++ standard library. We ignore it here
# for compatibility with GNU toolchains.
'stdc++': [],
Expand Down
246 changes: 145 additions & 101 deletions tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,138 @@ class libnoexit(Library):
src_files = ['atexit_dummy.c']


class libpthread(MuslInternalLibrary,
DebugLibrary,
AsanInstrumentedLibrary):
name = 'libpthread'
# See libc
cflags = ['-Os', '-fno-inline-functions', '-fno-builtin']

def __init__(self, **kwargs):
self.is_stub = kwargs.pop('stub')
super().__init__(**kwargs)

def get_cflags(self):
cflags = super().get_cflags()
cflags += ['-Wno-unused-but-set-variable',
'-Wno-unused-variable',
'-Wno-shift-op-parentheses',
'-Wno-unused-label',
'-Wno-logical-op-parentheses',
'-Wno-bitwise-op-parentheses']
if not self.is_stub:
cflags += ['-pthread']
return cflags

def get_base_name(self):
name = super().get_base_name()
if self.is_stub:
name += '-stub'
return name

@classmethod
def vary_on(cls):
return super().vary_on() + ['stub']

@classmethod
def get_default_variation(cls, **kwargs):
return super().get_default_variation(stub=not settings.PTHREADS, **kwargs)

def get_files(self):
files = files_in_path(
path='system/lib/pthread',
filenames=['thread_profiler.c'])

if self.is_stub:
# Include just a subset of the thread directory
files += files_in_path(
path='system/lib/libc/musl/src/thread',
filenames=[
'pthread_self.c',
'pthread_cleanup_push.c',
'pthread_attr_init.c',
'pthread_attr_destroy.c',
'pthread_attr_get.c',
'pthread_attr_setdetachstate.c',
'pthread_attr_setguardsize.c',
'pthread_attr_setinheritsched.c',
'pthread_attr_setschedparam.c',
'pthread_attr_setschedpolicy.c',
'pthread_attr_setscope.c',
'pthread_attr_setstack.c',
'pthread_attr_setstacksize.c',
'pthread_getconcurrency.c',
'pthread_getcpuclockid.c',
'pthread_getschedparam.c',
'pthread_setschedprio.c',
'pthread_setconcurrency.c',
'default_attr.c',
# C11 thread library functions
'call_once.c',
'tss_create.c',
'tss_delete.c',
'tss_set.c',
'cnd_broadcast.c',
'cnd_destroy.c',
'cnd_init.c',
'cnd_signal.c',
'cnd_timedwait.c',
'cnd_wait.c',
'mtx_destroy.c',
'mtx_init.c',
'mtx_lock.c',
'mtx_timedlock.c',
'mtx_trylock.c',
'mtx_unlock.c',
'thrd_create.c',
'thrd_exit.c',
'thrd_join.c',
'thrd_sleep.c',
'thrd_yield.c',
])
files += files_in_path(
path='system/lib/pthread',
filenames=[
'library_pthread_stub.c',
'pthread_self_stub.c',
'proxying_stub.c',
])
else:
files += glob_in_path(
path='system/lib/libc/musl/src/thread',
glob_pattern='*.c',
excludes=[
'clone.c',
'pthread_create.c',
'pthread_kill.c', 'pthread_sigmask.c',
'__set_thread_area.c', 'synccall.c',
'__syscall_cp.c', '__tls_get_addr.c',
'__unmapself.c',
# Empty files, simply ignore them.
'syscall_cp.c', 'tls.c',
# TODO: Support these. See #12216.
'pthread_setname_np.c',
'pthread_getname_np.c',
])
files += files_in_path(
path='system/lib/pthread',
filenames=[
'library_pthread.c',
'em_task_queue.c',
'proxying.c',
'proxying_legacy.c',
'thread_mailbox.c',
'pthread_create.c',
'pthread_kill.c',
'emscripten_thread_init.c',
'emscripten_thread_state.S',
'emscripten_futex_wait.c',
'emscripten_futex_wake.c',
'emscripten_yield.c',
])
return files


class libc(MuslInternalLibrary,
DebugLibrary,
AsanInstrumentedLibrary,
Expand Down Expand Up @@ -1083,7 +1215,7 @@ def get_files(self):
ignore = [
'ipc', 'passwd', 'signal', 'sched', 'time', 'linux',
'aio', 'exit', 'legacy', 'mq', 'setjmp',
'ldso', 'malloc'
'ldso', 'malloc', 'thread'
]

# individual files
Expand All @@ -1106,91 +1238,6 @@ def get_files(self):

ignore += LIBC_SOCKETS

if self.is_mt:
ignore += [
'clone.c',
'pthread_create.c',
'pthread_kill.c', 'pthread_sigmask.c',
'__set_thread_area.c', 'synccall.c',
'__syscall_cp.c', '__tls_get_addr.c',
'__unmapself.c',
# Empty files, simply ignore them.
'syscall_cp.c', 'tls.c',
# TODO: Support these. See #12216.
'pthread_setname_np.c',
'pthread_getname_np.c',
]
libc_files += files_in_path(
path='system/lib/pthread',
filenames=[
'library_pthread.c',
'em_task_queue.c',
'proxying.c',
'proxying_legacy.c',
'thread_mailbox.c',
'pthread_create.c',
'pthread_kill.c',
'emscripten_thread_init.c',
'emscripten_thread_state.S',
'emscripten_futex_wait.c',
'emscripten_futex_wake.c',
'emscripten_yield.c',
])
else:
ignore += ['thread']
libc_files += files_in_path(
path='system/lib/libc/musl/src/thread',
filenames=[
'pthread_self.c',
'pthread_cleanup_push.c',
'pthread_attr_init.c',
'pthread_attr_destroy.c',
'pthread_attr_get.c',
'pthread_attr_setdetachstate.c',
'pthread_attr_setguardsize.c',
'pthread_attr_setinheritsched.c',
'pthread_attr_setschedparam.c',
'pthread_attr_setschedpolicy.c',
'pthread_attr_setscope.c',
'pthread_attr_setstack.c',
'pthread_attr_setstacksize.c',
'pthread_getconcurrency.c',
'pthread_getcpuclockid.c',
'pthread_getschedparam.c',
'pthread_setschedprio.c',
'pthread_setconcurrency.c',
'default_attr.c',
# C11 thread library functions
'call_once.c',
'tss_create.c',
'tss_delete.c',
'tss_set.c',
'cnd_broadcast.c',
'cnd_destroy.c',
'cnd_init.c',
'cnd_signal.c',
'cnd_timedwait.c',
'cnd_wait.c',
'mtx_destroy.c',
'mtx_init.c',
'mtx_lock.c',
'mtx_timedlock.c',
'mtx_trylock.c',
'mtx_unlock.c',
'thrd_create.c',
'thrd_exit.c',
'thrd_join.c',
'thrd_sleep.c',
'thrd_yield.c',
])
libc_files += files_in_path(
path='system/lib/pthread',
filenames=[
'library_pthread_stub.c',
'pthread_self_stub.c',
'proxying_stub.c',
])

# These files are in libc directories, but only built in libc_optz.
ignore += [
'pow_small.c', 'log_small.c', 'log2_small.c'
Expand Down Expand Up @@ -1302,10 +1349,6 @@ def get_files(self):
if settings.RELOCATABLE:
libc_files += files_in_path(path='system/lib/libc', filenames=['dynlink.c'])

libc_files += files_in_path(
path='system/lib/pthread',
filenames=['thread_profiler.c'])

libc_files += glob_in_path('system/lib/libc/compat', '*.c')

# Check for missing file in non_lto_files list. Do this here
Expand Down Expand Up @@ -1410,17 +1453,17 @@ def can_use(self):
return super(libprintf_long_double, self).can_use() and settings.PRINTF_LONG_DOUBLE


class libwasm_workers(MTLibrary):
class libwasm_workers(DebugLibrary):
name = 'libwasm_workers'
includes = ['system/lib/libc']

def __init__(self, **kwargs):
self.debug = kwargs.pop('debug')
self.is_stub = kwargs.pop('stub')
super().__init__(**kwargs)

def get_cflags(self):
cflags = super().get_cflags()
if self.debug:
if self.is_debug:
cflags += ['-D_DEBUG']
# library_wasm_worker.c contains an assert that a nonnull parameter
# is no NULL, which llvm now warns is redundant/tautological.
Expand All @@ -1433,28 +1476,28 @@ def get_cflags(self):
cflags += ['-DNDEBUG', '-Oz']
if settings.MAIN_MODULE:
cflags += ['-fPIC']
if not self.is_stub:
cflags += ['-sWASM_WORKERS']
return cflags

def get_base_name(self):
name = 'libwasm_workers'
if not self.is_ww and not self.is_mt:
name += '_stub'
if self.debug:
name += '-debug'
name = super().get_base_name()
if self.is_stub:
name += '-stub'
return name

@classmethod
def vary_on(cls):
return super().vary_on() + ['debug']
return super().vary_on() + ['stub']

@classmethod
def get_default_variation(cls, **kwargs):
return super().get_default_variation(debug=settings.ASSERTIONS >= 1, **kwargs)
return super().get_default_variation(stub=not settings.WASM_WORKERS, **kwargs)

def get_files(self):
return files_in_path(
path='system/lib/wasm_worker',
filenames=['library_wasm_worker.c' if self.is_ww or self.is_mt else 'library_wasm_worker_stub.c'])
filenames=['library_wasm_worker_stub.c' if self.is_stub else 'library_wasm_worker.c'])

def can_use(self):
# see src/library_wasm_worker.js
Expand Down Expand Up @@ -2364,6 +2407,7 @@ def add_sanitizer_libs():
add_library('libmimalloc')
elif settings.MALLOC != 'none':
add_library('libmalloc')
add_library('libpthread')
add_library('libcompiler_rt')
if settings.LINK_AS_CXX:
add_library('libc++')
Expand Down

0 comments on commit 09f48a0

Please sign in to comment.