VM: Refactor mach_signal to Factor style
parent
0b5a12fdea
commit
302826c7be
|
@ -12,243 +12,220 @@ Modified for Factor by Slava Pestov */
|
||||||
|
|
||||||
#include "master.hpp"
|
#include "master.hpp"
|
||||||
|
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
/* The exception port on which our thread listens. */
|
/* The exception port on which our thread listens. */
|
||||||
mach_port_t our_exception_port;
|
mach_port_t our_exception_port;
|
||||||
|
|
||||||
/* The following sources were used as a *reference* for this exception handling
|
/* The following sources were used as a *reference* for this exception handling
|
||||||
code:
|
code:
|
||||||
1. Apple's mach/xnu documentation
|
|
||||||
2. Timothy J. Wood's "Mach Exception Handlers 101" post to the
|
1. Apple's mach/xnu documentation
|
||||||
omnigroup's macosx-dev list.
|
2. Timothy J. Wood's "Mach Exception Handlers 101" post to the
|
||||||
http://www.wodeveloper.com/omniLists/macosx-dev/2000/June/msg00137.html */
|
omnigroup's macosx-dev list.
|
||||||
|
http://www.wodeveloper.com/omniLists/macosx-dev/2000/June/msg00137.html */
|
||||||
|
|
||||||
/* Modify a suspended thread's thread_state so that when the thread resumes
|
/* Modify a suspended thread's thread_state so that when the thread resumes
|
||||||
executing, the call frame of the current C primitive (if any) is rewound, and
|
executing, the call frame of the current C primitive (if any) is rewound, and
|
||||||
the appropriate Factor error is thrown from the top-most Factor frame. */
|
the appropriate Factor error is thrown from the top-most Factor frame. */
|
||||||
void factor_vm::call_fault_handler(
|
void factor_vm::call_fault_handler(exception_type_t exception,
|
||||||
exception_type_t exception,
|
exception_data_type_t code,
|
||||||
exception_data_type_t code,
|
MACH_EXC_STATE_TYPE* exc_state,
|
||||||
MACH_EXC_STATE_TYPE *exc_state,
|
MACH_THREAD_STATE_TYPE* thread_state,
|
||||||
MACH_THREAD_STATE_TYPE *thread_state,
|
MACH_FLOAT_STATE_TYPE* float_state) {
|
||||||
MACH_FLOAT_STATE_TYPE *float_state)
|
cell handler = 0;
|
||||||
{
|
|
||||||
cell handler = 0;
|
|
||||||
|
|
||||||
if(exception == EXC_BAD_ACCESS)
|
if (exception == EXC_BAD_ACCESS) {
|
||||||
{
|
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
|
||||||
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
|
signal_fault_pc = (cell) MACH_PROGRAM_COUNTER(thread_state);
|
||||||
signal_fault_pc = (cell)MACH_PROGRAM_COUNTER(thread_state);
|
verify_memory_protection_error(signal_fault_addr);
|
||||||
verify_memory_protection_error(signal_fault_addr);
|
handler = (cell) factor::memory_signal_handler_impl;
|
||||||
handler = (cell)factor::memory_signal_handler_impl;
|
} else if (exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV) {
|
||||||
}
|
signal_fpu_status = fpu_status(mach_fpu_status(float_state));
|
||||||
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
|
mach_clear_fpu_status(float_state);
|
||||||
{
|
handler = (cell) factor::fp_signal_handler_impl;
|
||||||
signal_fpu_status = fpu_status(mach_fpu_status(float_state));
|
} else {
|
||||||
mach_clear_fpu_status(float_state);
|
switch (exception) {
|
||||||
handler = (cell)factor::fp_signal_handler_impl;
|
case EXC_ARITHMETIC:
|
||||||
}
|
signal_number = SIGFPE;
|
||||||
else
|
break;
|
||||||
{
|
case EXC_BAD_INSTRUCTION:
|
||||||
switch(exception)
|
signal_number = SIGILL;
|
||||||
{
|
break;
|
||||||
case EXC_ARITHMETIC: signal_number = SIGFPE; break;
|
default:
|
||||||
case EXC_BAD_INSTRUCTION: signal_number = SIGILL; break;
|
signal_number = SIGABRT;
|
||||||
default: signal_number = SIGABRT; break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler = (cell)factor::synchronous_signal_handler_impl;
|
handler = (cell) factor::synchronous_signal_handler_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
FACTOR_ASSERT(handler != 0);
|
FACTOR_ASSERT(handler != 0);
|
||||||
|
|
||||||
dispatch_signal_handler(
|
dispatch_signal_handler((cell*)&MACH_STACK_POINTER(thread_state),
|
||||||
(cell*)&MACH_STACK_POINTER(thread_state),
|
(cell*)&MACH_PROGRAM_COUNTER(thread_state),
|
||||||
(cell*)&MACH_PROGRAM_COUNTER(thread_state),
|
(cell) handler);
|
||||||
(cell)handler
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void call_fault_handler(
|
static void call_fault_handler(mach_port_t thread, exception_type_t exception,
|
||||||
mach_port_t thread,
|
exception_data_type_t code,
|
||||||
exception_type_t exception,
|
MACH_EXC_STATE_TYPE* exc_state,
|
||||||
exception_data_type_t code,
|
MACH_THREAD_STATE_TYPE* thread_state,
|
||||||
MACH_EXC_STATE_TYPE *exc_state,
|
MACH_FLOAT_STATE_TYPE* float_state) {
|
||||||
MACH_THREAD_STATE_TYPE *thread_state,
|
/* Look up the VM instance involved */
|
||||||
MACH_FLOAT_STATE_TYPE *float_state)
|
THREADHANDLE thread_id = pthread_from_mach_thread_np(thread);
|
||||||
{
|
FACTOR_ASSERT(thread_id);
|
||||||
/* Look up the VM instance involved */
|
std::map<THREADHANDLE, factor_vm*>::const_iterator vm =
|
||||||
THREADHANDLE thread_id = pthread_from_mach_thread_np(thread);
|
thread_vms.find(thread_id);
|
||||||
FACTOR_ASSERT(thread_id);
|
|
||||||
std::map<THREADHANDLE, factor_vm*>::const_iterator vm = thread_vms.find(thread_id);
|
|
||||||
|
|
||||||
/* Handle the exception */
|
/* Handle the exception */
|
||||||
if (vm != thread_vms.end())
|
if (vm != thread_vms.end())
|
||||||
vm->second->call_fault_handler(exception,code,exc_state,thread_state,float_state);
|
vm->second->call_fault_handler(exception, code, exc_state, thread_state,
|
||||||
|
float_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle an exception by invoking the user's fault handler and/or forwarding
|
/* Handle an exception by invoking the user's fault handler and/or forwarding
|
||||||
the duty to the previously installed handlers. */
|
the duty to the previously installed handlers. */
|
||||||
extern "C"
|
extern "C" kern_return_t catch_exception_raise(
|
||||||
kern_return_t
|
mach_port_t exception_port, mach_port_t thread, mach_port_t task,
|
||||||
catch_exception_raise (mach_port_t exception_port,
|
exception_type_t exception, exception_data_t code,
|
||||||
mach_port_t thread,
|
mach_msg_type_number_t code_count) {
|
||||||
mach_port_t task,
|
/* 10.6 likes to report exceptions from child processes too. Ignore those */
|
||||||
exception_type_t exception,
|
if (task != mach_task_self())
|
||||||
exception_data_t code,
|
return KERN_FAILURE;
|
||||||
mach_msg_type_number_t code_count)
|
|
||||||
{
|
|
||||||
/* 10.6 likes to report exceptions from child processes too. Ignore those */
|
|
||||||
if(task != mach_task_self()) return KERN_FAILURE;
|
|
||||||
|
|
||||||
/* Get fault information and the faulting thread's register contents..
|
/* Get fault information and the faulting thread's register contents..
|
||||||
|
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
||||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
MACH_EXC_STATE_TYPE exc_state;
|
||||||
MACH_EXC_STATE_TYPE exc_state;
|
mach_msg_type_number_t exc_state_count = MACH_EXC_STATE_COUNT;
|
||||||
mach_msg_type_number_t exc_state_count = MACH_EXC_STATE_COUNT;
|
if (thread_get_state(thread, MACH_EXC_STATE_FLAVOR, (natural_t*)&exc_state,
|
||||||
if (thread_get_state (thread, MACH_EXC_STATE_FLAVOR,
|
&exc_state_count) !=
|
||||||
(natural_t *)&exc_state, &exc_state_count)
|
KERN_SUCCESS) {
|
||||||
!= KERN_SUCCESS)
|
/* The thread is supposed to be suspended while the exception
|
||||||
{
|
handler is called. This shouldn't fail. */
|
||||||
/* The thread is supposed to be suspended while the exception
|
return KERN_FAILURE;
|
||||||
handler is called. This shouldn't fail. */
|
}
|
||||||
return KERN_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
MACH_THREAD_STATE_TYPE thread_state;
|
MACH_THREAD_STATE_TYPE thread_state;
|
||||||
mach_msg_type_number_t thread_state_count = MACH_THREAD_STATE_COUNT;
|
mach_msg_type_number_t thread_state_count = MACH_THREAD_STATE_COUNT;
|
||||||
if (thread_get_state (thread, MACH_THREAD_STATE_FLAVOR,
|
if (thread_get_state(thread, MACH_THREAD_STATE_FLAVOR,
|
||||||
(natural_t *)&thread_state, &thread_state_count)
|
(natural_t*)&thread_state, &thread_state_count) !=
|
||||||
!= KERN_SUCCESS)
|
KERN_SUCCESS) {
|
||||||
{
|
/* The thread is supposed to be suspended while the exception
|
||||||
/* The thread is supposed to be suspended while the exception
|
handler is called. This shouldn't fail. */
|
||||||
handler is called. This shouldn't fail. */
|
return KERN_FAILURE;
|
||||||
return KERN_FAILURE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MACH_FLOAT_STATE_TYPE float_state;
|
MACH_FLOAT_STATE_TYPE float_state;
|
||||||
mach_msg_type_number_t float_state_count = MACH_FLOAT_STATE_COUNT;
|
mach_msg_type_number_t float_state_count = MACH_FLOAT_STATE_COUNT;
|
||||||
if (thread_get_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
if (thread_get_state(thread, MACH_FLOAT_STATE_FLAVOR,
|
||||||
(natural_t *)&float_state, &float_state_count)
|
(natural_t*)&float_state, &float_state_count) !=
|
||||||
!= KERN_SUCCESS)
|
KERN_SUCCESS) {
|
||||||
{
|
/* The thread is supposed to be suspended while the exception
|
||||||
/* The thread is supposed to be suspended while the exception
|
handler is called. This shouldn't fail. */
|
||||||
handler is called. This shouldn't fail. */
|
return KERN_FAILURE;
|
||||||
return KERN_FAILURE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Modify registers so to have the thread resume executing the
|
/* Modify registers so to have the thread resume executing the
|
||||||
fault handler */
|
fault handler */
|
||||||
call_fault_handler(thread,exception,code[0],&exc_state,&thread_state,&float_state);
|
call_fault_handler(thread, exception, code[0], &exc_state, &thread_state,
|
||||||
|
&float_state);
|
||||||
|
|
||||||
/* Set the faulting thread's register contents..
|
/* Set the faulting thread's register contents..
|
||||||
|
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
||||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
if (thread_set_state(thread, MACH_FLOAT_STATE_FLAVOR,
|
||||||
if (thread_set_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
(natural_t*)&float_state, float_state_count) !=
|
||||||
(natural_t *)&float_state, float_state_count)
|
KERN_SUCCESS) {
|
||||||
!= KERN_SUCCESS)
|
return KERN_FAILURE;
|
||||||
{
|
}
|
||||||
return KERN_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_set_state (thread, MACH_THREAD_STATE_FLAVOR,
|
if (thread_set_state(thread, MACH_THREAD_STATE_FLAVOR,
|
||||||
(natural_t *)&thread_state, thread_state_count)
|
(natural_t*)&thread_state, thread_state_count) !=
|
||||||
!= KERN_SUCCESS)
|
KERN_SUCCESS) {
|
||||||
{
|
return KERN_FAILURE;
|
||||||
return KERN_FAILURE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return KERN_SUCCESS;
|
return KERN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The main function of the thread listening for exceptions. */
|
/* The main function of the thread listening for exceptions. */
|
||||||
static void *
|
static void* mach_exception_thread(void* arg) {
|
||||||
mach_exception_thread (void *arg)
|
for (;;) {
|
||||||
{
|
/* These two structures contain some private kernel data. We don't need
|
||||||
for (;;)
|
to access any of it so we don't bother defining a proper struct. The
|
||||||
{
|
correct definitions are in the xnu source code. */
|
||||||
/* These two structures contain some private kernel data. We don't need
|
/* Buffer for a message to be received. */
|
||||||
to access any of it so we don't bother defining a proper struct. The
|
struct {
|
||||||
correct definitions are in the xnu source code. */
|
mach_msg_header_t head;
|
||||||
/* Buffer for a message to be received. */
|
mach_msg_body_t msgh_body;
|
||||||
struct
|
char data[1024];
|
||||||
{
|
} msg;
|
||||||
mach_msg_header_t head;
|
/* Buffer for a reply message. */
|
||||||
mach_msg_body_t msgh_body;
|
struct {
|
||||||
char data[1024];
|
mach_msg_header_t head;
|
||||||
}
|
char data[1024];
|
||||||
msg;
|
} reply;
|
||||||
/* Buffer for a reply message. */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
mach_msg_header_t head;
|
|
||||||
char data[1024];
|
|
||||||
}
|
|
||||||
reply;
|
|
||||||
|
|
||||||
mach_msg_return_t retval;
|
mach_msg_return_t retval;
|
||||||
|
|
||||||
/* Wait for a message on the exception port. */
|
/* Wait for a message on the exception port. */
|
||||||
retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0,
|
retval =
|
||||||
sizeof (msg), our_exception_port,
|
mach_msg(&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof(msg),
|
||||||
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||||
if (retval != MACH_MSG_SUCCESS)
|
if (retval != MACH_MSG_SUCCESS) {
|
||||||
{
|
abort();
|
||||||
abort ();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle the message: Call exc_server, which will call
|
/* Handle the message: Call exc_server, which will call
|
||||||
catch_exception_raise and produce a reply message. */
|
catch_exception_raise and produce a reply message. */
|
||||||
exc_server (&msg.head, &reply.head);
|
exc_server(&msg.head, &reply.head);
|
||||||
|
|
||||||
/* Send the reply. */
|
/* Send the reply. */
|
||||||
if (mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
|
if (mach_msg(&reply.head, MACH_SEND_MSG, reply.head.msgh_size, 0,
|
||||||
0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL)
|
MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL) !=
|
||||||
!= MACH_MSG_SUCCESS)
|
MACH_MSG_SUCCESS) {
|
||||||
{
|
abort();
|
||||||
abort ();
|
}
|
||||||
}
|
}
|
||||||
}
|
return NULL; // quiet warning
|
||||||
return NULL; // quiet warning
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the Mach exception handler thread. */
|
/* Initialize the Mach exception handler thread. */
|
||||||
void mach_initialize ()
|
void mach_initialize() {
|
||||||
{
|
mach_port_t self;
|
||||||
mach_port_t self;
|
exception_mask_t mask;
|
||||||
exception_mask_t mask;
|
|
||||||
|
|
||||||
self = mach_task_self ();
|
self = mach_task_self();
|
||||||
|
|
||||||
/* Allocate a port on which the thread shall listen for exceptions. */
|
/* Allocate a port on which the thread shall listen for exceptions. */
|
||||||
if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port)
|
if (mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) !=
|
||||||
!= KERN_SUCCESS)
|
KERN_SUCCESS)
|
||||||
fatal_error("mach_port_allocate() failed",0);
|
fatal_error("mach_port_allocate() failed", 0);
|
||||||
|
|
||||||
/* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */
|
/* See
|
||||||
if (mach_port_insert_right (self, our_exception_port, our_exception_port,
|
* http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html.
|
||||||
MACH_MSG_TYPE_MAKE_SEND)
|
*/
|
||||||
!= KERN_SUCCESS)
|
if (mach_port_insert_right(self, our_exception_port, our_exception_port,
|
||||||
fatal_error("mach_port_insert_right() failed",0);
|
MACH_MSG_TYPE_MAKE_SEND) !=
|
||||||
|
KERN_SUCCESS)
|
||||||
|
fatal_error("mach_port_insert_right() failed", 0);
|
||||||
|
|
||||||
/* The exceptions we want to catch. */
|
/* The exceptions we want to catch. */
|
||||||
mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC;
|
mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC;
|
||||||
|
|
||||||
/* Create the thread listening on the exception port. */
|
/* Create the thread listening on the exception port. */
|
||||||
start_thread(mach_exception_thread,NULL);
|
start_thread(mach_exception_thread, NULL);
|
||||||
|
|
||||||
/* Replace the exception port info for these exceptions with our own.
|
/* Replace the exception port info for these exceptions with our own.
|
||||||
Note that we replace the exception port for the entire task, not only
|
Note that we replace the exception port for the entire task, not only
|
||||||
for a particular thread. This has the effect that when our exception
|
for a particular thread. This has the effect that when our exception
|
||||||
port gets the message, the thread specific exception port has already
|
port gets the message, the thread specific exception port has already
|
||||||
been asked, and we don't need to bother about it.
|
been asked, and we don't need to bother about it. See
|
||||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */
|
http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */
|
||||||
if (task_set_exception_ports (self, mask, our_exception_port,
|
if (task_set_exception_ports(self, mask, our_exception_port,
|
||||||
EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
|
EXCEPTION_DEFAULT, MACHINE_THREAD_STATE) !=
|
||||||
!= KERN_SUCCESS)
|
KERN_SUCCESS)
|
||||||
fatal_error("task_set_exception_ports() failed",0);
|
fatal_error("task_set_exception_ports() failed", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,48 +36,28 @@ Modified for Factor by Slava Pestov */
|
||||||
allowing the thread to continue from the point of the exception; otherwise,
|
allowing the thread to continue from the point of the exception; otherwise,
|
||||||
no reply message is sent and the called routine must have dealt with the
|
no reply message is sent and the called routine must have dealt with the
|
||||||
exception thread directly. */
|
exception thread directly. */
|
||||||
extern "C" boolean_t exc_server (mach_msg_header_t *request_msg, mach_msg_header_t *reply_msg);
|
extern "C" boolean_t exc_server(mach_msg_header_t* request_msg,
|
||||||
|
mach_msg_header_t* reply_msg);
|
||||||
|
|
||||||
/* http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/catch_exception_raise.html
|
/* http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/catch_exception_raise.html
|
||||||
These functions are defined in this file, and called by exc_server.
|
These functions are defined in this file, and called by exc_server.
|
||||||
FIXME: What needs to be done when this code is put into a shared library? */
|
FIXME: What needs to be done when this code is put into a shared library? */
|
||||||
extern "C"
|
extern "C" kern_return_t catch_exception_raise(
|
||||||
kern_return_t
|
mach_port_t exception_port, mach_port_t thread, mach_port_t task,
|
||||||
catch_exception_raise (mach_port_t exception_port,
|
exception_type_t exception, exception_data_t code,
|
||||||
mach_port_t thread,
|
mach_msg_type_number_t code_count);
|
||||||
mach_port_t task,
|
extern "C" kern_return_t catch_exception_raise_state(
|
||||||
exception_type_t exception,
|
mach_port_t exception_port, exception_type_t exception,
|
||||||
exception_data_t code,
|
exception_data_t code, mach_msg_type_number_t code_count,
|
||||||
mach_msg_type_number_t code_count);
|
thread_state_flavor_t* flavor, thread_state_t in_state,
|
||||||
extern "C"
|
mach_msg_type_number_t in_state_count, thread_state_t out_state,
|
||||||
kern_return_t
|
mach_msg_type_number_t* out_state_count);
|
||||||
catch_exception_raise_state (mach_port_t exception_port,
|
|
||||||
exception_type_t exception,
|
|
||||||
exception_data_t code,
|
|
||||||
mach_msg_type_number_t code_count,
|
|
||||||
thread_state_flavor_t *flavor,
|
|
||||||
thread_state_t in_state,
|
|
||||||
mach_msg_type_number_t in_state_count,
|
|
||||||
thread_state_t out_state,
|
|
||||||
mach_msg_type_number_t *out_state_count);
|
|
||||||
|
|
||||||
extern "C"
|
extern "C" kern_return_t catch_exception_raise_state_identity(
|
||||||
kern_return_t
|
mach_port_t exception_port, mach_port_t thread, mach_port_t task,
|
||||||
catch_exception_raise_state_identity (mach_port_t exception_port,
|
exception_type_t exception, exception_data_t code,
|
||||||
mach_port_t thread,
|
mach_msg_type_number_t codeCnt, thread_state_flavor_t* flavor,
|
||||||
mach_port_t task,
|
thread_state_t in_state, mach_msg_type_number_t in_state_count,
|
||||||
exception_type_t exception,
|
thread_state_t out_state, mach_msg_type_number_t* out_state_count);
|
||||||
exception_data_t code,
|
|
||||||
mach_msg_type_number_t codeCnt,
|
|
||||||
thread_state_flavor_t *flavor,
|
|
||||||
thread_state_t in_state,
|
|
||||||
mach_msg_type_number_t in_state_count,
|
|
||||||
thread_state_t out_state,
|
|
||||||
mach_msg_type_number_t *out_state_count);
|
|
||||||
|
|
||||||
namespace factor
|
namespace factor { void mach_initialize(); }
|
||||||
{
|
|
||||||
|
|
||||||
void mach_initialize ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue