seanh@research6.computer-science.manchester.ac.uk (Sean Holdsworth) (07/03/90)
As an extension to the recent problems raised regarding implementing a thread package for sparc based machines running SunOS, I'm now trying to extend the ideas to cover preemptive (signal based) scheduling rather than just cooperative scheduling. I'm afraid its the usual story about something which was relatively easy to implement in 680x0 code being near impossible for sparc. The scheme I use is to make thread preemption signal driven. I arrange to catch this signal using a separate signal stack for the signal handler. I look in the sigcontext structure, passed to the handler as a parameter, to find things like the PC, nPC and icc of the thread when it was interrupted. These I push onto the top of the user stack for that thread, taking care to modify the saved SP to reflect this. Then, instead of returning normally from the handler, I modify the saved PC and nPC so as to `return' to an assembler written routine which completes saving the context of the interrupted thread, including flushing its register windows, and then jumps to a scheduler routine. So far so good. The problems arise when the scheduler has selected the next thread to run and it has to reestablish the context of the thread to be resumed. The scheduler has the saved stack pointer of this thread and on the thread's stack lurk the rest of its context including the PC and nPC. Now for the problem: I can restore all registers other than SP and the PC easily but I can't figure out how to complete the job. I think I've got a partial solution to the part of the problem that the nPC address may not directly follow the PC address by using a delayed control transfer couple; doing the equivalent of jump PC jump nPC causes the instruction at address PC to be executed and execution to continue as normal from address nPC. The 'slight' problem here is that when it comes to executing this sequence all the other registers must have been restored but the jump instruction requires the address to be in a register... Its interesting to see how SunOS has got round this same problem. The code which restores the context after an interrupt handler has run, and which is entered when the handler function returns, seems to restore all registers other than g1, o0 and the sp and then makes a call to system call number 139. The effect of making this call seems to be to complete the restoration of context and to put the user back to where it was at the point of the signal. If you look in /usr/include/syscall.h this is marked as `unused' but seems to be put to good use in this context ;-) Any hints, tips or suggestions of why I'm doing it all wrong and should be doing it using method X very much appreciated. Please reply by email and if I get a sensible story out of this I will summarize. Sean Holdsworth. Janet: seanh@uk.ac.man.cs Tel: +44-61-275-6294 UUCP: ...!uunet!mcsun!ukc!man.cs!seanh Fax: +44-61-275-6280 Inet: seanh%cs.man.ac.uk@nsfnet-relay.ac.uk Int: 6294
"Mark_Weiser.PARC"@xerox.com (07/13/90)
The PCR (Portable Common Runtime) package for sparcs provides full pre-emptive threads for sparcs, including a solution to the blocked on page-fault problem. Source by anonymous ftp from arisia.xerox.com, directory pub, file pcr.tar.Z. You can look and see how we did it in there. This package is in use by hundreds of people running heavily multi-threaded systems of over a million lines of code, so I think it works.