removing threads from paused list before re-queueing them

This commit is contained in:
Alex Shinn 2010-08-26 21:18:00 +09:00
parent 148528ecab
commit 280d0dc7b3

View file

@ -91,11 +91,26 @@ sexp sexp_thread_terminate (sexp ctx sexp_api_params(self, n), sexp thread) {
return res; return res;
} }
static int sexp_delete_list (sexp ctx, int global, sexp x) {
sexp ls1=NULL, ls2=sexp_global(ctx, global);
for ( ; sexp_pairp(ls2) && sexp_car(ls2) != x; ls1=ls2, ls2=sexp_cdr(ls2))
;
if (sexp_pairp(ls2)) {
if (ls1) sexp_cdr(ls1) = sexp_cdr(ls2);
else sexp_global(ctx, global) = sexp_cdr(ls2);
return 1;
} else {
return 0;
}
}
static void sexp_insert_timed (sexp ctx, sexp thread, sexp timeout) { static void sexp_insert_timed (sexp ctx, sexp thread, sexp timeout) {
#if SEXP_USE_FLONUMS #if SEXP_USE_FLONUMS
double d; double d;
#endif #endif
sexp ls1=SEXP_NULL, ls2=sexp_global(ctx, SEXP_G_THREADS_PAUSED); sexp ls1=SEXP_NULL, ls2;
sexp_delete_list(ctx, SEXP_G_THREADS_PAUSED, thread);
ls2 = sexp_global(ctx, SEXP_G_THREADS_PAUSED);
if (sexp_integerp(timeout) || sexp_flonump(timeout)) if (sexp_integerp(timeout) || sexp_flonump(timeout))
gettimeofday(&sexp_context_timeval(thread), NULL); gettimeofday(&sexp_context_timeval(thread), NULL);
if (sexp_integerp(timeout)) { if (sexp_integerp(timeout)) {
@ -106,11 +121,14 @@ static void sexp_insert_timed (sexp ctx, sexp thread, sexp timeout) {
sexp_context_timeval(thread).tv_sec += trunc(d); sexp_context_timeval(thread).tv_sec += trunc(d);
sexp_context_timeval(thread).tv_usec += (d-trunc(d))*1000000; sexp_context_timeval(thread).tv_usec += (d-trunc(d))*1000000;
#endif #endif
} else if (sexp_contextp(timeout)) {
sexp_context_timeval(thread).tv_sec = sexp_context_timeval(timeout).tv_sec;
sexp_context_timeval(thread).tv_usec = sexp_context_timeval(timeout).tv_usec;
} else { } else {
sexp_context_timeval(thread).tv_sec = 0; sexp_context_timeval(thread).tv_sec = 0;
sexp_context_timeval(thread).tv_usec = 0; sexp_context_timeval(thread).tv_usec = 0;
} }
if (sexp_numberp(timeout)) if (sexp_numberp(timeout) || sexp_contextp(timeout))
while (sexp_pairp(ls2) while (sexp_pairp(ls2)
&& sexp_context_before(sexp_car(ls2), sexp_context_timeval(thread))) && sexp_context_before(sexp_car(ls2), sexp_context_timeval(thread)))
ls1=ls2, ls2=sexp_cdr(ls2); ls1=ls2, ls2=sexp_cdr(ls2);
@ -386,6 +404,14 @@ sexp sexp_scheduler (sexp ctx sexp_api_params(self, n), sexp root_thread) {
if (sexp_context_waitp(res)) { if (sexp_context_waitp(res)) {
/* the only thread available was waiting */ /* the only thread available was waiting */
if (sexp_pairp(paused)
&& sexp_context_before(sexp_car(paused), sexp_context_timeval(res))) {
tmp = res;
res = sexp_car(paused);
sexp_global(ctx, SEXP_G_THREADS_PAUSED) = sexp_cdr(paused);
if (sexp_not(sexp_memq(ctx, tmp, paused)))
sexp_insert_timed(ctx, tmp, tmp);
}
sexp_wait_on_single_thread(res); sexp_wait_on_single_thread(res);
sexp_context_timeoutp(res) = 1; sexp_context_timeoutp(res) = 1;
sexp_context_waitp(res) = 0; sexp_context_waitp(res) = 0;