From 9fd4929bb04bbaa62b0c1d66869db3772d1653e4 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Wed, 23 Dec 2015 02:25:52 -0500 Subject: [PATCH] Added notes --- gc-notes.txt | 47 +++++++++++++++++++++++++++++++++++++++++++++++ gc.c | 3 +++ 2 files changed, 50 insertions(+) diff --git a/gc-notes.txt b/gc-notes.txt index 65a31003..236ae53e 100644 --- a/gc-notes.txt +++ b/gc-notes.txt @@ -14,6 +14,53 @@ TODO: part of this is implementing the beginnings of srfi-18, to create multiple threads, sync them, etc - need to cooperate when a mutator is blocked + IMPLEMENTATION NOTES: + + these become gc_cont and gc_args, so we need them for the wrapper: + GC(td,cfn,buf,1); return; + also need the result of the primitive, although that obviously is not + available until after it finishes blocking. will just have to live with that + constraint. + + requirements: + - collector detects initiates async transition + - collector will need to perform a minor GC instead of this mutator + will need to pass in top of stack then, since collector won't have that. + can use address of continuation, if we can guarantee it will always be + allocated on the stack prior to wrapper call. or can just let the wrapper + do it, and stash it somewhere collector can get to it + - collector must set flag immediately to let mutator know what happened + - mutator must know when the transition occurs, and wait for it to finish + - can use mutator lock + + will cont always be called via closcall1? + maybe we need to require prim accepts cont as an arg. might simplify + calling the wrapper. + + then instead of a wrapper, the prim can call functions to set initial state and cleanup. it already does this to set thread state, so this isn't that big of a change (just call 2 other functions): + + before_blocking { + set thread state ==> BLOCKING + set thd->gc_cont to cont, in case collector needs to use it + set stack_top to new field in "thd", again in case collector needs it + OR NOT, I think we can use stack_limit for this, to define the + range of stack addresses + } + + after_blocking { + set thread state ==> RUNNABLE + check async flag + if set: + wait for thd->lock + unset async flag + transport result to heap, if necessary (not a value type) + set gc_args[0] to result + longjmp. assumes gc_cont already set by collector + else: + call into cont with result, just like today (see Cyc_io_read_line) + } + + OLDER NOTES: might be able to stop a thread and do a minor GC on it, but no longjmp until after major GC. would need to figure out how to repack gc_cont and args optionally, some primitives can accept a cont, how to handle? I guess we would have to diff --git a/gc.c b/gc.c index 87b1c105..ac716d75 100644 --- a/gc.c +++ b/gc.c @@ -1169,6 +1169,9 @@ void gc_wait_handshake() pthread_mutex_unlock(&(m->lock)); } // TODO: else if (statusc == STATUS_ASYNC) + /* + take m->lock (also have to handle on mutator, maybe just lock/unlock after exiting prim? but then how to know if async transition happened? does the collector need to set a flag? + */ } } else if (thread_status == CYC_THREAD_STATE_TERMINATED) { // Thread is no longer running