Next: Scheduling, Previous: Thread Settings, Up: Thread Interface [Contents][Index]
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 and KERN_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 and
KERN_INVALID_ARGUMENT
if target_thread is not a thread.
The function thread_abort
aborts the kernel primitives:
mach_msg
, msg_send
, msg_receive
and msg_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
returns SEND_INTERRUPTED
;
msg_receive
returns RCV_INTERRUPTED
; msg_rpc
returns either SEND_INTERRUPTED
or RCV_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 by thread_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 by thread_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 handler
thread_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 and KERN_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
is mach_thread_self
or flavor is unrecognized for this machine.
The function returns MIG_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 and
KERN_INVALID_ARGUMENT
if target_thread is not a thread or
is mach_thread_self
or flavor is unrecognized for this
machine.
Next: Scheduling, Previous: Thread Settings, Up: Thread Interface [Contents][Index]