home *** CD-ROM | disk | FTP | other *** search
- ; This source file is part of the LynxLib miscellaneous library by
- ; Robert Fischer, and is Copyright 1990 by Robert Fischer. It costs no
- ; money, and you may not make money off of it, but you may redistribute
- ; it. It comes with ABSOLUTELY NO WARRANTY. See the file LYNXLIB.DOC
- ; for more details.
- ; To contact the author:
- ; Robert Fischer \\80 Killdeer Rd \\Hamden, CT 06517 USA
- ; (203) 288-9599 fischer-robert@cs.yale.edu
-
- * Coroutine master
- * Uses C calling conventions
-
- * Process control block structure
- * typedef enum {P_NEW, P_BLOCKED, P_READY, P_RUNNING, P_DEAD} procstate;
- *
- * typedef struct {
- * proc_state state; process state
- * char *stack; current stack pointer
- * message *msg; message value
- * } pcb
-
- * PCB offsets
- stack = 0
-
- ; -------------------------------------------
- ; A PROCESS IS IDENTIFIED BY ITS STACK POINTER
- ; -------------------------------------------
-
- * invoke(f, x, p)
- * Calls f(x) in process p. Returns when p blocks or terminates.
- * func *f; Function to call
- * LONG x; argument to give it
- * pcb *p; process control block for that function
- *
-
- _init_co_s::
- * Pop parameters from master stack
- move.l 4(sp), a2 ; function f
- move.l 8(sp), d1 ; argument x
- move.l 12(sp), a1 ; pcb address p
-
- move.l stack(a1), a0
-
- * Almost call function
- move.l d1, -(a0) ; push argument x
- move.l #term, -(a0) ; Push termination address
- move.l a2, -(a0) ; Push resume() address
- lea -36(a0), a0 ; Dummy-save the registers
-
- move.l a0, stack(a1)
- rts
-
- term:
- * Switch to master stack
- move.l resume_sp, a0
- move.l (a0)+, sp
- move.l a0, resume_sp
- movem.l (sp)+, a3-a6/d3-d7
-
- * Don't need to save slave's stack pointer because slave is DEAD
-
- * Return to master for good
- move.l #0, d0 ; Put a FALSE in d0 to indicate f has terminated
- rts
-
- * ----------------------------------------------------------------------
-
- * BOOLEAN resume(p, m, ret_msg)
- * pcb *p;
- * message m;
- * message *ret_msg; Return message from slave
- * returns FALSE if p terminates, TRUE if it's still going
- *
- * Called by master.
- * Resumes process p, which should be in state P_READY.
- * Passes p.msg to the resumed process as a returned value.
-
- _resume_co::
- * Pick up argument
- move.l 4(sp), a1 ; pointer to slave's stack pointer
- move.l 8(sp), d0 ; Message for resumed process
-
- * Prepare for eventual return to master
- movem.l a3-a6/d3-d7, -(sp)
-
- * Push master's sp onto resume_stack
- move.l resume_sp, a0
- move.l sp, -(a0)
- move.l a0, resume_sp
-
- * Switch stacks to slave stack
- move.l stack(a1), sp
-
- * Return to slave from rendezvous
- ; return message in d0 (above)
- movem.l (sp)+, a3-a6/d3-d7 ; restore registers
- rts ; return
-
- * ----------------------------------------------------------------------
-
- * message to_master(to_msg)
- * message to_msg
- *
- * Called by slave function.
- * Blocks current process and passes control back to master.
- * When process is resumed, the message in the pcb is passed as
- * the value of the function.
-
- _to_master::
-
- * Save things about slave's stack
- move.l 4(sp), d1 ; slave's message
- movem.l a3-a6/d3-d7, -(sp) ; save registers
- move.l sp, d0 ; save slave's stack pointer
-
- * Switch to master's stack
- move.l resume_sp, a0
- move.l (a0)+, sp
- move.l a0, resume_sp
- movem.l (sp)+, a3-a6/d3-d7
-
- * Find stack** variable on master's stack & store slave's stack * in it
- move.l 4(sp), a0
- move.l d0, (a0) ; Save into pcb
-
- * Store away slave's message
- move.l 12(sp), a0
- move.l d1, (a0) ; Stuff slave's message into *ret_msg
-
- move.l #-1, d0 ; Put a TRUE in d0 to indicate f has not terminated
- rts
-
- * ----------------------------------------------------------------------
- .bss
-
- ; In this stack, every time resume() is called, the pcb * of the process
- ; being resumed is pushed on the stack. At tell_master, this is popped
- ; off the stack so tell_master() can tell which process is returning
- resume_stack : ds.l 100
- resume_end : ; End of resume stack
- .data
- resume_sp : dc.l resume_end ; Resume stack pointer
-