Skip to content

Commit

Permalink
Remove special case JS function proxying from library_pthread.c (#16405)
Browse files Browse the repository at this point in the history
\The normal `__proxy` method for JS functions works fine in these cases
and avoiding the special cases reduces the dependencies of
`library_pthread.c` which is included in all threaded programs.
  • Loading branch information
kleisauke authored Mar 6, 2022
1 parent 48a1620 commit a18bbf7
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 87 deletions.
2 changes: 0 additions & 2 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2029,8 +2029,6 @@ def phase_linker_setup(options, state, newargs, user_settings):
'emscripten_main_thread_process_queued_calls',
'emscripten_run_in_main_runtime_thread_js',
'emscripten_stack_set_limits',
'emscripten_sync_run_in_main_thread_2',
'emscripten_sync_run_in_main_thread_4',
]

if settings.MAIN_MODULE:
Expand Down
31 changes: 21 additions & 10 deletions src/library_html5_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,20 @@ var LibraryHtml5WebGL = {

_emscripten_webgl_power_preferences: "['default', 'low-power', 'high-performance']",

// In offscreen framebuffer mode, we implement these functions in C so that they enable
// the proxying of GL commands. Otherwise, they are implemented here in JS.
#if !(USE_PTHREADS && OFFSCREEN_FRAMEBUFFER)
#if USE_PTHREADS && OFFSCREEN_FRAMEBUFFER
// In offscreen framebuffer mode, we implement a proxied version of the
// emscripten_webgl_create_context() function in JS.
emscripten_webgl_create_context_proxied__proxy: 'sync',
emscripten_webgl_create_context_proxied__deps: ['emscripten_webgl_do_create_context'],
emscripten_webgl_create_context_proxied: function(target, attributes) {
return _emscripten_webgl_do_create_context(target, attributes);
},

// The other proxied GL commands are defined in C (guarded by the
// __EMSCRIPTEN_OFFSCREEN_FRAMEBUFFER__ definition).
#else
// When not in offscreen framebuffer mode, these functions are implemented
// in JS and forwarded without any proxying.
emscripten_webgl_create_context__sig: 'iii',
emscripten_webgl_create_context: 'emscripten_webgl_do_create_context',

Expand All @@ -60,16 +71,16 @@ var LibraryHtml5WebGL = {
emscripten_webgl_commit_frame: 'emscripten_webgl_do_commit_frame',
#endif

// This code is called from the main proxying logic, which has a big switch
// for all the messages, one of which is this GL-using one. This won't be
// This code is called from emscripten_webgl_create_context() and proxied
// to the main thread when in offscreen framebuffer mode. This won't be
// called if GL is not linked in, but also make sure to not add a dep on
// GL unnecessarily from here, as that would cause a linker error.
emscripten_webgl_do_create_context__deps: [
#if LibraryManager.has('library_webgl.js')
'$GL',
#endif
#if (USE_PTHREADS && OFFSCREEN_FRAMEBUFFER)
'emscripten_sync_run_in_main_thread_2',
#if USE_PTHREADS && OFFSCREEN_FRAMEBUFFER
'emscripten_webgl_create_context_proxied',
#endif
'$JSEvents', '_emscripten_webgl_power_preferences', '$findEventTarget', '$findCanvasEventTarget'],
// This function performs proxying manually, depending on the style of context that is to be created.
Expand Down Expand Up @@ -104,7 +115,7 @@ var LibraryHtml5WebGL = {
var targetStr = UTF8ToString(target);
#endif

#if (USE_PTHREADS && OFFSCREEN_FRAMEBUFFER)
#if USE_PTHREADS && OFFSCREEN_FRAMEBUFFER
// Create a WebGL context that is proxied to main thread if canvas was not found on worker, or if explicitly requested to do so.
if (ENVIRONMENT_IS_PTHREAD) {
if (contextAttributes.proxyContextToMainThread === {{{ cDefine('EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS') }}} ||
Expand All @@ -122,7 +133,7 @@ var LibraryHtml5WebGL = {
{{{ makeSetValue('attributes', C_STRUCTS.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer, '1', 'i32') }}};
{{{ makeSetValue('attributes', C_STRUCTS.EmscriptenWebGLContextAttributes.preserveDrawingBuffer, '1', 'i32') }}};
}
return _emscripten_sync_run_in_main_thread_2({{{ cDefine('EM_PROXIED_CREATE_CONTEXT') }}}, target, attributes);
return _emscripten_webgl_create_context_proxied(target, attributes);
}
}
#endif
Expand Down Expand Up @@ -617,7 +628,7 @@ function handleWebGLProxying(funcs) {
} else if (targetingOffscreenFramebuffer) {
// When targeting only OFFSCREEN_FRAMEBUFFER, unconditionally proxy all GL calls to
// main thread.
funcs[i + '__proxy'] = 'sync';
funcs[i + '__proxy'] = 'sync';
} else {
// Building without OFFSCREENCANVAS_SUPPORT or OFFSCREEN_FRAMEBUFFER; or building
// with OFFSCREENCANVAS_SUPPORT and no OFFSCREEN_FRAMEBUFFER: the application
Expand Down
15 changes: 11 additions & 4 deletions src/library_pthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var LibraryPThread = {
$PThread__deps: ['_emscripten_thread_init',
'$killThread',
'$cancelThread', '$cleanupThread', '$zeroMemory',
'$ptrToString',
'$ptrToString', '$spawnThread',
'_emscripten_thread_free_data',
'exit',
#if !MINIMAL_RUNTIME
Expand Down Expand Up @@ -635,6 +635,13 @@ var LibraryPThread = {
PThread.threadInit();
},

$pthreadCreateProxied__internal: true,
$pthreadCreateProxied__proxy: 'sync',
$pthreadCreateProxied__deps: ['__pthread_create_js'],
$pthreadCreateProxied: function(pthread_ptr, attr, start_routine, arg) {
return ___pthread_create_js(pthread_ptr, attr, start_routine, arg);
},

// ASan wraps the emscripten_builtin_pthread_create call in
// __lsan::ScopedInterceptorDisabler. Unfortunately, that only disables it on
// the thread that made the call. __pthread_create_js gets proxied to the
Expand All @@ -644,7 +651,7 @@ var LibraryPThread = {
// allocations from __pthread_create_js we could also remove this.
__pthread_create_js__noleakcheck: true,
__pthread_create_js__sig: 'iiiii',
__pthread_create_js__deps: ['$spawnThread', 'pthread_self', 'emscripten_sync_run_in_main_thread_4'],
__pthread_create_js__deps: ['$spawnThread', 'pthread_self', '$pthreadCreateProxied'],
__pthread_create_js: function(pthread_ptr, attr, start_routine, arg) {
if (typeof SharedArrayBuffer == 'undefined') {
err('Current environment does not support SharedArrayBuffer, pthreads are not available!');
Expand Down Expand Up @@ -759,7 +766,7 @@ var LibraryPThread = {
// need to transfer ownership of objects, then proxy asynchronously via
// postMessage.
if (ENVIRONMENT_IS_PTHREAD && (transferList.length === 0 || error)) {
return _emscripten_sync_run_in_main_thread_4({{{ cDefine('EM_PROXIED_PTHREAD_CREATE') }}}, pthread_ptr, attr, start_routine, arg);
return pthreadCreateProxied(pthread_ptr, attr, start_routine, arg);
}

// If on the main thread, and accessing Canvas/OffscreenCanvas failed, abort
Expand Down Expand Up @@ -892,7 +899,7 @@ var LibraryPThread = {
#endif
},

emscripten_proxy_to_main_thread_js__deps: ['emscripten_run_in_main_runtime_thread_js'],
emscripten_proxy_to_main_thread_js__deps: ['$withStackSave', 'emscripten_run_in_main_runtime_thread_js'],
emscripten_proxy_to_main_thread_js__docs: '/** @type{function(number, (number|boolean), ...(number|boolean))} */',
emscripten_proxy_to_main_thread_js: function(index, sync) {
// Additional arguments are passed after those two, which are the actual
Expand Down
5 changes: 0 additions & 5 deletions src/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,6 @@ global.LibraryManager = {
libraries.push('library_wget.js');
}

if (USE_PTHREADS) { // TODO: Currently WebGL proxying makes pthreads library depend on WebGL.
libraries.push('library_webgl.js');
libraries.push('library_html5_webgl.js');
}

if (EMSCRIPTEN_TRACING) {
libraries.push('library_memoryprofiler.js');
}
Expand Down
2 changes: 0 additions & 2 deletions src/struct_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -997,8 +997,6 @@
{
"file": "emscripten/threading.h",
"defines": [
"EM_PROXIED_PTHREAD_CREATE",
"EM_PROXIED_CREATE_CONTEXT",
"EM_PROXIED_RESIZE_OFFSCREENCANVAS",
"EM_QUEUED_JS_CALL_MAX_ARGS",
"EM_FUNC_SIG_V",
Expand Down
6 changes: 2 additions & 4 deletions system/include/emscripten/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,8 @@ void *emscripten_sync_run_in_main_thread_7(int function, void *arg1, void *arg2,
#define EM_FUNC_SIG_SPECIAL_INTERNAL (1 << 24)
#define EM_PROXIED_FUNC_SPECIAL(x) (EM_FUNC_SIG_SPECIAL_INTERNAL | ((x) << 20))

#define EM_PROXIED_PTHREAD_CREATE (EM_PROXIED_FUNC_SPECIAL(0) | EM_FUNC_SIG_IIIII)
#define EM_PROXIED_CREATE_CONTEXT (EM_PROXIED_FUNC_SPECIAL(2) | EM_FUNC_SIG_III)
#define EM_PROXIED_RESIZE_OFFSCREENCANVAS (EM_PROXIED_FUNC_SPECIAL(3) | EM_FUNC_SIG_IIII)
#define EM_PROXIED_JS_FUNCTION (EM_PROXIED_FUNC_SPECIAL(4) | EM_FUNC_SIG_D)
#define EM_PROXIED_RESIZE_OFFSCREENCANVAS (EM_PROXIED_FUNC_SPECIAL(0) | EM_FUNC_SIG_IIII)
#define EM_PROXIED_JS_FUNCTION (EM_PROXIED_FUNC_SPECIAL(1) | EM_FUNC_SIG_D)

// Runs the given function synchronously on the main Emscripten runtime thread.
// If this thread is the main thread, the operation is immediately performed,
Expand Down
8 changes: 0 additions & 8 deletions system/lib/pthread/library_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,12 @@ void emscripten_async_waitable_close(em_queued_call* call) {

extern double emscripten_receive_on_main_thread_js(int functionIndex, int numCallArgs, double* args);
extern int _emscripten_notify_thread_queue(pthread_t targetThreadId, pthread_t mainThreadId);
extern int __pthread_create_js(struct pthread *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

static void _do_call(void* arg) {
em_queued_call* q = (em_queued_call*)arg;
// C function pointer
assert(EM_FUNC_SIG_NUM_FUNC_ARGUMENTS(q->functionEnum) <= EM_QUEUED_CALL_MAX_ARGS);
switch (q->functionEnum) {
case EM_PROXIED_PTHREAD_CREATE:
q->returnValue.i =
__pthread_create_js(q->args[0].vp, q->args[1].vp, q->args[2].vp, q->args[3].vp);
break;
case EM_PROXIED_CREATE_CONTEXT:
q->returnValue.i = emscripten_webgl_create_context(q->args[0].cp, q->args[1].vp);
break;
case EM_PROXIED_RESIZE_OFFSCREENCANVAS:
q->returnValue.i =
emscripten_set_canvas_element_size(q->args[0].cp, q->args[1].i, q->args[2].i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ E
F
G
H
I
J
K
o
p
q
r
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ $emscripten_main_thread_process_queued_calls
$emscripten_proxy_main
$emscripten_run_in_main_runtime_thread_js
$emscripten_stack_set_limits
$emscripten_sync_run_in_main_thread
$emscripten_sync_run_in_main_thread
$emscripten_tls_init
$init_file_lock
$init_mparams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ a.k
a.l
a.m
a.n
a.o
Original file line number Diff line number Diff line change
@@ -1 +1 @@
47521
41477
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ k
l
m
n
o
Original file line number Diff line number Diff line change
@@ -1 +1 @@
17533
17345
4 changes: 1 addition & 3 deletions tests/reference_struct_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,7 @@
"EM_LOG_JS_STACK": 16,
"EM_LOG_NO_PATHS": 64,
"EM_LOG_WARN": 2,
"EM_PROXIED_CREATE_CONTEXT": 622854144,
"EM_PROXIED_PTHREAD_CREATE": 687865856,
"EM_PROXIED_RESIZE_OFFSCREENCANVAS": 657457152,
"EM_PROXIED_RESIZE_OFFSCREENCANVAS": 654311424,
"EM_QUEUED_JS_CALL_MAX_ARGS": 20,
"ENAMETOOLONG": 37,
"ENETDOWN": 38,
Expand Down
80 changes: 40 additions & 40 deletions tools/deps_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,52 +105,52 @@
'emscripten_pc_get_function': ['malloc', 'free'],
'emscripten_run_preload_plugins_data': ['malloc'],
'emscripten_run_script_string': ['emscripten_builtin_malloc', 'emscripten_builtin_free'],
'emscripten_set_batterychargingchange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_batterylevelchange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_beforeunload_callback_on_thread': ['malloc', 'free'],
'emscripten_set_blur_callback_on_thread': ['malloc', 'free'],
'emscripten_set_click_callback_on_thread': ['malloc', 'free'],
'emscripten_set_dblclick_callback_on_thread': ['malloc', 'free'],
'emscripten_set_devicemotion_callback_on_thread': ['malloc', 'free'],
'emscripten_set_deviceorientation_callback_on_thread': ['malloc', 'free'],
'emscripten_set_focus_callback_on_thread': ['malloc', 'free'],
'emscripten_set_focusin_callback_on_thread': ['malloc', 'free'],
'emscripten_set_focusout_callback_on_thread': ['malloc', 'free'],
'emscripten_set_fullscreenchange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_gamepadconnected_callback_on_thread': ['malloc', 'free'],
'emscripten_set_gamepaddisconnected_callback_on_thread': ['malloc', 'free'],
'emscripten_set_keydown_callback_on_thread': ['malloc', 'free'],
'emscripten_set_keypress_callback_on_thread': ['malloc', 'free'],
'emscripten_set_keyup_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mousedown_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mouseenter_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mouseleave_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mousemove_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mouseout_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mouseover_callback_on_thread': ['malloc', 'free'],
'emscripten_set_mouseup_callback_on_thread': ['malloc', 'free'],
'emscripten_set_offscreencanvas_size_on_target_thread_js': ['malloc', 'free'],
'emscripten_set_orientationchange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_pointerlockchange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_pointerlockerror_callback_on_thread': ['malloc', 'free'],
'emscripten_set_resize_callback_on_thread': ['malloc', 'free'],
'emscripten_set_scroll_callback_on_thread': ['malloc', 'free'],
'emscripten_set_touchcancel_callback_on_thread': ['malloc', 'free'],
'emscripten_set_touchend_callback_on_thread': ['malloc', 'free'],
'emscripten_set_touchmove_callback_on_thread': ['malloc', 'free'],
'emscripten_set_touchstart_callback_on_thread': ['malloc', 'free'],
'emscripten_set_visibilitychange_callback_on_thread': ['malloc', 'free'],
'emscripten_set_wheel_callback_on_thread': ['malloc', 'free'],
'emscripten_set_batterychargingchange_callback_on_thread': ['malloc'],
'emscripten_set_batterylevelchange_callback_on_thread': ['malloc'],
'emscripten_set_beforeunload_callback_on_thread': ['malloc'],
'emscripten_set_blur_callback_on_thread': ['malloc'],
'emscripten_set_click_callback_on_thread': ['malloc'],
'emscripten_set_dblclick_callback_on_thread': ['malloc'],
'emscripten_set_devicemotion_callback_on_thread': ['malloc'],
'emscripten_set_deviceorientation_callback_on_thread': ['malloc'],
'emscripten_set_focus_callback_on_thread': ['malloc'],
'emscripten_set_focusin_callback_on_thread': ['malloc'],
'emscripten_set_focusout_callback_on_thread': ['malloc'],
'emscripten_set_fullscreenchange_callback_on_thread': ['malloc'],
'emscripten_set_gamepadconnected_callback_on_thread': ['malloc'],
'emscripten_set_gamepaddisconnected_callback_on_thread': ['malloc'],
'emscripten_set_keydown_callback_on_thread': ['malloc'],
'emscripten_set_keypress_callback_on_thread': ['malloc'],
'emscripten_set_keyup_callback_on_thread': ['malloc'],
'emscripten_set_mousedown_callback_on_thread': ['malloc'],
'emscripten_set_mouseenter_callback_on_thread': ['malloc'],
'emscripten_set_mouseleave_callback_on_thread': ['malloc'],
'emscripten_set_mousemove_callback_on_thread': ['malloc'],
'emscripten_set_mouseout_callback_on_thread': ['malloc'],
'emscripten_set_mouseover_callback_on_thread': ['malloc'],
'emscripten_set_mouseup_callback_on_thread': ['malloc'],
'emscripten_set_offscreencanvas_size_on_target_thread_js': ['malloc'],
'emscripten_set_orientationchange_callback_on_thread': ['malloc'],
'emscripten_set_pointerlockchange_callback_on_thread': ['malloc'],
'emscripten_set_pointerlockerror_callback_on_thread': ['malloc'],
'emscripten_set_resize_callback_on_thread': ['malloc'],
'emscripten_set_scroll_callback_on_thread': ['malloc'],
'emscripten_set_touchcancel_callback_on_thread': ['malloc'],
'emscripten_set_touchend_callback_on_thread': ['malloc'],
'emscripten_set_touchmove_callback_on_thread': ['malloc'],
'emscripten_set_touchstart_callback_on_thread': ['malloc'],
'emscripten_set_visibilitychange_callback_on_thread': ['malloc'],
'emscripten_set_wheel_callback_on_thread': ['malloc'],
'emscripten_webgl_create_context': ['malloc'],
'emscripten_webgl_get_parameter_utf8': ['malloc'],
'emscripten_webgl_get_program_info_log_utf8': ['malloc'],
'emscripten_webgl_get_shader_info_log_utf8': ['malloc'],
'emscripten_webgl_get_shader_source_utf8': ['malloc'],
'emscripten_webgl_get_supported_extensions': ['malloc'],
'emscripten_websocket_set_onclose_callback_on_thread': ['malloc', 'free'],
'emscripten_websocket_set_onerror_callback_on_thread': ['malloc', 'free'],
'emscripten_websocket_set_onclose_callback_on_thread': ['malloc'],
'emscripten_websocket_set_onerror_callback_on_thread': ['malloc'],
'emscripten_websocket_set_onmessage_callback_on_thread': ['malloc', 'free'],
'emscripten_websocket_set_onopen_callback_on_thread': ['malloc', 'free'],
'emscripten_websocket_set_onopen_callback_on_thread': ['malloc'],
'emscripten_wget_data': ['malloc', 'free'],
'getaddrinfo': ['malloc', 'htonl', 'htons', 'ntohs'],
'gethostbyaddr': ['malloc', 'htons'],
Expand All @@ -170,7 +170,7 @@
'localtime': ['malloc'],
'localtime_r': ['malloc'],
'mktime': ['malloc'],
'pthread_create': ['malloc', 'free', 'emscripten_main_thread_process_queued_calls'],
'pthread_create': ['malloc', 'emscripten_main_thread_process_queued_calls'],
'recv': ['htons'],
'recvmsg': ['htons'],
'accept': ['htons'],
Expand Down

0 comments on commit a18bbf7

Please sign in to comment.