Skip to content

Replace thread save/restore API with switch #1869

New issue

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

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

Already on GitHub? # to your account

Merged
merged 1 commit into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 15 additions & 17 deletions ocaml/otherlibs/systhreads/st_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,7 @@ static void memprof_ctx_iter(th_ctx_action f, void* data)
} while (th != curr_thread);
}

/* Saving and restoring runtime state in curr_thread */

CAMLexport void caml_thread_save_runtime_state(void)
static void thread_save_runtime_state(void)
{
if (Caml_state->in_minor_collection)
caml_fatal_error("Thread switch from inside minor GC");
Expand Down Expand Up @@ -273,12 +271,8 @@ CAMLexport void caml_thread_save_runtime_state(void)
caml_memprof_leave_thread();
}

CAMLexport void caml_thread_restore_runtime_state(void)
static void thread_restore_runtime_state(void)
{
/* Update curr_thread to point to the thread descriptor corresponding
to the thread currently executing */
curr_thread = st_tls_get(thread_descriptor_key);

#ifdef NATIVE_CODE
Caml_state->top_of_stack = curr_thread->top_of_stack;
Caml_state->bottom_of_stack= curr_thread->bottom_of_stack;
Expand All @@ -303,16 +297,24 @@ CAMLexport void caml_thread_restore_runtime_state(void)
caml_memprof_enter_thread(curr_thread->memprof_ctx);
}

CAMLexport void caml_thread_switch_runtime_state(void)
{
caml_thread_t new_thread = st_tls_get(thread_descriptor_key);
if (new_thread == curr_thread) return;
thread_save_runtime_state();
curr_thread = new_thread;
thread_restore_runtime_state();
}

CAMLexport void caml_switch_runtime_locking_scheme(struct caml_locking_scheme* new)
{
struct caml_locking_scheme* old;

caml_thread_save_runtime_state();
old = atomic_exchange(&caml_locking_scheme, new);
/* We hold 'old', but it is no longer the runtime lock */
old->unlock(old->context);
acquire_runtime_lock();
caml_thread_restore_runtime_state();
caml_thread_switch_runtime_state();
}


Expand All @@ -321,9 +323,6 @@ CAMLexport void caml_switch_runtime_locking_scheme(struct caml_locking_scheme* n

static void caml_thread_enter_blocking_section(void)
{
/* Save the current runtime state in the thread descriptor
of the current thread */
caml_thread_save_runtime_state();
/* Tell other threads that the runtime is free */
release_runtime_lock();
}
Expand All @@ -338,7 +337,7 @@ static void caml_thread_leave_blocking_section(void)
#endif
/* Wait until the runtime is free */
acquire_runtime_lock();
caml_thread_restore_runtime_state();
caml_thread_switch_runtime_state();
#ifdef _WIN32
SetLastError(error);
#endif
Expand Down Expand Up @@ -630,7 +629,7 @@ static void caml_thread_stop(void)
changed as the thread was running, so we save it in the
curr_thread data to make sure that the cleanup logic
below uses accurate information. */
caml_thread_save_runtime_state();
thread_save_runtime_state();
/* Tell memprof that this thread is terminating. */
caml_memprof_delete_th_ctx(curr_thread->memprof_ctx);
/* Signal that the thread has terminated */
Expand Down Expand Up @@ -881,7 +880,6 @@ CAMLprim value caml_thread_yield(value unit) /* ML */
*/
caml_raise_async_if_exception(caml_process_pending_signals_exn(),
"signal handler");
caml_thread_save_runtime_state();
/* caml_locking_scheme may have changed in caml_process_pending_signals_exn */
s = atomic_load(&caml_locking_scheme);
s->yield(s->context);
Expand All @@ -890,7 +888,7 @@ CAMLprim value caml_thread_yield(value unit) /* ML */
s->unlock(s->context);
acquire_runtime_lock();
}
caml_thread_restore_runtime_state();
caml_thread_switch_runtime_state();
caml_raise_async_if_exception(caml_process_pending_signals_exn(),
"signal handler");

Expand Down
10 changes: 6 additions & 4 deletions ocaml/otherlibs/systhreads/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ CAMLextern_libthreads
void caml_switch_runtime_locking_scheme(struct caml_locking_scheme*);

CAMLextern_libthreads
void caml_thread_save_runtime_state(void);

CAMLextern_libthreads
void caml_thread_restore_runtime_state(void);
void caml_thread_switch_runtime_state(void);

/* A prior version of this API used save/restore rather than a single switch.
For compatibility, aliases are defined for the old API.
(These will be removed when the lone user of this API is updated) */
#define caml_thread_save_runtime_state()
#define caml_thread_restore_runtime_state caml_thread_switch_runtime_state

#ifdef __cplusplus
}
Expand Down