User-Level Native Thread Primitives (GThread) Library White Paper (G06.26+)
User-Level Native Thread Primitives (GThread Library) 03/31/2005
Hewlett-Packard Company--540065-001 Page 38 of 46
Code at the resumption point of the unthreaded code would recognize that the value returned from
GTHREAD_SETJMP_ was not 0 or 1, and perform (or schedule) the thread disposition, including a
call to GTHREAD_TERMINATE_.
Suspend current thread:
Thread^Suspend(), the facility to block a thread, is a DEFINE:
DEFINE Thread^Suspend = GTHREAD_SETJMP_(CurThread,@Thread^Swapout)#;
Thread^SwapOut(CTh) puts the thread to sleep and awakens the main thread (unthreaded code):
IF (GTH_STACK_USED_(CTh) > GTH_ALLOCATED_SIZE_(CTh)) THEN
{deallocate current swap area}
newLen := GTH_STACK_USED_(CTh) + room to grow;
NewAddr := {allocate new swap area with newLen};
GTH_SET_ALLOCATION_(CTh, newAddr, newLen);
GTH_STACK_SAVE_(CTh);
{handle possible error return}
@CurThread := {null value}; -- indicate unthreaded context
GTHREAD_LONGJMP_(MainCB,1d,GTH_NULL_PROCADDR_);
Dispatch a thread:
Thread^Dispatch() is the procedure to run all ready threads; it is called from the unthreaded master
code. (The caveat for GTHREAD_SETJMP_ could apply to this procedure, because its loop might
change local state after the GTHREAD_SETJMP_ call.)
INT .EXT NextThread (ThreadImp^Struct);
IF GTHREAD_SETJMP_(MainCB,GTH_NULL_PROCADDR) = 0d THEN
IF (GTH_STACK_USED_(MainCB) > 0d) THEN
-- Presumably Swapped-Master initialization
IF GTHREAD_ORIGIN_SET_() THEN
... -- Error: unthreaded master stack is too deep
ELSE RETURN; -- from initialization call
WHILE {there's some thread ready} DO
BEGIN
@NextThread := {next thread to run};