improve comments on `future_t' fields; remove a redundant field

This commit is contained in:
Matthew Flatt 2011-12-02 09:58:22 -07:00
parent c2fac607f0
commit 67c3aa4b2d
4 changed files with 52 additions and 16 deletions

View File

@ -1454,7 +1454,6 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
scheme_fill_lwc_end(); scheme_fill_lwc_end();
future->lwc = scheme_current_lwc; future->lwc = scheme_current_lwc;
future->fts = fts; future->fts = fts;
future->arg_p = scheme_current_thread;
/* Try to capture it locally (on this thread) */ /* Try to capture it locally (on this thread) */
if (GC_gen0_alloc_page_ptr if (GC_gen0_alloc_page_ptr
@ -2186,7 +2185,8 @@ static Scheme_Object *apply_future_lw(future_t *ft)
static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock) static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock)
XFORM_SKIP_PROC XFORM_SKIP_PROC
/* This function explicitly cooperates with the GC by storing the /* The lock is *not* help when calling this function.
This function explicitly cooperates with the GC by storing the
pointers it needs to save across a collection in `storage', so pointers it needs to save across a collection in `storage', so
it can be used in a future thread. If future-thread-local it can be used in a future thread. If future-thread-local
allocation fails, the result is 0. */ allocation fails, the result is 0. */
@ -2196,7 +2196,7 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
storage[2] = ft; storage[2] = ft;
lw = scheme_capture_lightweight_continuation(ft->arg_p, ft->lwc, storage); lw = scheme_capture_lightweight_continuation(ft->fts->thread, ft->lwc, storage);
if (!lw) return 0; if (!lw) return 0;
ft = (future_t *)storage[2]; ft = (future_t *)storage[2];
@ -2212,9 +2212,10 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
continuation. */ continuation. */
return 1; return 1;
} }
ft->want_lw = 0;
} }
ft->want_lw = 0;
ft->fts->thread->current_ft = NULL; /* tells worker thread that it no longer ft->fts->thread->current_ft = NULL; /* tells worker thread that it no longer
needs to handle the future */ needs to handle the future */
@ -2392,7 +2393,6 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
scheme_fill_lwc_end(); scheme_fill_lwc_end();
future->lwc = scheme_current_lwc; future->lwc = scheme_current_lwc;
future->fts = fts; future->fts = fts;
future->arg_p = scheme_current_thread;
fid = future->id; fid = future->id;
@ -2744,8 +2744,8 @@ static int push_marks(future_t *f, Scheme_Cont_Frame_Data *d)
{ {
if (f->suspended_lw) { if (f->suspended_lw) {
return scheme_push_marks_from_lightweight_continuation(f->suspended_lw, d); return scheme_push_marks_from_lightweight_continuation(f->suspended_lw, d);
} else if (f->arg_p) { } else if (f->fts->thread) {
return scheme_push_marks_from_thread(f->arg_p, d); return scheme_push_marks_from_thread(f->fts->thread, d);
} }
return 0; return 0;
@ -2866,7 +2866,6 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future, int is_a
need_pop = push_marks(future, &mark_d); need_pop = push_marks(future, &mark_d);
else else
need_pop = 0; need_pop = 0;
future->arg_p = NULL;
switch (future->prim_protocol) switch (future->prim_protocol)
{ {

View File

@ -59,13 +59,16 @@ typedef struct future_t {
int id; int id;
int thread_short_id; int thread_short_id;
int status;
/* The status field is the main locking mechanism. It /* The status field is the main locking mechanism. It
should only be read and written when holding a lock should only be read and written when holding a lock
(and all associated fields for a status should be (and all associated fields for a status should be
set at the same time). */ set at the same time). */
int status;
mzrt_sema *can_continue_sema; mzrt_sema *can_continue_sema;
/* this semcpahore is non_NULL when a future thread is blocked
while trying to run the future; th want_lw flag may be set in
that case */
Scheme_Object *orig_lambda; Scheme_Object *orig_lambda;
void *code; void *code;
@ -74,11 +77,34 @@ typedef struct future_t {
thread if this custodian is shut down */ thread if this custodian is shut down */
/* Runtime call stuff */ /* Runtime call stuff */
int want_lw; /* flag to indicate waiting for lw capture */
/* flag to indicate whether the future is in the "waiting for lwc" queue */ int want_lw;
/* flag to indicate waiting for lw capture; if this flag is set,
then the future thread currently running the future must be
blocked, and the runtime thread must not already be working on
behalf of the future; since a future thread is blocked on this
future, then can_continue_sema is normally set, but the runtime
thread sets can_continue_sema to NULL while trying to capture the
continuation --- in case anoter thread tries to let the original
future thread continue because it was blocked on a touch for a
future that completed; the `want_lw' flag should be changed only
while holding a lock */
int in_queue_waiting_for_lwc; int in_queue_waiting_for_lwc;
/* flag to indicate whether the future is in the "waiting for lwc"
queue; the future might be in the queue even if want_lw is set to
0, and so this flag just prevents */
int in_touch_queue; int in_touch_queue;
/* like `in_queue_waiting_for_lwc' but for being in a `touch'
future */
int rt_prim_is_atomic; int rt_prim_is_atomic;
/* when a future thread is blocked on this future, it sets
`rt_prim_is_atomic' if the blocking operation can run
in any thread atomically (i.e., it's a "synchronizing"
operation insteda of a general blocking operation) */
double time_of_request; double time_of_request;
const char *source_of_request; const char *source_of_request;
int source_type; int source_type;
@ -113,11 +139,25 @@ typedef struct future_t {
Scheme_Object **arg_S4; Scheme_Object **arg_S4;
Scheme_Thread *arg_p; Scheme_Thread *arg_p;
/* when a future thread is blocked while running this future,
`arg_p' s set along with the blocking-operation arguments to
indicate the future thread's (fake) Racket thread, which has the
runstack, etc. */
struct Scheme_Current_LWC *lwc; struct Scheme_Current_LWC *lwc;
/* when a future thread is blocked while running this future,
if `want_lw' is set, then `lwc' points to information for
capturing a lightweight continuation */
struct Scheme_Future_Thread_State *fts; struct Scheme_Future_Thread_State *fts;
/* when a future thread is blocked while running this future,
`fts' is set to identify the future thread */
struct Scheme_Lightweight_Continuation *suspended_lw; struct Scheme_Lightweight_Continuation *suspended_lw;
int maybe_suspended_lw; /* set to 1 with suspended_lw untl test in runtime thread */ /* holds a lightweight continuation captured for the operation,
if any */
int maybe_suspended_lw;
/* set to 1 with suspended_lw untl test in runtime thread; this
extra flag avoids spinning if the suspended continuation
cannot be resumed in the main thread for some reason */
Scheme_Object *retval_s; Scheme_Object *retval_s;
void *retval_p; /* use only with conservative GC */ void *retval_p; /* use only with conservative GC */

View File

@ -21,7 +21,6 @@ static int future_MARK(void *p, struct NewGC *gc) {
gcMARK2(f->arg_S1, gc); gcMARK2(f->arg_S1, gc);
gcMARK2(f->arg_s2, gc); gcMARK2(f->arg_s2, gc);
gcMARK2(f->arg_S2, gc); gcMARK2(f->arg_S2, gc);
gcMARK2(f->arg_p, gc);
gcMARK2(f->arg_S4, gc); gcMARK2(f->arg_S4, gc);
gcMARK2(f->retval_s, gc); gcMARK2(f->retval_s, gc);
gcMARK2(f->retval, gc); gcMARK2(f->retval, gc);
@ -55,7 +54,6 @@ static int future_FIXUP(void *p, struct NewGC *gc) {
gcFIXUP2(f->arg_S1, gc); gcFIXUP2(f->arg_S1, gc);
gcFIXUP2(f->arg_s2, gc); gcFIXUP2(f->arg_s2, gc);
gcFIXUP2(f->arg_S2, gc); gcFIXUP2(f->arg_S2, gc);
gcFIXUP2(f->arg_p, gc);
gcFIXUP2(f->arg_S4, gc); gcFIXUP2(f->arg_S4, gc);
gcFIXUP2(f->retval_s, gc); gcFIXUP2(f->retval_s, gc);
gcFIXUP2(f->retval, gc); gcFIXUP2(f->retval, gc);

View File

@ -2444,7 +2444,6 @@ future {
gcMARK2(f->arg_S1, gc); gcMARK2(f->arg_S1, gc);
gcMARK2(f->arg_s2, gc); gcMARK2(f->arg_s2, gc);
gcMARK2(f->arg_S2, gc); gcMARK2(f->arg_S2, gc);
gcMARK2(f->arg_p, gc);
gcMARK2(f->arg_S4, gc); gcMARK2(f->arg_S4, gc);
gcMARK2(f->retval_s, gc); gcMARK2(f->retval_s, gc);
gcMARK2(f->retval, gc); gcMARK2(f->retval, gc);