support for dlopen within threads #1202
Open
qianxichen233 wants to merge 2 commits into
Open
Conversation
…Task 3) When one thread calls dlopen(), all other running threads in the same cage now automatically get the library instantiated into their Wasm stores via a fire-and-forget epoch interrupt (EPOCH_DLOPEN = 0xd10ad). Runtime changes: - cage/signal: add epoch_dlopen_trigger_others() — sets EPOCH_DLOPEN on all other threads and sends SIGUSR2 to interrupt blocked syscalls - lind-multi-process/signal: add handle_dlopen_replay() — called from signal_handler for all non-main threads; pre-grows the table, calls module_with_child, and registers library symbols for dlsym - lind-boot/execute: drop got_guard before epoch_dlopen_trigger_others to avoid lock contention; call epoch_dlopen_trigger_others after append_module - lind-multi-process/lib: snapshot dlopen_modules at the same point as global_snapshots (before asyncify unwind) to eliminate a TOCTOU race in pthread_create_call - wasmtime/linker: skip apply_global_snapshots when snapshots is empty (the dlopen replay path; globals are set by attach_memory_base/attach_table_base) - lind-utils (LindGOT::new_entry): pre-fill duplicate GOT handlers from symbol_cache so replaying threads see correct function table indices Test (thread_dlopen_concurrent.c): Uses a two-barrier design — workers first signal via g_ready that they are registered, then main calls dlopen (EPOCH_DLOPEN fires on all workers), then main releases via g_go. The epoch check at pthread_barrier_wait's Wasm function entry delivers handle_dlopen_replay before any library call. lib.c: add add(int,int) export used by the new test.
Contributor
End-to-End Test ReportTest Previewgrate harnessGrate Test Report
Cases
static harnessTest ReportDeterministic TestsSummary
Test Results by Category
Fail TestsSummary
wasm harnessTest ReportDeterministic TestsSummary
Test Results by Category
Fail TestsSummary
Test Results by Category
C++ harnessSummary
Cases
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dlopen within threads: epoch-based cross-thread library replay (#1028 Task 3)
When one thread calls
dlopen()while other threads are already running, the newly-loaded library must be instantiated into every running thread's Wasm store. Previously this was unsupported (guarded with a panic).Mechanism (fire-and-forget)
epoch_dlopen_trigger_others()setsEPOCH_DLOPEN(0xd10ad) on all other registered threads and sendsSIGUSR2to interrupt any blocked syscallshandle_dlopen_replay()runs inside each thread's epoch callback: pre-grows the shared function table, instantiates the library viamodule_with_child, and pre-fills GOT cells fromsymbol_cacheso function indices are correct without a full GOT updateLindGOT::new_entrypre-fills duplicate GOT handlers from cache so replaying threads immediately see valid function table indiceshandle_dlopen_replaydlopen_modulesis snapshotted at the same point asglobal_snapshots(before asyncify unwind inpthread_create_call) to eliminate a TOCTOU raceLimitation
The epoch fires at Wasm function entries. Application code must ensure at least one function-call epoch checkpoint is reached between when dlopen fires and when worker threads first call into the newly-loaded library. The test enforces this with a two-barrier design: workers signal they are registered before main calls dlopen, then wait on a second barrier whose function-entry epoch check delivers the replay.
Test
thread_dlopen_concurrent.c— 4 workers block ong_ready(guaranteeing registration), main callsdlopen, then releases viag_go. Workers verify the library via both an inherited function pointer and an independentdlsymcall. Passes 15/15 runs consistently.