Fix fsemaphore-try-wait? so the sema's count is decremented. Make fsemaphore-wait and other futures-related functions cooperate with the GC better.
This commit is contained in:
parent
825a931ffa
commit
ca5c061a71
|
@ -299,6 +299,18 @@ We should also test deep continuations.
|
||||||
(check-equal? #f (touch f1))
|
(check-equal? #f (touch f1))
|
||||||
(check-equal? #t (touch f2)))
|
(check-equal? #t (touch f2)))
|
||||||
|
|
||||||
|
(let ([m (make-fsemaphore 3)])
|
||||||
|
(fsemaphore-try-wait? m)
|
||||||
|
(check-equal? 2 (fsemaphore-count m)))
|
||||||
|
|
||||||
|
(let* ([m (make-fsemaphore 0)]
|
||||||
|
[f (future (λ ()
|
||||||
|
(fsemaphore-post m)
|
||||||
|
42))])
|
||||||
|
(sleep 0.5)
|
||||||
|
(fsemaphore-try-wait? m)
|
||||||
|
(check-equal? 0 (fsemaphore-count m)))
|
||||||
|
|
||||||
;Test fsemaphore wait on a future thread
|
;Test fsemaphore wait on a future thread
|
||||||
;(here the future thread should be able to capture the cont. locally)
|
;(here the future thread should be able to capture the cont. locally)
|
||||||
(let* ([m (make-fsemaphore 0)]
|
(let* ([m (make-fsemaphore 0)]
|
||||||
|
|
|
@ -1015,6 +1015,7 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
sema = (fsemaphore_t*)argv[0];
|
sema = (fsemaphore_t*)argv[0];
|
||||||
|
jit_future_storage[0] = (void*)sema;
|
||||||
mzrt_mutex_lock(sema->mut);
|
mzrt_mutex_lock(sema->mut);
|
||||||
if (!sema->ready) {
|
if (!sema->ready) {
|
||||||
if (!fts) {
|
if (!fts) {
|
||||||
|
@ -1022,11 +1023,15 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
|
||||||
fsema to be ready while cooperating with the scheduler */
|
fsema to be ready while cooperating with the scheduler */
|
||||||
mzrt_mutex_unlock(sema->mut);
|
mzrt_mutex_unlock(sema->mut);
|
||||||
scheme_block_until(fsemaphore_ready, NULL, (Scheme_Object*)sema, 0);
|
scheme_block_until(fsemaphore_ready, NULL, (Scheme_Object*)sema, 0);
|
||||||
|
|
||||||
|
/* Fetch the sema pointer again, in case it was moved during a GC */
|
||||||
|
sema = (fsemaphore_t*)jit_future_storage[0];
|
||||||
mzrt_mutex_lock(sema->mut);
|
mzrt_mutex_lock(sema->mut);
|
||||||
} else {
|
} else {
|
||||||
/* On a future thread, suspend the future (to be
|
/* On a future thread, suspend the future (to be
|
||||||
resumed whenever the fsema becomes ready */
|
resumed whenever the fsema becomes ready */
|
||||||
future_t *future = fts->thread->current_ft;
|
future_t *future = fts->thread->current_ft;
|
||||||
|
jit_future_storage[1] = (void*)future;
|
||||||
if (!future) {
|
if (!future) {
|
||||||
/* Should never be here */
|
/* Should never be here */
|
||||||
scheme_log_abort("fsemaphore-wait: future was NULL for future thread.");
|
scheme_log_abort("fsemaphore-wait: future was NULL for future thread.");
|
||||||
|
@ -1075,6 +1080,10 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fetch the future and sema pointers again, in case moved by a GC */
|
||||||
|
sema = (fsemaphore_t*)jit_future_storage[0];
|
||||||
|
future = (future_t*)jit_future_storage[1];
|
||||||
|
|
||||||
/* Check again to see whether the sema has become ready */
|
/* Check again to see whether the sema has become ready */
|
||||||
mzrt_mutex_lock(sema->mut);
|
mzrt_mutex_lock(sema->mut);
|
||||||
if (sema->ready) {
|
if (sema->ready) {
|
||||||
|
@ -1121,6 +1130,7 @@ Scheme_Object *scheme_fsemaphore_try_wait(int argc, Scheme_Object **argv)
|
||||||
if (!sema->ready) {
|
if (!sema->ready) {
|
||||||
ret = scheme_false;
|
ret = scheme_false;
|
||||||
} else {
|
} else {
|
||||||
|
sema->ready--;
|
||||||
ret = scheme_true;
|
ret = scheme_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1807,9 +1817,10 @@ static void future_raise_wrong_type_exn(const char *who, const char *expected_ty
|
||||||
|
|
||||||
future->time_of_request = scheme_get_inexact_milliseconds();
|
future->time_of_request = scheme_get_inexact_milliseconds();
|
||||||
future->source_of_request = who;
|
future->source_of_request = who;
|
||||||
//future->src_type = ??
|
|
||||||
future_do_runtimecall(fts, (void*)scheme_wrong_type, 0);
|
future_do_runtimecall(fts, (void*)scheme_wrong_type, 0);
|
||||||
|
|
||||||
|
/* Fetch the future again, in case moved by a GC */
|
||||||
|
future = fts->thread->current_ft;
|
||||||
future->arg_str0 = NULL;
|
future->arg_str0 = NULL;
|
||||||
future->arg_str1 = NULL;
|
future->arg_str1 = NULL;
|
||||||
future->arg_i2 = 0;
|
future->arg_i2 = 0;
|
||||||
|
@ -1834,6 +1845,9 @@ void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void
|
||||||
|
|
||||||
future_do_runtimecall(fts, (void*)f, 1);
|
future_do_runtimecall(fts, (void*)f, 1);
|
||||||
|
|
||||||
|
/* Fetch the future again, in case moved by a GC */
|
||||||
|
future = fts->thread->current_ft;
|
||||||
|
|
||||||
future->arg_S0 = NULL;
|
future->arg_S0 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1853,6 +1867,10 @@ Scheme_Object *scheme_rtcall_make_fsemaphore(const char *who, int src_type, int
|
||||||
future->source_type = src_type;
|
future->source_type = src_type;
|
||||||
|
|
||||||
future_do_runtimecall(fts, (void*)scheme_make_fsemaphore_inl, 1);
|
future_do_runtimecall(fts, (void*)scheme_make_fsemaphore_inl, 1);
|
||||||
|
|
||||||
|
/* Fetch the future again, in case moved by a GC */
|
||||||
|
future = fts->thread->current_ft;
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
retval = future->retval_s;
|
retval = future->retval_s;
|
||||||
future->retval_s = NULL;
|
future->retval_s = NULL;
|
||||||
|
@ -1883,6 +1901,9 @@ void scheme_rtcall_allocate_values(const char *who, int src_type, int count, Sch
|
||||||
|
|
||||||
future_do_runtimecall(fts, (void*)f, 1);
|
future_do_runtimecall(fts, (void*)f, 1);
|
||||||
|
|
||||||
|
/* Fetch the future again, in case moved by a GC */
|
||||||
|
future = fts->thread->current_ft;
|
||||||
|
|
||||||
future->arg_s0 = NULL;
|
future->arg_s0 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user