[comp.sys.apollo] Context switch on timer interrupt..

jonasf@kuling.UUCP (Jonas "flax" Flygare) (07/03/90)

I'm working on a little project that might become an assignment 
this fall... My hopes is to write a small OS-kernel using lightweight 
processes or some mutation thereof and timer interrupts.
The first step was to get 'user controlled' context switches using 
a hacked variant of setjmp/longjmp worked just fine. (I had to make sure
no check was made as to which direction I moved on the stack + allocate
space on the stack for each process + make things Look Good before exiting 
or I would have 'Stack frame corrupted etc etc..') 
I then set up a timer to generate interrupts and a scheduler to 
be installed using signal(...) and it works fine, for one turn in the 
scheduler (each process executes once) but when I go from process N to the 
first again my program dies. I suspect there is some check on the stack
in the signalhandler, but I have no idea how to get around this problem..
(I'd prefer _not_ to have to set the stack pointer manually each time
I make a context switch just to fool the system I'm not doing anything 
Bad..)
Any help appreciated.. :-)
-- 
jonasf@kuling.docs.uu.se : "Doedth eddydthig dthrike you adth dthrayge 
Jonas (flax) Flygare     :  aboud dthidth houdth?" -- Dirk Gently

mishkin@apollo.HP.COM (Nathaniel Mishkin) (07/05/90)

In article <1579@kuling.UUCP> you write:
|> I'm working on a little project that might become an assignment 
|> this fall... My hopes is to write a small OS-kernel using lightweight 
|> processes or some mutation thereof and timer interrupts.
|> The first step was to get 'user controlled' context switches using 
|> a hacked variant of setjmp/longjmp worked just fine. (I had to make sure
|> no check was made as to which direction I moved on the stack + allocate
|> space on the stack for each process + make things Look Good before exiting 
|> or I would have 'Stack frame corrupted etc etc..') 
|> I then set up a timer to generate interrupts and a scheduler to 
|> be installed using signal(...) and it works fine, for one turn in the 
|> scheduler (each process executes once) but when I go from process N to the 
|> first again my program dies. I suspect there is some check on the stack
|> in the signalhandler, but I have no idea how to get around this problem..
|> (I'd prefer _not_ to have to set the stack pointer manually each time
|> I make a context switch just to fool the system I'm not doing anything 
|> Bad..)

You can't use setjmp/longjmp to do context switches (i.e., change stacks)
because longjmp does a "stack walk" so that cleanup handlers (established
by "pfm_$cleanup") that are "between" the current stack frame and the
stack from you're longjmp'ing to can be executed.  Another problem is
that there's logically another piece of per-thread storage (other than
what setjmp saves): a pointer to the top-most cleanup handler.  setjmp
doesn't save this value since setjmp's role in life is not to make doing
multi-threading easy; when you longjmp (or stack walk for any reason),
this value is automatically adjusted.

In my somewhat long and painful involvement with doing the kind of thing
you're trying to do on DOMAIN/OS and other more traditional Unix systems,
I've come to the conclusion that there's no way to get around writing
machine code and knowing more than you wish you had to know about the
underlying system.  E.g., various systems' longjmp's do stack walks so
they can make sure you're not trying to longjmp to a bogus place (i.e.,
to an invalid frame).

DOMAIN/OS's CPS facility (task_$) is the supported way to do lightweight
processes (LWP).  POSIX is also in the process of defining a LWP interface
called PThreads; I suspect we'll support that interface once it stablizes.

                    -- Nat Mishkin
                       Cooperative Object Computing Operation
                       Hewlett-Packard Company
                       mishkin@apollo.hp.com