Information Technology Reference
In-Depth Information
size and dynamically grow it if needed.
Initializing per-thread state. When we initialize the thread control block,
we need to set the new thread's registers to some sensible initial values. In the
pseudocode, we rst the thread's stack pointer to the base of the newly allocated
stack. Then, we initialize the thread's instruction pointer and argument registers
so that when it runs it will call func(arg) .
Note that rather than having the thread call func(arg) directly, we initialize
the thread's state so that the thread will rst call the function stub() with two
arguments: func , the function to run, and arg , the arguments to that function.
The function stub() then calls func(arg) to run the function specified by the
caller. We add this extra step so that if the func() procedure returns (rather
than calling threadexit() when it is done), it has somewhere to return to. If
func() does return to stub() , stub() calls threadexit() itself to finish this
thread.
4.4.2
Deleting a thread
To delete a thread, we need to (1) remove it from the ready list so that it will
never run again and (2) free the per-thread state we allocated for it.
There is one subtlety: if a thread removes itself from the ready list and frees
its own per-thread state, then the constructs we've described will break. For
example, if a thread removes itself from the ready list but an interrupt occurs
before the thread finishes deallocating its state, we have a memory leak since
the thread will never resume to finish deallocating its state. Worse, suppose
that a thread frees its own state; what does it do then? How can it continue
running the rest of the code in sthreadexit() if it does not have a stack?
What happens if an interrupt occurs after the running thread's state has been
deallocated? If the context switch code tries to save the current thread's state
to its TCB, it will be writing to freed memory, possibly corrupting memory and
causing a subtle bug.
There is a simple fix. A thread does not delete its own state. Instead, a
thread transitions to theFinishedstate by moving its TCB from the ready list
to a list of finished threads the scheduler should never run. Then, any time the
thread library code runs (e.g., when some other thread calls yield() or when
an interrupt occurs), the thread library can call a method to free the state of
any threads on the finished list.
Thus, sthreaddelete() merely moves the current thread to the finished
list and then yields to some thread on the ready list. Later on, it is safe for
some other thread to free the state of the threads on the finished list.
 
Search WWH ::




Custom Search