Next: Scheduling, Previous: Thread Settings, Up: Thread Interface
Increments the thread's suspend count and prevents the thread from executing any more user level instructions. In this context a user level instruction is either a machine instruction executed in user mode or a system trap instruction including page faults. Thus if a thread is currently executing within a system trap the kernel code may continue to execute until it reaches the system return code or it may suspend within the kernel code. In either case, when the thread is resumed the system trap will return. This could cause unpredictable results if the user did a suspend and then altered the user state of the thread in order to change its direction upon a resume. The call
thread_abort
is provided to allow the user to abort any system call that is in progress in a predictable way.The suspend count may become greater than one with the effect that it will take more than one resume call to restart the thread.
The function returns
KERN_SUCCESS
if the thread has been suspended andKERN_INVALID_ARGUMENT
if target_thread is not a thread.
Decrements the thread's suspend count. If the count becomes zero the thread is resumed. If it is still positive, the thread is left suspended. The suspend count may not become negative.
The function returns
KERN_SUCCESS
if the thread has been resumed,KERN_FAILURE
if the suspend count is already zero andKERN_INVALID_ARGUMENT
if target_thread is not a thread.
The function
thread_abort
aborts the kernel primitives:mach_msg
,msg_send
,msg_receive
andmsg_rpc
and page-faults, making the call return a code indicating that it was interrupted. The call is interrupted whether or not the thread (or task containing it) is currently suspended. If it is suspended, the thread receives the interrupt when it is resumed.A thread will retry an aborted page-fault if its state is not modified before it is resumed.
msg_send
returnsSEND_INTERRUPTED
;msg_receive
returnsRCV_INTERRUPTED
;msg_rpc
returns eitherSEND_INTERRUPTED
orRCV_INTERRUPTED
, depending on which half of the RPC was interrupted.The main reason for this primitive is to allow one thread to cleanly stop another thread in a manner that will allow the future execution of the target thread to be controlled in a predictable way.
thread_suspend
keeps the target thread from executing any further instructions at the user level, including the return from a system call.thread_get_state
/thread_set_state
allows the examination or modification of the user state of a target thread. However, if a suspended thread was executing within a system call, it also has associated with it a kernel state. This kernel state can not be modified bythread_set_state
with the result that when the thread is resumed the system call may return changing the user state and possibly user memory.thread_abort
aborts the kernel call from the target thread's point of view by resetting the kernel state so that the thread will resume execution at the system call return with the return code value set to one of the interrupted codes. The system call itself will either be entirely completed or entirely aborted, depending on the precise moment at which the abort was received. Thus if the thread's user state has been changed bythread_set_state
, it will not be modified by any unexpected system call side effects.For example to simulate a Unix signal, the following sequence of calls may be used:
thread_suspend
: Stops the thread.thread_abort
: Interrupts any system call in progress, setting the return value to `interrupted'. Since the thread is stopped, it will not return to user code.thread_set_state
: Alters thread's state to simulate a procedure call to the signal handlerthread_resume
: Resumes execution at the signal handler. If the thread's stack has been correctly set up, the thread may return to the interrupted system call. (Of course, the code to push an extra stack frame and change the registers is VERY machine-dependent.)Calling
thread_abort
on a non-suspended thread is pretty risky, since it is very difficult to know exactly what system trap, if any, the thread might be executing and whether an interrupt return would cause the thread to do something useful.The function returns
KERN_SUCCESS
if the thread received an interrupt andKERN_INVALID_ARGUMENT
if target_thread is not a thread.
The function
thread_get_state
returns the execution state (e.g. the machine registers) of target_thread as specified by flavor. The old_state is an array of integers that is provided by the caller and returned filled with the specified information. old_stateCnt is input set to the maximum number of integers in old_state and returned equal to the actual number of integers in old_state.target_thread may not be
mach_thread_self()
.The definition of the state structures can be found in machine/thread_status.h.
The function returns
KERN_SUCCESS
if the state has been returned,KERN_INVALID_ARGUMENT
if target_thread is not a thread or ismach_thread_self
or flavor is unrecognized for this machine. The function returnsMIG_ARRAY_TOO_LARGE
if the returned state is too large for old_state. In this case, old_state is filled as much as possible and old_stateCnt is set to the number of elements that would have been returned if there were enough room.
The function
thread_set_state
sets the execution state (e.g. the machine registers) of target_thread as specified by flavor. The new_state is an array of integers. new_state_count is the number of elements in new_state. The entire set of registers is reset. This will do unpredictable things if target_thread is not suspended.target_thread may not be
mach_thread_self
.The definition of the state structures can be found in machine/thread_status.h.
The function returns
KERN_SUCCESS
if the state has been set andKERN_INVALID_ARGUMENT
if target_thread is not a thread or ismach_thread_self
or flavor is unrecognized for this machine.