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();
future->lwc = scheme_current_lwc;
future->fts = fts;
future->arg_p = scheme_current_thread;
/* Try to capture it locally (on this thread) */
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)
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
it can be used in a future thread. If future-thread-local
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;
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;
ft = (future_t *)storage[2];
@ -2212,9 +2212,10 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
continuation. */
return 1;
}
ft->want_lw = 0;
}
ft->want_lw = 0;
ft->fts->thread->current_ft = NULL; /* tells worker thread that it no longer
needs to handle the future */
@ -2392,7 +2393,6 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
scheme_fill_lwc_end();
future->lwc = scheme_current_lwc;
future->fts = fts;
future->arg_p = scheme_current_thread;
fid = future->id;
@ -2744,8 +2744,8 @@ static int push_marks(future_t *f, Scheme_Cont_Frame_Data *d)
{
if (f->suspended_lw) {
return scheme_push_marks_from_lightweight_continuation(f->suspended_lw, d);
} else if (f->arg_p) {
return scheme_push_marks_from_thread(f->arg_p, d);
} else if (f->fts->thread) {
return scheme_push_marks_from_thread(f->fts->thread, d);
}
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);
else
need_pop = 0;
future->arg_p = NULL;
switch (future->prim_protocol)
{

View File

@ -59,13 +59,16 @@ typedef struct future_t {
int id;
int thread_short_id;
int status;
/* The status field is the main locking mechanism. It
should only be read and written when holding a lock
(and all associated fields for a status should be
set at the same time). */
int status;
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;
void *code;
@ -74,11 +77,34 @@ typedef struct future_t {
thread if this custodian is shut down */
/* 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 in_queue_waiting_for_lwc;
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;
/* 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;
/* like `in_queue_waiting_for_lwc' but for being in a `touch'
future */
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;
const char *source_of_request;
int source_type;
@ -113,11 +139,25 @@ typedef struct future_t {
Scheme_Object **arg_S4;
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;
/* 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;
/* when a future thread is blocked while running this future,
`fts' is set to identify the future thread */
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;
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_s2, gc);
gcMARK2(f->arg_S2, gc);
gcMARK2(f->arg_p, gc);
gcMARK2(f->arg_S4, gc);
gcMARK2(f->retval_s, 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_s2, gc);
gcFIXUP2(f->arg_S2, gc);
gcFIXUP2(f->arg_p, gc);
gcFIXUP2(f->arg_S4, gc);
gcFIXUP2(f->retval_s, gc);
gcFIXUP2(f->retval, gc);

View File

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