Skip to content

Commit

Permalink
Simplify systhreads thread-local state management
Browse files Browse the repository at this point in the history
Use a global key to access the per-thread `caml_thread_t` rather than
have a key per domain. This fixes the issue reported in ocaml#11226.
  • Loading branch information
kayceesrk committed May 10, 2022
1 parent f7eb3b5 commit 989e62d
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions otherlibs/systhreads/st_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ struct caml_thread_struct {

typedef struct caml_thread_struct* caml_thread_t;

/* Thread-local key for accessing the current thread's [caml_thread_t] */
st_tlskey caml_thread_key;

/* overall table for threads across domains */
struct caml_thread_table {
caml_thread_t all_threads;
caml_thread_t current_thread;
st_tlskey thread_key;
st_masterlock thread_lock;
int tick_thread_running;
st_thread_id tick_thread_id;
Expand All @@ -116,10 +118,6 @@ static struct caml_thread_table thread_table[Max_domains];
/* The thread identifier of the "tick" thread for this domain */
#define Tick_thread_id thread_table[Caml_state->id].tick_thread_id

/* The key used for storing the thread descriptor in the specific data
of the corresponding system thread. */
#define Thread_key thread_table[Caml_state->id].thread_key

/* Identifier for next thread creation */
static atomic_uintnat thread_next_id = 0;

Expand Down Expand Up @@ -214,7 +212,7 @@ static void caml_thread_leave_blocking_section(void)
st_masterlock_acquire(&Thread_main_lock);
/* Update Current_thread to point to the thread descriptor corresponding to
the thread currently executing */
Current_thread = st_tls_get(Thread_key);
Current_thread = st_tls_get(caml_thread_key);
/* Restore the runtime state from the curr_thread descriptor */
caml_thread_restore_runtime_state();
}
Expand Down Expand Up @@ -365,8 +363,7 @@ CAMLprim value caml_thread_initialize_domain(value v)
new_thread->prev = new_thread;
new_thread->backtrace_last_exn = Val_unit;

st_tls_newkey(&Thread_key);
st_tls_set(Thread_key, (void *) new_thread);
st_tls_set(caml_thread_key, new_thread);

All_threads = new_thread;
Current_thread = new_thread;
Expand Down Expand Up @@ -402,6 +399,9 @@ CAMLprim value caml_thread_initialize(value unit)
caml_failwith("caml_thread_initialize: cannot initialize Thread "
"while several domains are running.");

/* Initialize the key to the [caml_thread_t] structure */
st_tls_newkey(&caml_thread_key);

/* First initialise the systhread chain on this domain */
caml_thread_initialize_domain(Val_unit);

Expand Down Expand Up @@ -476,12 +476,12 @@ static void * caml_thread_start(void * v)

caml_init_domain_self(th->domain_id);

st_tls_set(Thread_key, th);
st_tls_set(caml_thread_key, th);

caml_domain_set_name("Domain");

st_masterlock_acquire(&Thread_main_lock);
Current_thread = st_tls_get(Thread_key);
Current_thread = st_tls_get(caml_thread_key);
caml_thread_restore_runtime_state();

#ifdef POSIX_SIGNALS
Expand Down Expand Up @@ -586,7 +586,7 @@ CAMLexport int caml_c_thread_register(void)
if (Caml_state == NULL) {
caml_init_domain_self(0);
};
if (st_tls_get(Thread_key) != NULL) return 0;
if (st_tls_get(caml_thread_key) != NULL) return 0;
/* Take master lock to protect access to the runtime */
st_masterlock_acquire(&Thread_main_lock);
/* Create a thread info block */
Expand All @@ -608,7 +608,7 @@ CAMLexport int caml_c_thread_register(void)
All_threads->next = th;
}
/* Associate the thread descriptor with the thread */
st_tls_set(Thread_key, (void *) th);
st_tls_set(caml_thread_key, (void *) th);
/* Allocate the thread descriptor on the heap */
th->descr = caml_thread_new_descriptor(Val_unit); /* no closure */

Expand All @@ -633,13 +633,13 @@ CAMLexport int caml_c_thread_unregister(void)
/* If Caml_state is not set, this thread was likely not registered */
if (Caml_state == NULL) return 0;

th = st_tls_get(Thread_key);
th = st_tls_get(caml_thread_key);
/* Not registered? */
if (th == NULL) return 0;
/* Wait until the runtime is available */
st_masterlock_acquire(&Thread_main_lock);
/* Forget the thread descriptor */
st_tls_set(Thread_key, NULL);
st_tls_set(caml_thread_key, NULL);
/* Remove thread info block from list of threads, and free it */
caml_thread_remove_info(th);

Expand Down Expand Up @@ -699,7 +699,7 @@ CAMLprim value caml_thread_yield(value unit)
caml_raise_if_exception(caml_process_pending_signals_exn());
caml_thread_save_runtime_state();
st_thread_yield(&Thread_main_lock);
Current_thread = st_tls_get(Thread_key);
Current_thread = st_tls_get(caml_thread_key);
caml_thread_restore_runtime_state();
caml_raise_if_exception(caml_process_pending_signals_exn());

Expand Down

0 comments on commit 989e62d

Please sign in to comment.