|
The Tswitch Thread Support Library | |
|
| |
Tswitch is written in x86 assembler using the NASM assembler. The present version of tswitch runs on the standard Intel architecture under Linux. (I'm hoping to make a Windows port as time allows.)
The following interface is presented to the client:
These save and restore the CPU registers into or from a buffer area
provided by the user.
Tswitch defines the type name regbuf_t which the client uses to
declare a variable. The regsave and regrest calls then load the
CPU registers into or out of this variable.
Since regrest restores the PC value along with the other registers,
a regrest call
transfers control to the regsave which saved the value.
As such, regrest does not return, or rather, a call to regrest
returns from another call to regsave.
So regsave returns once for the original call, then zero or more times
from regrest calls. Since the program must often behave differently
in these cases, the library arranges for the return values to be
different. On the original return, regsave returns zero. When
returning from regrest, it returns the value given as the second
parameter to regrest.
Readers familiar with setjmp and longjmp from
the standard C library will recognize that regsave and regrest are
essentially the same operations.
This function switches the current stack to a new area specified
by the caller. The argument space
points to the memory area for the new stack, which is size
bytes long.
The method copies a portion of the existing stack to the new area,
then changes the stack pointer to point to the copy.
It copies nframe
stack frames, starting with the frame from which
restack is called, plus nparm additional
32-bit words. The later accounts for parameters to the top frame
copied; the function cannot tell how many there are.
This number should be at least one, to allow for the return address,
plus the number of parameters you need to preserve in the copy of the
stack.
If all goes well,
Restack returns the amount of remaining free space on the stack
after the copy, else it returns a negative value.
In the former case, the function returns
with the new stack in use.
Restack copies nframe stack frames.
Of course, the client cannot return from the top
frame when running on the copied stack, since the stack pointer will
be invalid after the return.
Restack
changes the last return address of this top frame to
point to a cleanup function, so attempts to return too far will
transfer there.
The default error function prints a
message and terminates the process.
Setcleanup specifies an alternative function, perhaps one that
calls regrest to switch to a stack has not just been hosed.
static.
Restack copies the current stack frame into the specified space, then
changes the stack pointer to reference it.
If you have pointers to variables on the old stack, the copies of
the pointers on the new stack will still point to
the variables on the original stack.
It's also worth remembering that the new stacks are of fixed size. These are fairly easy to overflow.