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