@@ -251,7 +251,9 @@ static void memprof_ctx_iter(th_ctx_action f, void* data)
251
251
} while (th != curr_thread );
252
252
}
253
253
254
- static void thread_save_runtime_state (void )
254
+ /* Saving and restoring runtime state in curr_thread */
255
+
256
+ CAMLexport void caml_thread_save_runtime_state (void )
255
257
{
256
258
if (Caml_state -> _in_minor_collection )
257
259
caml_fatal_error ("Thread switch from inside minor GC" );
@@ -279,8 +281,12 @@ static void thread_save_runtime_state(void)
279
281
caml_memprof_leave_thread ();
280
282
}
281
283
282
- static void thread_restore_runtime_state (void )
284
+ CAMLexport void caml_thread_restore_runtime_state (void )
283
285
{
286
+ /* Update curr_thread to point to the thread descriptor corresponding
287
+ to the thread currently executing */
288
+ curr_thread = st_tls_get (thread_descriptor_key );
289
+
284
290
#ifdef NATIVE_CODE
285
291
Caml_state -> _top_of_stack = curr_thread -> top_of_stack ;
286
292
Caml_state -> _bottom_of_stack = curr_thread -> bottom_of_stack ;
@@ -305,24 +311,16 @@ static void thread_restore_runtime_state(void)
305
311
caml_memprof_enter_thread (curr_thread -> memprof_ctx );
306
312
}
307
313
308
- CAMLexport void caml_thread_switch_runtime_state (void )
309
- {
310
- caml_thread_t new_thread = st_tls_get (thread_descriptor_key );
311
- if (new_thread == curr_thread ) return ;
312
- thread_save_runtime_state ();
313
- curr_thread = new_thread ;
314
- thread_restore_runtime_state ();
315
- }
316
-
317
314
CAMLexport void caml_switch_runtime_locking_scheme (struct caml_locking_scheme * new )
318
315
{
319
316
struct caml_locking_scheme * old ;
320
317
318
+ caml_thread_save_runtime_state ();
321
319
old = atomic_exchange (& caml_locking_scheme , new );
322
320
/* We hold 'old', but it is no longer the runtime lock */
323
321
old -> unlock (old -> context );
324
322
acquire_runtime_lock ();
325
- caml_thread_switch_runtime_state ();
323
+ caml_thread_restore_runtime_state ();
326
324
}
327
325
328
326
@@ -331,6 +329,9 @@ CAMLexport void caml_switch_runtime_locking_scheme(struct caml_locking_scheme* n
331
329
332
330
static void caml_thread_enter_blocking_section (void )
333
331
{
332
+ /* Save the current runtime state in the thread descriptor
333
+ of the current thread */
334
+ caml_thread_save_runtime_state ();
334
335
/* Tell other threads that the runtime is free */
335
336
release_runtime_lock ();
336
337
}
@@ -345,7 +346,7 @@ static void caml_thread_leave_blocking_section(void)
345
346
#endif
346
347
/* Wait until the runtime is free */
347
348
acquire_runtime_lock ();
348
- caml_thread_switch_runtime_state ();
349
+ caml_thread_restore_runtime_state ();
349
350
#ifdef _WIN32
350
351
SetLastError (error );
351
352
#endif
@@ -637,7 +638,7 @@ static void caml_thread_stop(void)
637
638
changed as the thread was running, so we save it in the
638
639
curr_thread data to make sure that the cleanup logic
639
640
below uses accurate information. */
640
- thread_save_runtime_state ();
641
+ caml_thread_save_runtime_state ();
641
642
/* Tell memprof that this thread is terminating. */
642
643
caml_memprof_delete_th_ctx (curr_thread -> memprof_ctx );
643
644
/* Signal that the thread has terminated */
@@ -888,6 +889,7 @@ CAMLprim value caml_thread_yield(value unit) /* ML */
888
889
*/
889
890
caml_raise_async_if_exception (caml_process_pending_signals_exn (),
890
891
"signal handler" );
892
+ caml_thread_save_runtime_state ();
891
893
/* caml_locking_scheme may have changed in caml_process_pending_signals_exn */
892
894
s = atomic_load (& caml_locking_scheme );
893
895
s -> yield (s -> context );
@@ -896,7 +898,7 @@ CAMLprim value caml_thread_yield(value unit) /* ML */
896
898
s -> unlock (s -> context );
897
899
acquire_runtime_lock ();
898
900
}
899
- caml_thread_switch_runtime_state ();
901
+ caml_thread_restore_runtime_state ();
900
902
caml_raise_async_if_exception (caml_process_pending_signals_exn (),
901
903
"signal handler" );
902
904
0 commit comments