Go to the first, previous, next, last section, table of contents.
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.
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.
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 supsended, the thread
receives the interupt 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.
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 thread_self
or flavor is unrecogized 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.
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_stateCnt 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 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 thread_self
or flavor is unrecogized for this machine.
Go to the first, previous, next, last section, table of contents.