Skip to content

Pthreads #3266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 278 commits into from
Jun 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
278 commits
Select commit Hold shift + click to select a range
3a1396c
Make memory allocation thread-safe. Add test.
juj Sep 5, 2014
f6ec01f
Fix a bug where pthread exit might get called twice due to a race con…
juj Sep 6, 2014
5ed8605
Add a test for previous bug fix.
juj Sep 6, 2014
5b85dfc
Fix typo in assert in pthread_cancel.
juj Sep 6, 2014
b044ac2
Fix browser.test_pthread_mutex expected return value.
juj Sep 6, 2014
deafe10
Add (non-working) test for old GCC atomic fetch_and_op builtin operat…
juj Sep 8, 2014
f63fdc2
TEMP: fastcomp does not have __sync_fetch_and_nand, so implement it f…
juj Sep 8, 2014
0c692f1
TEMP: Route GCC atomic fetch and op builtins to library functions to …
juj Sep 8, 2014
4c76081
Add test for GCC old atomic builtin __sync_op_and_fetch instructions.
juj Sep 8, 2014
8b07c45
TEMP: Implement __sync_op_and_fetch builtins in the test browser.test…
juj Sep 8, 2014
4e8ac20
Add test for the remaining GCC atomics.
juj Sep 8, 2014
dc30616
TEMP: Fix up GCC atomics in browser.test_pthread_gcc_atomics to be pr…
juj Sep 8, 2014
281f27f
Implement atomic operations for internal musl libc use for the JS arch.
juj Sep 8, 2014
51f795e
Implement __wake and __wait musl libc internal futex operations for E…
juj Sep 8, 2014
1f4069c
Implement pthread_once() from musl.
juj Sep 8, 2014
01d4a45
Add test for pthread_once()
juj Sep 8, 2014
d05db20
Implement a_swap and a_fetch_add for internal musl libc atomics for t…
juj Sep 8, 2014
b8fe785
Fix typo in previous commit.
juj Sep 8, 2014
963bc7a
Add pthread barrier API from musl.
juj Sep 8, 2014
c126ff9
Add test for pthread barriers.
juj Sep 8, 2014
362e5fc
Implement musl pthread control structure for each created pthread.
juj Nov 29, 2014
fb4b1e9
Add support for thread local storage.
juj Nov 29, 2014
d7c47b1
Add support for pthread condition variables and add a test.
juj Nov 29, 2014
96cd3bc
Add support for pthread read-write locks. TODO: Add a test.
juj Nov 29, 2014
1d0e9af
Add support for pthread spinlocks. TODO: Add a test.
juj Nov 29, 2014
e7ee3d6
Add musl semaphore implementation. TODO: Add test.
juj Nov 30, 2014
2015020
Remove custom directives for GCC atomic ops tests since these are now…
juj Nov 30, 2014
d126f92
Remove Atomic cas and fence emulation support in GCC atomics test, si…
juj Nov 30, 2014
2a9d6fc
Add test file for Mandelbrot threading test.
juj Dec 3, 2014
2da6a86
Temporarily disable non-pthread arraybuffer creation, because the if(…
juj Jan 19, 2015
2a44747
Comment out functions that don't exist in the latest threading spec.
juj Jan 19, 2015
7364b19
Make return value of emscripten_futex_wait() match the integers from …
juj Jan 19, 2015
da98c3f
Remove the old unnecessary atomics polyfill.
juj Jan 19, 2015
53cdde8
Import global Atomics object to asm.js
juj Jan 19, 2015
206204b
Remove handwritten JS implementations for atomics that are now implem…
juj Jan 19, 2015
c288dfb
Mark down a note that pthread start signatures are known to be differ…
juj Jan 19, 2015
9466df9
Add primitive support for alarm() signal.
juj Jan 19, 2015
43e5abd
Add stubs for sched_get_priority_min() and sched_get_priority_max()
juj Jan 19, 2015
21b46a8
Restore the default pthread startup function form.
juj Jan 19, 2015
0da4bc8
Add a hack to detect whether pthread is 'v' or 'vi'.
juj Jan 19, 2015
b9e52f9
Mimic linux thread scheduling parameters.
juj Jan 20, 2015
457f3f4
Implement pthread_get/setschedparam.
juj Jan 20, 2015
d36826f
Implement pthread_setschedprio.
juj Jan 20, 2015
998c7d8
Remove pthread_once from JS code, since it's implemented in musl.
juj Jan 20, 2015
c51e4ee
Implement stubs for pthread_sigmask and sigpending.
juj Jan 20, 2015
7cff836
Make --emrun compatible with -lpthread.
juj Jan 20, 2015
d23f60b
Add support for pthread joinable status at thread creation. Improve p…
juj Jan 20, 2015
f9dee02
Fix pthread_create with PTHREAD_CREATE_JOINABLE.
juj Jan 20, 2015
00b975d
Add better check for ENVIRONMENT_IS_PTHREAD versus ENVIRONMENT_IS_WOR…
juj Jan 20, 2015
82b86cb
Refactor the creation of a pthread into a separate function so that i…
juj Jan 20, 2015
e3c134f
Fix bad offset for thread detach state attr.
juj Jan 21, 2015
f8a7639
Fix default detach state to PTHREAD_CREATE_JOINABLE for newly created…
juj Jan 21, 2015
7ca0f87
Fix return codes for threads.
juj Jan 21, 2015
6ec73b1
Replace assert() in pthread_cancel with proper error handling.
juj Jan 22, 2015
0e82c8d
Implement pthread_detach.
juj Jan 22, 2015
c1784bb
Mark down TODO in pthread_exit.
juj Jan 22, 2015
f8fe238
Remove the use of custom 'joinable' attribute on threads, and reuse t…
juj Jan 22, 2015
d71ec47
Add new link setting -s PTHREAD_POOL_SIZE=<int> which specifies the n…
juj Jan 22, 2015
b035d9d
Add -s PTHREAD_POOL_SIZE=8 to test runner.
juj Jan 22, 2015
2dbe6ce
Fix typo in pthread_cancel that caused it to fail.
juj Jan 22, 2015
997bbef
Fix pthread_detach to return ESRCH instead of EINVAL when attempting …
juj Jan 22, 2015
6a9a030
Run destructors of thread-specific data when a pthread exits.
juj Jan 22, 2015
a43f296
Implement pthread_getcpuclockid error result according to spec.
juj Jan 22, 2015
7f2ff5a
If a pthread gets canceled, mark the thread return code to be PTHREAD…
juj Jan 22, 2015
ea527e2
Clarify hack.
juj Jan 22, 2015
e21444e
Fix typo in pthread quit.
juj Jan 22, 2015
e768a12
Migrate pthread schedPrio and schedPolicy from handwritten JS structu…
juj Jan 22, 2015
cf083f9
Fix wrong expression in pthread_detach.
juj Jan 22, 2015
37b1153
Fix pthread_detach to allow detaching a thread that has already quit …
juj Jan 22, 2015
d7a9dd4
Fix emrun postjs to not try to do a http post when running the file o…
juj Jan 22, 2015
e0dfe95
Fix an issue where TLS data would get deleted from unallocated data s…
juj Jan 22, 2015
3753d40
Add stub no-op pthread_atfork that does nothing since fork() is not s…
juj Jan 23, 2015
41ae531
Change musl pthread_attr_getstack to be standard conforming.
juj Jan 23, 2015
5d3f21d
Fix pthread_getschedparam, pthread_setschedparam and pthread_setsched…
juj Jan 24, 2015
c510272
Implement support for pthread_attr_setinheritsched.
juj Jan 24, 2015
d702c36
Add missing deps in pthread_create.
juj Jan 24, 2015
5f24780
Add debug prints to pthread_join.
juj Jan 25, 2015
9d42bed
Fix pthread_join to properly be able to join a thread that was cancel…
juj Jan 25, 2015
00d5398
Add coverage in sleep&usleep for supporting cooperative thread cancel…
juj Jan 25, 2015
51645b2
Remove an assert in pthread_testcancel to a benign no-op form.
juj Jan 25, 2015
4f29d30
Implement pthread_setcancelstate() and pthread_setcanceltype().
juj Jan 25, 2015
8354aa1
Migrate to musl pthread_mutex implementation.
juj Jan 25, 2015
ec7fcf6
Fix the meaning of var allocatedOwnStack to be proper.
juj Jan 25, 2015
826bb06
Manually initialize filesystem in pthread workers so that they can do…
juj Jan 25, 2015
2d59eda
Add test for printf in pthreads.
juj Jan 25, 2015
02e33e5
Fix interpretation of musl thread stack base address to take into acc…
juj Jan 25, 2015
e61ade1
Add a sanity check assert to pthread stack creation.
juj Jan 25, 2015
e22adb6
Fix an issue with FS initialization in pthreads, and only initialize …
juj Jan 25, 2015
5dffd80
Fix issues with TTY creation in pthreads.
juj Jan 25, 2015
62dce5f
Maintain space for tempDoublePtr in pthreads. Fix allocatedOwnStack s…
juj Jan 25, 2015
d9abe64
Fix musl behavior of pthread_attr_setschedpolicy to return EINVAL on …
juj Jan 25, 2015
98f4cb4
Fix pthread_setcancelstate to not be a cancellation point.
juj Jan 25, 2015
d71e127
Fix pthread_join to properly wait for thread to finish execution in t…
juj Jan 25, 2015
f2189bf
Fix pthread_join to properly return ESRCH after joining a thread that…
juj Jan 25, 2015
7ba85ae
Fake support for sending signal 0 (no signal) to main thread with pth…
juj Jan 25, 2015
30f787d
Properly return ESRCH from pthread_kill when attempting to kill a thr…
juj Jan 25, 2015
bcee732
Add error checking to range of signals in pthread_kill.
juj Jan 25, 2015
dedaca2
Impose limits on scheduler priorities in pthread_setschedparam and pt…
juj Jan 25, 2015
3b28b28
Update Emscripten futex api to latest version and fix up pthread_cond…
juj Jan 25, 2015
1be3070
Fix build error in test_pthread_malloc.cpp
juj Jan 29, 2015
67a6978
Build pthread libraries as part of musl libc instead of rebuilding th…
juj Jan 29, 2015
5bb55c6
Implement stub for clock_getcpuclockid.
juj Feb 2, 2015
d6f208c
Fix pthread_setschedprio reference to priority and update input check…
juj Feb 2, 2015
3eb0093
Add test for TLS operation in the main thread.
juj Feb 2, 2015
e639945
Fix TLS operation in the main thread.
juj Feb 2, 2015
5a7f79b
Fix TLS storage allocation for main thread.
juj Feb 2, 2015
7baa4cb
Set sysconf(_SC_THREAD_PRIORITY_SCHEDULING) to return 0 to denote tha…
juj Feb 3, 2015
848390b
Fix uppercase typo in pthread_join.
juj Feb 3, 2015
b45caf1
Restore custom mutex implementation which works better for Emscripten…
juj Feb 3, 2015
4835e84
Add stub entries for unsupported pthread_mutexattr_get/setprioceiling.
juj Feb 3, 2015
e4d3138
Add new control field to musl mutex in order to implement JS futex ba…
juj Feb 3, 2015
b51aa91
Initialize main thread thread block better so that the fields are ava…
juj Feb 3, 2015
4327892
Fix typo with missing parentheses.
juj Feb 3, 2015
000c792
Implement support for recursive mutexes and unlocking an errorcheck m…
juj Feb 3, 2015
c62be35
Add support for PTHREAD_MUTEX_ERRORCHECK.
juj Feb 3, 2015
212ce07
Fix pthread_mutex_unlock to return EPERM on error check mutexes if th…
juj Feb 3, 2015
af1c598
Fix pthread_mutex_trylock/timedlock handling of mutex ownership and u…
juj Feb 3, 2015
d96149d
Fix pthread_mutex_timedlock() interpretation of parameter 'at'. Retur…
juj Feb 3, 2015
fc191ee
Fix pthread_mutex_timedlock to return EINVAL if tv_nsec is wrong.
juj Feb 3, 2015
a550eb0
Add new (failing) test for volatile float and volatile double loads a…
juj Feb 4, 2015
59ad37f
Add a new (failing) test that checks that a pthread is able to spawn …
juj Feb 4, 2015
6f07b00
Implement support for pthreads to spawn other pthreads. Remove use of…
juj Feb 4, 2015
2e6ef40
Fix freeing of pthread data.
juj Feb 4, 2015
bfdd11e
Use the pthread_t self parameter to identify whether a pthread_t stru…
juj Feb 5, 2015
440a812
Add support for sibling threads to pthread_kill each other.
juj Feb 5, 2015
4bea8fd
Enable sibling pthreads to pthread_cancel() each other.
juj Feb 5, 2015
d9a5309
Enable sibling pthreads to pthread_detach() each other. Improve error…
juj Feb 5, 2015
64fc147
Enable main thread to call pthread_exit() (routes to exit()).
juj Feb 5, 2015
59c15b1
Make __pthread_self be an alias to pthread_self since the two functio…
juj Feb 5, 2015
df5f1a1
Enable threads to call pthread_get/schedparam/prio on their sibling p…
juj Feb 5, 2015
ffb75f7
Fix main thread pthread_t block initialization of self parameter.
juj Feb 5, 2015
64088da
Migrate pthread_setcanceltype/state, pthread_testcancel and usleep to…
juj Feb 5, 2015
aed6cdf
Make pthread_join a cancellation point. Add a temp hack to duplicate …
juj Feb 5, 2015
c867776
Fix the timeout value computation when waiting for a futex in __timed…
juj Feb 5, 2015
d86e9b3
Migrate back to musl mutex, which is now working better. Overload ems…
juj Feb 5, 2015
96f3d4a
Fix futex wait value in usleep to actually sleep and not spinlock.
juj Feb 5, 2015
ed8119f
Remove the -1 semantic on emscripten_futex_wake, and instead use INT_…
juj Feb 5, 2015
6df5c61
Remove obsolete __pthread_self().
juj Feb 5, 2015
83c3b48
Implement cooperative thread cancellation testing to musl pthread mut…
juj Feb 5, 2015
7282535
Improve musl rwlock to return EDEADLK instead of hanging/deadlocking …
juj Feb 5, 2015
aff64f2
Revise pthread cancellation point checks: usleep() must be a cancella…
juj Feb 6, 2015
d2bb705
Fix pthread wait issues with cancellation which caused semaphores not…
juj Feb 6, 2015
0c9b6ac
When running pthread cleanup handlers, make thread cancellation defer…
juj Feb 9, 2015
174a082
Implement a machinery to defer C file IO calls from pthreads to the E…
juj Feb 9, 2015
1dbac7a
Implement proxying of all library.js C runtime functions to Emscripte…
juj Feb 9, 2015
cd41b65
Add browser test for file IO in pthreads.
juj Feb 9, 2015
b45d9a8
Update mandelbrot sample.
juj Feb 10, 2015
c985137
Remove obsolete pthread stub functions from library.js
juj Feb 10, 2015
0d15d1f
Add 4-6 arg deferred execution handlers. Add a postMessage for deferr…
juj Feb 10, 2015
c1f1717
Add functions to emulate HEAPF32 and HEAPF64 Atomic loads and stores …
juj Feb 10, 2015
1483d84
Use futex-based sleep to in test_pthread_mutex to work around bug htt…
juj Feb 10, 2015
9fdeb94
Improve debug comment.
juj Feb 10, 2015
aa783c6
When the main thread of the C runtime quits e.g. with exit(), kill al…
juj Feb 11, 2015
e835df2
Fix a bug in setup of the ENV variable that caused spawned pthreads t…
juj Feb 11, 2015
86b7039
Add a runtime check to static/dynamicAlloc functions to ensure that p…
juj Feb 11, 2015
ee9b66e
Test both forms of sleeping (spinlock with performance.now() and fute…
juj Feb 12, 2015
b799894
Improve mandelbrot demo to allow dynamically configuring the number o…
juj Feb 17, 2015
8e422c5
Initial wip SSE implementation of mandelbrot.
juj Feb 17, 2015
3dc5c3c
SSE update to Mandelbrot demo.
juj Feb 18, 2015
b9c5311
Mandelbrot improvements.
juj Feb 18, 2015
37d5e6e
Smooth outputted performance in Mandelbrot to give a more stable read…
juj Feb 18, 2015
fdf1d0f
Add new function read_and_preprocess(filename) to tools/shared.py to …
juj Feb 21, 2015
41783a0
Preprocess proxyClient.js when importing it.
juj Feb 21, 2015
7149c71
Fix src/parseTools.js preprocessing to understand quotes in include s…
juj Feb 21, 2015
5da5c1b
Pass the new JSBackend command line flag -emscripten-enable-pthreads …
juj Feb 21, 2015
63ca02e
Separate pthreads implementation into its own pthreads.bc so that it'…
juj Feb 21, 2015
58de76c
Add a test print to malloc test.
juj Feb 21, 2015
b997dea
Build dlmalloc either as thread safe or thread unsafe depending on wh…
juj Feb 21, 2015
103ee47
Only import Atomics and SharedArrayBuffer to asm.js module if USE_PTH…
juj Feb 21, 2015
65e5a9e
Properly instantiate either SharedIntXArray or IntXArray depending on…
juj Feb 21, 2015
10777fd
Only import the Atomics functions to asm.js module if USE_PTHREADS is…
juj Feb 21, 2015
ebbe6b7
Add the original dummy implementation of pthread functions as src/lib…
juj Feb 21, 2015
2ae040d
Add usleep to the pthread stub library functions.
juj Feb 22, 2015
b94b3b3
Update the expected result of sysconf test.
juj Feb 22, 2015
3e1f110
Remove non-shared versions of typed array views from the asm.js modul…
juj Mar 24, 2015
3eac339
Whitespace cleanup in emcc.
juj Mar 24, 2015
d50185a
Rename EM_DEFERRED_* to EM_PROXIED_* to better reflect that the calls…
juj Mar 24, 2015
d2caa92
In library.js, do not refer to ENVIRONMENT_IS_PTHREAD when not buildi…
juj Mar 24, 2015
6570aeb
Remove unneeded nonexistent dependency to emscripten_get_now_is_monot…
juj Mar 24, 2015
929ecd7
Use !== in clock_getcpuclockid().
juj Mar 24, 2015
577401a
Update formatting and comments.
juj Mar 24, 2015
7f10d23
Refer to ENVIRONMENT_IS_PTHREAD in src/preamble.js only if compiling …
juj Mar 24, 2015
00d542d
Use strict equals comparison for thread message passing commands.
juj Mar 24, 2015
7cbea08
Code syntax formatting.
juj Mar 24, 2015
737efa1
Add a comment explaining the added new control field to pthread_mutex…
juj Mar 24, 2015
996f689
Don't refer to ENVIRONMENT_IS_PTHREADS if not building with pthreads …
juj Mar 24, 2015
fa107e3
Use 'var' for ENVIRONMENT_IS_PTHREAD in src/shell.js.
juj Mar 24, 2015
91fc9ad
Fix more references to ENVIRONMENT_IS_PTHREAD when not compiling with…
juj Mar 25, 2015
e5e55b8
Include gets() when building library_pthread.c with LLVM 3.6 and C11.
juj Mar 25, 2015
213b9a1
Add missing else in library_pthread.js that resulted in a bogus error…
juj Mar 25, 2015
0e657b8
Adjust to pthreads API change in futex wait operation: the timeout va…
juj Mar 25, 2015
1b8662b
Fix signature typo in EM_PROXIED_PUTS.
juj Mar 25, 2015
3b93da8
Process queued calls in usleep() to assist C runtime calls from pthre…
juj Mar 25, 2015
01a463c
Remove references to the deleted getwd() function.
juj Apr 13, 2015
d3c7af9
Update documentation for pthreads.
juj Mar 30, 2015
ff51e66
Add a note about pthread-main.js deployment.
juj Apr 13, 2015
e2fc742
Rename threadBlock to threadInfoStruct to reflect the usage better.
juj Apr 13, 2015
454db94
Document the existence of the __EMSCRIPTEN_PTHREADS__ preprocessor de…
juj Apr 14, 2015
0b146e1
Fix missing '.bc' suffixes when including pthreads symbols to build.
juj Apr 14, 2015
b57729e
Allocate tempDoublePtr for the worker at worker init time.
juj Apr 15, 2015
85999dd
Remove unnecessary if (typeof SharedArrayBuffer != 'undefined') test…
juj Apr 15, 2015
fde70c1
Remove reference to ENVIRONMENT_IS_PTHREAD in function getenv() when …
juj Apr 15, 2015
7bbb6a6
Skip testing Atomic NAND for now at least, LLVM 3.6 attempts to suppo…
juj Apr 15, 2015
d21e7de
Allocate tempDoublePtr for pthreads via malloc, since the runtime is …
juj Apr 15, 2015
eb359e6
Skip nand portion of test_pthread_gcc_atomic_op_and_fetch test, since…
juj Apr 15, 2015
ddb3511
Add new test for iostream operation with pthreads. https://bugzilla.m…
juj Apr 16, 2015
cd0a6dc
Don't add static initializers to atinit when running in pthreads.
juj Apr 16, 2015
a1cfef9
Force-skip ensureInitRuntime() in all cases when running in pthreads …
juj Apr 16, 2015
5af0de2
Mark static memory area to be immediately sealed on pthreads to make …
juj Apr 16, 2015
0e32b72
Add support to JS libraries to specify a variable with syntax myVar: …
juj Apr 16, 2015
091f758
Implement new machinery with PthreadWorkerInit variable that stores a…
juj Apr 16, 2015
645755f
Add pthreads specific debug/error print to print an error stack trace…
juj Apr 16, 2015
671784f
Fix several global variables from src/library.js to be properly carri…
juj Apr 16, 2015
3b99bb7
Fix printf, fprintf and dprintf with varargs from pthreads.
juj Apr 17, 2015
abb3d70
Implement pthread_getattr_np, and add a test.
juj Apr 27, 2015
0f03b22
Improve test test_pthread_atomics to cover 32bit load, store and cas …
juj Apr 28, 2015
4dadeef
Add emulation for more 64bit atomic operations.
juj Apr 28, 2015
fe751d8
Fix tools/system_libs.py syntax after pthreads rebase.
juj May 4, 2015
ec44f9a
Remove stray leftover line "#endif // POINTER_MASKING" in src/preambl…
juj May 4, 2015
1b047d9
Improve src/parseTools.js preprocess() function to report file:line d…
juj May 4, 2015
e10f77f
Readapt tools/system_libs.py adding for pthreads and malloc to work a…
juj May 4, 2015
3cf5532
Add test file for browser.test_pthread_64bit_atomics.cpp.
juj May 4, 2015
1384a73
Add emulated support and testing for 64-bit GCC atomic op intrinsics.
juj May 5, 2015
d0f91f6
Use document.currentScript to locate the current script file instead …
juj Apr 29, 2015
db1f776
Fix an issue where nested pthread spawns could not be immediately pth…
juj May 6, 2015
824450b
Fix an issue where multiple threads allocating lots of memory (enough…
juj May 6, 2015
ec4edf3
Fix emscripten_main_thread_process_queued_calls() to not process same…
juj May 12, 2015
a58c2fe
Add emscripten_atomic_swap intrinsics. Add support for GCC __sync_loc…
juj May 13, 2015
8ceb2b2
Add testing of Emscripten intrinsics in the spinlock test. Fix test_p…
juj May 14, 2015
c0304d5
HACK: Atomics.exchange() is not yet implemented, so as a temp workaro…
juj May 14, 2015
29ecfad
Build pthread tests with -O3 to catch any potential optimizer interac…
juj May 20, 2015
b3687b9
Optimize emulated 64bit atomic ops by using a spinlock instead of pth…
juj May 20, 2015
00c32b7
Polyfill SharedArrayBuffer.slice() operation which doesn't exist curr…
juj May 21, 2015
f11be16
Add support for preprocessor #if < operation.
juj May 21, 2015
f2c2340
Add new functions emscripten_num_logical_cores() which returns the nu…
juj May 21, 2015
204d37a
Add a shallow test for emscripten_num_logical_cores(); functionality.
juj May 21, 2015
eba1d21
Implement operator > for preprocessor.
juj May 21, 2015
07213d7
Add support for asking the pthread warmup pool size at startup as wel…
juj May 21, 2015
ccafa0a
Remove the -lpthread setting, and only use -s USE_PTHREADS=1 to have …
juj May 27, 2015
c223827
Abort compilation if PROXY_TO_WORKER=1 is attempted with USE_PTHREADS=1.
juj May 27, 2015
914f095
Fix test browser.test_pthread_create_pthread to close the test window…
juj May 27, 2015
52072b4
Abort execution on a warning if pthreads is not supported in the brow…
juj May 27, 2015
fe15b39
Fix pthread_cleanup_push() to new API after rebase.
juj May 27, 2015
5399f2a
Test that preprocessor define __EMSCRIPTEN_PTHREADS__ is actually pre…
juj May 28, 2015
e0cff8c
Clean up -s USE_PTHREADS detection in emcc.
juj May 28, 2015
03cf47e
Apply coding conventions to pthreads: space after for().
juj May 28, 2015
afe2900
Restore missing test code in tests/test_browser.py that was removed i…
juj May 28, 2015
80c8aae
Comment long #if-#else-#endif chains in src/preamble.js for clarity.
juj May 28, 2015
f87bd74
Mark linker options for dynamic linking unsupported with -s USE_PTHRE…
juj May 28, 2015
8c6d6f5
When SharedArrayBuffer is not supported, give browser test runner a s…
juj Jun 1, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion emcc
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,28 @@ try:
if js_opts:
shared.Settings.RUNNING_JS_OPTS = 1

if shared.Settings.USE_PTHREADS:
if not any(s.startswith('PTHREAD_POOL_SIZE=') for s in settings_changes):
settings_changes.append('PTHREAD_POOL_SIZE=0')
js_libraries.append(shared.path_from_root('src', 'library_pthread.js'))
newargs.append('-D__EMSCRIPTEN_PTHREADS__=1')
else:
js_libraries.append(shared.path_from_root('src', 'library_pthread_stub.js'))

if shared.Settings.USE_PTHREADS:
if shared.Settings.PROXY_TO_WORKER:
logging.error('-s PROXY_TO_WORKER=1 is not yet supported with -s USE_PTHREADS=1!')
exit(1)
if shared.Settings.LINKABLE:
logging.error('-s LINKABLE=1 is not supported with -s USE_PTHREADS=1!')
exit(1)
if shared.Settings.SIDE_MODULE:
logging.error('-s SIDE_MODULE=1 is not supported with -s USE_PTHREADS=1!')
exit(1)
if shared.Settings.MAIN_MODULE:
logging.error('-s MAIN_MODULE=1 is not supported with -s USE_PTHREADS=1!')
exit(1)

shared.Settings.EMSCRIPTEN_VERSION = shared.EMSCRIPTEN_VERSION
shared.Settings.OPT_LEVEL = opt_level
shared.Settings.DEBUG_LEVEL = debug_level
Expand Down Expand Up @@ -1351,6 +1373,9 @@ try:
final += '.mem.js'
src = None

if shared.Settings.USE_PTHREADS:
shutil.copyfile(shared.path_from_root('src', 'pthread-main.js'), os.path.join(os.path.dirname(os.path.abspath(target)), 'pthread-main.js'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should document this adding of the file in the site/ dir somewhere. it's another file people will need to copy around etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, that needs to be mentioned.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added note.


log_time('source transforms')

# It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
Expand Down Expand Up @@ -1606,7 +1631,7 @@ try:
<script>
if ((',' + window.location.search.substr(1) + ',').indexOf(',noProxy,') < 0) {
console.log('running code in a web worker');
''' + open(shared.path_from_root('src', 'webGLClient.js')).read() + '\n' + open(shared.path_from_root('src', 'proxyClient.js')).read().replace('{{{ filename }}}', child_js).replace('{{{ IDBStore.js }}}', open(shared.path_from_root('src', 'IDBStore.js')).read()) + '''
''' + open(shared.path_from_root('src', 'webGLClient.js')).read() + '\n' + shared.read_and_preprocess(shared.path_from_root('src', 'proxyClient.js')).replace('{{{ filename }}}', child_js).replace('{{{ IDBStore.js }}}', open(shared.path_from_root('src', 'IDBStore.js')).read()) + '''
} else {
// note: no support for code mods (PRECISE_F32==2)
console.log('running code on the main thread');
Expand Down
43 changes: 31 additions & 12 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
backend_args = [backend_compiler, infile, '-march=js', '-filetype=asm', '-o', temp_js]
if settings['PRECISE_F32']:
backend_args += ['-emscripten-precise-f32']
if settings['USE_PTHREADS']:
backend_args += ['-emscripten-enable-pthreads']
if settings['WARN_UNALIGNED']:
backend_args += ['-emscripten-warn-unaligned']
if settings['RESERVED_FUNCTION_POINTERS'] > 0:
Expand Down Expand Up @@ -220,8 +222,8 @@ def save_settings():
staticbump = mem_init.count(',')+1
while staticbump % 16 != 0: staticbump += 1
pre = pre.replace('STATICTOP = STATIC_BASE + 0;', '''STATICTOP = STATIC_BASE + %d;
/* global initializers */ __ATINIT__.push(%s);
%s''' % (staticbump, global_initializers, mem_init)) # XXX wrong size calculation!
/* global initializers */ %s __ATINIT__.push(%s);
%s''' % (staticbump, 'if (!ENVIRONMENT_IS_PTHREAD)' if settings['USE_PTHREADS'] else '', global_initializers, mem_init)) # XXX wrong size calculation!

if settings['SIDE_MODULE']:
pre = pre.replace('Runtime.GLOBAL_BASE', 'gb').replace('{{{ STATIC_BUMP }}}', str(staticbump))
Expand Down Expand Up @@ -460,7 +462,12 @@ def make_emulated_param(i):
'shiftRightArithmeticByScalar',
'shiftRightLogicalByScalar',
'shiftLeftByScalar'];
fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'NaN', 'Infinity']
fundamentals = ['Math']
if settings['USE_PTHREADS']:
fundamentals += ['SharedInt8Array', 'SharedInt16Array', 'SharedInt32Array', 'SharedUint8Array', 'SharedUint16Array', 'SharedUint32Array', 'SharedFloat32Array', 'SharedFloat64Array', 'Atomics']
else:
fundamentals += ['Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array']
fundamentals += ['NaN', 'Infinity']
if metadata['simd']:
fundamentals += ['SIMD']
if settings['ALLOW_MEMORY_GROWTH']: fundamentals.append('byteLength')
Expand Down Expand Up @@ -523,7 +530,7 @@ def keyfunc(other):
if not settings['SIDE_MODULE']:
asm_setup += 'var gb = Runtime.GLOBAL_BASE, fb = 0;\n'

asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew']
asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'establishStackSpace', 'setThrew']
if not settings['RELOCATABLE']:
asm_runtime_funcs += ['setTempRet0', 'getTempRet0']
else:
Expand Down Expand Up @@ -649,6 +656,10 @@ def math_fix(g):
asm_global_funcs += ''.join([' var SIMD_' + ty + '=global' + access_quote('SIMD') + access_quote(ty) + ';\n' for ty in simdtypes])
asm_global_funcs += ''.join([' var SIMD_' + ty + '_' + g + '=SIMD_' + ty + access_quote(g) + ';\n' for ty in simdinttypes for g in simdintfuncs])
asm_global_funcs += ''.join([' var SIMD_' + ty + '_' + g + '=SIMD_' + ty + access_quote(g) + ';\n' for ty in simdfloattypes for g in simdfloatfuncs])
if settings['USE_PTHREADS']:
# asm_global_funcs += ''.join([' var Atomics_' + ty + '=global' + access_quote('Atomics') + access_quote(ty) + ';\n' for ty in ['load', 'store', 'exchange', 'compareExchange', 'add', 'sub', 'and', 'or', 'xor', 'fence']])
# TODO: Once bug https://bugzilla.mozilla.org/show_bug.cgi?id=1141986 is implemented, replace the following line with the above one!
asm_global_funcs += ''.join([' var Atomics_' + ty + '=global' + access_quote('Atomics') + access_quote(ty) + ';\n' for ty in ['load', 'store', 'compareExchange', 'add', 'sub', 'and', 'or', 'xor', 'fence']])
asm_global_vars = ''.join([' var ' + g + '=env' + access_quote(g) + '|0;\n' for g in basic_vars + global_vars])

# sent data
Expand Down Expand Up @@ -724,14 +735,15 @@ def math_fix(g):
var HEAPU32 = new global%s(buffer);
var HEAPF32 = new global%s(buffer);
var HEAPF64 = new global%s(buffer);
''' % (access_quote('Int8Array'),
access_quote('Int16Array'),
access_quote('Int32Array'),
access_quote('Uint8Array'),
access_quote('Uint16Array'),
access_quote('Uint32Array'),
access_quote('Float32Array'),
access_quote('Float64Array')) if not settings['ALLOW_MEMORY_GROWTH'] else '''
''' % (access_quote('SharedInt8Array' if settings['USE_PTHREADS'] else 'Int8Array'),
access_quote('SharedInt16Array' if settings['USE_PTHREADS'] else 'Int16Array'),
access_quote('SharedInt32Array' if settings['USE_PTHREADS'] else 'Int32Array'),
access_quote('SharedUint8Array' if settings['USE_PTHREADS'] else 'Uint8Array'),
access_quote('SharedUint16Array' if settings['USE_PTHREADS'] else 'Uint16Array'),
access_quote('SharedUint32Array' if settings['USE_PTHREADS'] else 'Uint32Array'),
access_quote('SharedFloat32Array' if settings['USE_PTHREADS'] else 'Float32Array'),
access_quote('SharedFloat64Array' if settings['USE_PTHREADS'] else 'Float64Array'))
if not settings['ALLOW_MEMORY_GROWTH'] else '''
var Int8View = global%s;
var Int16View = global%s;
var Int32View = global%s;
Expand Down Expand Up @@ -800,6 +812,12 @@ def math_fix(g):
top = top|0;
STACKTOP = top;
}
function establishStackSpace(stackBase, stackMax) {
stackBase = stackBase|0;
stackMax = stackMax|0;
STACKTOP = stackBase;
STACK_MAX = stackMax;
}
''' + ('''
function setAsync() {
___async = 1;
Expand Down Expand Up @@ -869,6 +887,7 @@ def math_fix(g):
Runtime.stackAlloc = asm['stackAlloc'];
Runtime.stackSave = asm['stackSave'];
Runtime.stackRestore = asm['stackRestore'];
Runtime.establishStackSpace = asm['establishStackSpace'];
''')
if not settings['RELOCATABLE']:
funcs_js.append('''
Expand Down
52 changes: 52 additions & 0 deletions site/source/docs/porting/pthreads.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. Pthreads support:

==============================
Pthreads support
==============================

Low level multithreading is currently supported in Firefox Nightly release channel via an experimental extension to JavaScript Web Workers. This is a work-in-progress research project, and the prototype specification can be located `here <https://docs.google.com/document/d/1NDGA_gZJ7M7w1Bh8S0AoDyEqwDdRh4uSoTPSNn77PFk/edit?usp=sharing>`.

The proposed specification allows Emscripten applications to share the main memory heap between web workers. This along with primitives for low level atomics and futex support enables Emscripten to implement support for the Pthreads (POSIX threads) API.

Compiling with pthreads enabled
===============================

By default, support for pthreads is not enabled, since the specification is still in a prototyping stage. To enable code generation for pthreads, the following command line flags exist:

- Pass the compiler flag -s USE_PTHREADS=1 when compiling any .c/.cpp files, AND when linking to generate the final output .js file.
- Optionally, pass the linker flag -s PTHREAD_POOL_SIZE=<integer> to specify a predefined pool of web workers to populate at page preRun time before application main() is called. If -1 is passed to both PTHREAD_POOL_SIZE and PTHREAD_HINT_NUM_CORES, then a popup dialog will ask the user the size of the pool (useful for testing).
- Optionally, pass the linker flag -s PTHREAD_HINT_NUM_CORES=<integer> to choose what the function emscripten_num_logical_cores(); will return if navigator.hardwareConcurrency is not supported. If -1 is specified here, a popup dialog will be shown at startup to let the user specify the value that is returned here. This can be helpful in order to dynamically test how an application behaves with different values here.

There should be no other changes required. In C/C++ code, the preprocessor check #ifdef __EMSCRIPTEN_PTHREADS__ can be used to detect whether Emscripten is currently targeting pthreads.

Special considerations
======================

The Emscripten implementation for the pthreads API should follow the POSIX standard closely, but some behavioral differences do exist:

- When -s PTHREAD_POOL_SIZE=<integer> is not specified and pthread_create() is called, the new thread will not actually start to run immediately, but the main JS thread must yield execution back to browser first. This behavior is a result of `#1049079 <https://bugzilla.mozilla.org/show_bug.cgi?id=1049079>`.

- Currently several of the functions in the C runtime, such as filesystem functions like fopen(), fread(), printf(), fprintf() etc. are not multithreaded, but instead their execution is proxied over to the main application thread. Memory allocation via malloc() and free() is fully multithreaded though.

- The Emscripten implementation does not support `POSIX signals <http://man7.org/linux/man-pages/man7/signal.7.html>`, which are sometimes used in conjunction with pthreads. This is because it is not possible to send signals to web workers and pre-empt their execution. The only exception to this is pthread_kill() which can be used as normal to forcibly terminate a running thread.

- The Emscripten implementation does also not support multiprocessing via fork() and join().

- For web security purposes, there exists a fixed limit (by default 20) of threads that can be spawned when running in Firefox Nightly. `#1052398 <https://bugzilla.mozilla.org/show_bug.cgi?id=1052398>`. To adjust the limit, navigate to about:config and change the value of the pref "dom.workers.maxPerDomain".

- Some of the features in the pthreads specification are unsupported since the upstream musl library that Emscripten utilizes does not support them, or they are marked optional and a conformant implementation need not support them. Such unsupported features in Emscripten include prioritization of threads, and pthread_rwlock_unlock() is not performed in thread priority order. The functions pthread_mutexattr_set/getprotocol(), pthread_mutexattr_set/getprioceiling() and pthread_attr_set/getscope() are no-ops.

- One particular note to pay attention to when porting is that sometimes in existing codebases the callback function pointers to pthread_create() and pthread_cleanup_push() omit the void* argument, which strictly speaking is undefined behavior in C/C++, but works in several x86 calling conventions. Doing this in Emscripten will issue a compiler warning, and can abort at runtime when attempting to call a function pointer with incorrect signature, so in the presence of such errors, it is good to check the signatures of the thread callback functions.

Also note that when compiling code that uses pthreads, an additional JavaScript file `pthread-main.js` is generated alongside the output .js file. That file must be deployed with the rest of the generated code files.

Running code and tests
======================

Any code that is compiled with pthreads support enabled will currently only work in the Firefox Nightly channel, since the SharedArrayBuffer specification is still in an experimental research stage before standardization. There exists two test suites that can be used to verify the behavior of the pthreads API implementation in Emscripten:

- The Emscripten unit test suite contains several pthreads-specific tests in the "browser." suite. Run any of the tests named browser.test_pthread_*.

- An Emscripten-specialized version of the `Open POSIX Test Suite <http://posixtest.sourceforge.net/>` is available at `juj/posixtestsuite <https://github.com/juj/posixtestsuite>` GitHub repository. This suite contains about 300 tests for pthreads conformance. To run this suite, the pref dom.workers.maxPerDomain should first be increased to at least 50.

Please check these first in case of any issues. Bugs can be reported to the Emscripten bug tracker as usual.
2 changes: 1 addition & 1 deletion src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ if (!BOOTSTRAPPING_STRUCT_INFO) {
load('modules.js');
load('parseTools.js');
load('jsifier.js');
globalEval(processMacros(preprocess(read('runtime.js'))));
globalEval(processMacros(preprocess(read('runtime.js'), 'runtime.js')));
Runtime.QUANTUM_SIZE = QUANTUM_SIZE;

//===============================
Expand Down
3 changes: 2 additions & 1 deletion src/deps_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"eglGetProcAddress": ["emscripten_GetProcAddress"],
"glfwGetProcAddress": ["emscripten_GetProcAddress"],
"emscripten_GetProcAddress": ["strstr"],
"__cxa_begin_catch": ["__cxa_can_catch", "__cxa_is_pointer_type"]
"__cxa_begin_catch": ["__cxa_can_catch", "__cxa_is_pointer_type"],
"sleep": ["usleep"]
}

38 changes: 20 additions & 18 deletions src/emrun_postjs.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
function emrun_register_handlers() {
function post(msg) {
var http = new XMLHttpRequest();
http.open("POST", "stdio.html", true);
http.send(msg);
}
// If the address contains localhost, or we are running the page from port 6931, we can assume we're running the test runner and should post stdout logs.
if (document.URL.search("localhost") != -1 || document.URL.search(":6931/") != -1) {
var emrun_http_sequence_number = 1;
var prevPrint = Module['print'];
var prevErr = Module['printErr'];
function emrun_exit() { post('^exit^'+EXITSTATUS); };
Module['addOnExit'](emrun_exit);
Module['print'] = function emrun_print(text) { post('^out^'+(emrun_http_sequence_number++)+'^'+encodeURIComponent(text)); prevPrint(text); }
Module['printErr'] = function emrun_printErr(text) { post('^err^'+(emrun_http_sequence_number++)+'^'+encodeURIComponent(text)); prevErr(text); }
if (typeof window === "object" && !ENVIRONMENT_IS_PTHREAD) {
function emrun_register_handlers() {
function post(msg) {
var http = new XMLHttpRequest();
http.open("POST", "stdio.html", true);
http.send(msg);
}
// If the address contains localhost, or we are running the page from port 6931, we can assume we're running the test runner and should post stdout logs.
if (document.URL.search("localhost") != -1 || document.URL.search(":6931/") != -1) {
var emrun_http_sequence_number = 1;
var prevPrint = Module['print'];
var prevErr = Module['printErr'];
function emrun_exit() { post('^exit^'+EXITSTATUS); };
Module['addOnExit'](emrun_exit);
Module['print'] = function emrun_print(text) { post('^out^'+(emrun_http_sequence_number++)+'^'+encodeURIComponent(text)); prevPrint(text); }
Module['printErr'] = function emrun_printErr(text) { post('^err^'+(emrun_http_sequence_number++)+'^'+encodeURIComponent(text)); prevErr(text); }

// Notify emrun web server that this browser has successfully launched the page.
post('^pageload^');
}
}
// Notify emrun web server that this browser has successfully launched the page.
post('^pageload^');
}
window.addEventListener('load', emrun_register_handlers);

// POSTs the given binary data represented as a (typed) array data back to the emrun-based web server.
// To use from C code, call e.g. EM_ASM_({emrun_file_dump("file.dat", HEAPU8.subarray($0, $0 + $1));}, my_data_pointer, my_data_pointer_byte_length);
Expand Down
Loading