cs: fix touch
on future waiting for an atomic action
When the runtime thread `touch`es a future that is blocked on an atomic action (just as JIT compilation), the runtime thread would eagerly run the action, but still leave the future on the atomic-action queue. Atomic actions tend to be ok to run a second time (including JIT compilation), so a problem may not show up immediately, but a semaphore can get out of sync and cause problems later.
This commit is contained in:
parent
42cb80bc70
commit
1117392cb5
|
@ -2023,13 +2023,20 @@ Scheme_Object *general_touch(int argc, Scheme_Object *argv[])
|
||||||
}
|
}
|
||||||
else if (ft->status == WAITING_FOR_PRIM)
|
else if (ft->status == WAITING_FOR_PRIM)
|
||||||
{
|
{
|
||||||
/* Invoke the primitive and stash the result.
|
if (ft->rt_prim_is_atomic) {
|
||||||
Release the lock so other threads can manipulate the queue
|
/* Should be in the atomic-wait queue, so
|
||||||
while the runtime call executes. */
|
handle those actions now: */
|
||||||
ft->status = HANDLING_PRIM;
|
mzrt_mutex_unlock(fs->future_mutex);
|
||||||
ft->want_lw = 0;
|
scheme_check_future_work();
|
||||||
mzrt_mutex_unlock(fs->future_mutex);
|
} else {
|
||||||
invoke_rtcall(fs, ft, 0);
|
/* Invoke the primitive and stash the result.
|
||||||
|
Release the lock so other threads can manipulate the queue
|
||||||
|
while the runtime call executes. */
|
||||||
|
ft->status = HANDLING_PRIM;
|
||||||
|
ft->want_lw = 0;
|
||||||
|
mzrt_mutex_unlock(fs->future_mutex);
|
||||||
|
invoke_rtcall(fs, ft, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ft->maybe_suspended_lw && (ft->status != WAITING_FOR_FSEMA))
|
else if (ft->maybe_suspended_lw && (ft->status != WAITING_FOR_FSEMA))
|
||||||
{
|
{
|
||||||
|
@ -2769,6 +2776,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
||||||
if (fts->is_runtime_thread) {
|
if (fts->is_runtime_thread) {
|
||||||
/* On runtime thread - must be slow-path tracing */
|
/* On runtime thread - must be slow-path tracing */
|
||||||
future->prim_func = func;
|
future->prim_func = func;
|
||||||
|
future->rt_prim_is_atomic = 0;
|
||||||
future->status = WAITING_FOR_PRIM;
|
future->status = WAITING_FOR_PRIM;
|
||||||
invoke_rtcall(scheme_future_state, future, 0);
|
invoke_rtcall(scheme_future_state, future, 0);
|
||||||
fts->worker_gc_counter = *fs->gc_counter_ptr;
|
fts->worker_gc_counter = *fs->gc_counter_ptr;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user