#ifndef MULTIPROCESSING_H
#define MULTIPROCESSING_H

#ifndef MACTYPES_H
#include <CarbonCore/MacTypes.h>
#endif



#include <HYS/CarbonCore/Multiprocessing.h>
#include <AvailabilityMacros.h>

#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*Timer Option Masks

Indicate optional actions when calling MPArmTimer. 

enum {
   kMPPreserveTimerIDMask = 1L << 0,
   kMPTimeIsDeltaMask = 1L << 1,
   kMPTimeIsDurationMask = 1L << 2
};
Constants
kMPPreserveTimerIDMask

Available in Mac OS X v10.0 and later.
kMPTimeIsDeltaMask

Specifying this mask indicates that the specified time should be added to the previous expiration time to form the new expiration time. You can use this mask to compensate for timing drift caused by the finite amount of time required to arm the timer, receive the notification, and so on. 

Available in Mac OS X v10.0 and later.
kMPTimeIsDurationMask

Specifying this mask indicates that the specified expiration time is of type Duration. You can use this mask to avoid having to call time conversion routines when specifying an expiration time. 

Available in Mac OS X v10.0 and later.
Discussion
Version Notes

Introduced with Multiprocessing Services 2.0.*/
enum {
   kMPPreserveTimerIDMask = 1L << 0,
   kMPTimeIsDeltaMask = 1L << 1,
   kMPTimeIsDurationMask = 1L << 2
};


/*MPTaskID

Represents a task ID. 

typedef struct OpaqueMPTaskID * MPTaskID;
Discussion

You obtain a task ID by calling the function MPCreateTask. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPTaskID * MPTaskID;

/*Task Creation Options

Specify optional actions when calling the MPCreateTask function.

enum {
   kMPCreateTaskTakesAllExceptionsMask = 2,
   kMPCreateTaskNotDebuggableMask = 4,
   kMPCreateTaskValidOptionsMask = 6
};
typedef OptionBits MPTaskOptions;
Constants
Discussion
Version Notes

Introduced with Multiprocessing Services 2.1.*/
enum {
   kMPCreateTaskTakesAllExceptionsMask = 2,
   kMPCreateTaskNotDebuggableMask = 4,
   kMPCreateTaskValidOptionsMask = 6
};
typedef OptionBits MPTaskOptions;

/*MPQueueID

Represents a queue ID, which Multiprocessing Services uses to manipulate message queues.

typedef struct OpaqueMPQueueID * MPQueueID;
Discussion

You obtain a queue ID by calling the function MPCreateQueue. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPQueueID * MPQueueID;



/*Timer Duration Constants

Specify the maximum time a task should wait for an event to occur. 

enum {
   kDurationImmediate = 0,
   kDurationForever = 0x7FFFFFFF,
   kDurationMillisecond = 1,
   kDurationMicrosecond = -1
};
Constants
kDurationImmediate

The task times out immediately, whether or not the event has occurred. If the event occurred, the return status is noErr. If the event did not occur, the return status is kMPTimeoutErr (assuming no other errors occurred). 

Available in Mac OS X v10.0 and later.
kDurationForever

The task waits forever. The blocking call waits until either the event occurs, or until the object being waited upon (such as a message queue) is deleted.

Available in Mac OS X v10.0 and later.
kDurationMillisecond

The task waits one millisecond before timing out. 

Available in Mac OS X v10.0 and later.
kDurationMicrosecond

The task waits one microsecond before timing out. 

Available in Mac OS X v10.0 and later.
Discussion

You can use these constants in conjunction with other values to indicate specific wait intervals. For example, to wait 1 second, you can pass kDurationMillisecond * 1000. 
Version Notes

Introduced with Multiprocessing Services 2.0.*/
enum {
   kDurationImmediate = 0,
   kDurationForever = 0x7FFFFFFF,
   kDurationMillisecond = 1,
   kDurationMicrosecond = -1
};

/*MPSemaphoreID

Represents a semaphore ID, which Multiprocessing Services uses to manipulate semaphores.

typedef struct OpaqueMPSemaphoreID * MPSemaphoreID;
Discussion

You obtain a semaphore ID by calling the function MPCreateSemaphore. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPSemaphoreID * MPSemaphoreID;

/*MPSemaphoreCount

Represents a semaphore count. 

typedef ItemCount MPSemaphoreCount;
Discussion
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef ItemCount MPSemaphoreCount;

/*MPProcessID

Represents a process ID. 

typedef struct OpaqueMPProcessID * MPProcessID;
Discussion

Note that this process ID is identical to the process ID (or context ID) handled by the Code Fragment Manager. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPProcessID * MPProcessID;

/*Memory Allocation Alignment Constants

Specify the alignment of the desired memory block when calling the MPAllocateAligned function.

enum {
   kMPAllocateDefaultAligned = 0,
   kMPAllocate8ByteAligned = 3,
   kMPAllocate16ByteAligned = 4,
   kMPAllocate32ByteAligned = 5,
   kMPAllocate1024ByteAligned = 10,
   kMPAllocate4096ByteAligned = 12,
   kMPAllocateMaxAlignment = 16,
   kMPAllocateAltiVecAligned = kMPAllocate16ByteAligned,
   kMPAllocateVMXAligned = kMPAllocateAltiVecAligned,
   kMPAllocateVMPageAligned = 254,
   kMPAllocateInterlockAligned = 255
};
Constants
kMPAllocateDefaultAligned

Use the default alignment.

Available in Mac OS X v10.0 and later.
kMPAllocate8ByteAligned

Use 8-byte alignment.

Available in Mac OS X v10.0 and later.
kMPAllocate16ByteAligned

Use 16-byte alignment.

Available in Mac OS X v10.0 and later.
kMPAllocate32ByteAligned

Use 32-byte alignment. 

Available in Mac OS X v10.0 and later.
kMPAllocate1024ByteAligned

Use 1024-byte alignment.

Available in Mac OS X v10.0 and later.
kMPAllocate4096ByteAligned

Use 4096-byte alignment.

Available in Mac OS X v10.0 and later.
kMPAllocateMaxAlignment

Use the maximum alignment (65536 byte).

Available in Mac OS X v10.0 and later.
kMPAllocateAltiVecAligned

Use AltiVec alignment.

Available in Mac OS X v10.0 and later.
kMPAllocateVMXAligned

Use VMX (now called AltiVec) alignment.

Available in Mac OS X v10.0 and later.
kMPAllocateVMPageAligned

Use virtual memory page alignment. This alignment is set at runtime. 

Available in Mac OS X v10.0 and later.
kMPAllocateInterlockAligned

Use interlock alignment, which is the alignment needed to allow the use of CPU interlock instructions (that is, lwarx and stwcx.) on the returned memory address. This alignment is set at runtime. In most cases you would never need to use this alignment. 

Available in Mac OS X v10.0 and later.
Discussion
Version Notes

Introduced with Multiprocessing Services 2.0.*/
enum {
   kMPAllocateDefaultAligned = 0,
   kMPAllocate8ByteAligned = 3,
   kMPAllocate16ByteAligned = 4,
   kMPAllocate32ByteAligned = 5,
   kMPAllocate1024ByteAligned = 10,
   kMPAllocate4096ByteAligned = 12,
   kMPAllocateMaxAlignment = 16,
   kMPAllocateAltiVecAligned = kMPAllocate16ByteAligned,
   kMPAllocateVMXAligned = kMPAllocateAltiVecAligned,
   kMPAllocateVMPageAligned = 254,
   kMPAllocateInterlockAligned = 255
};

/*MPTimerID

Represents a timer ID. 

typedef struct OpaqueMPTimerID * MPTimerID;
Discussion

You obtain a timer ID by calling the function MPCreateTimer. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPTimerID * MPTimerID;

/*MPOpaqueID

Represents a generic notification ID (that is, an ID that could be a queue ID, event ID, kernel notification ID, or semaphore ID). 

typedef struct OpaqueMPOpaqueID * MPOpaqueID;
Discussion
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueMPOpaqueID * MPOpaqueID;


//function
/*MPCreateSemaphore

Creates a semaphore.

OSStatus MPCreateSemaphore (
   MPSemaphoreCount maximumValue,
   MPSemaphoreCount initialValue,
   MPSemaphoreID * semaphore
);
Parameters
maximumValue

The maximum allowed value of the semaphore. 
initialValue

The initial value of the semaphore.
semaphore

On return, semaphore contains the ID of the newly–created semaphore. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

If you want to create a binary semaphore, you can call the macro MPCreateBinarySemaphore (MPSemaphoreID *semaphore) instead, which simply calls MPCreateSemaphore with both maximumValue and initialValue set to 1.

Also see the function MPDeleteSemaphore. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPCreateSemaphore (
   MPSemaphoreCount maximumValue,
   MPSemaphoreCount initialValue,
   MPSemaphoreID * semaphore
);

/*MPSignalSemaphore

Signals a semaphore. 

OSStatus MPSignalSemaphore (
   MPSemaphoreID semaphore
);
Parameters
semaphore

The ID of the semaphore you want to signal. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If the value of the semaphore was already at the maximum, MPSignalSemaphore returns kInsufficientResourcesErr.
Discussion

If tasks are waiting on the semaphore, the oldest (first queued) task is unblocked so that the corresponding MPWaitOnSemaphore call for that task completes. Otherwise, if the value of the semaphore is not already equal to its maximum value, it is incremented by one.

Note that you can call this function from an interrupt handler. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPSignalSemaphore (
   MPSemaphoreID semaphore
);

/*MPWaitOnSemaphore

Waits on a semaphore

OSStatus MPWaitOnSemaphore (
   MPSemaphoreID semaphore,
   Duration timeout
);
Parameters
semaphore

The ID of the semaphore you want to wait on. 
timeout

The maximum time the function should wait before timing out. See Timer Duration Constants for a list of constants you can use to specify the wait interval. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

If the value of the semaphore is greater than zero, the value is decremented and the function returns with noErr. Otherwise, the task is blocked awaiting a signal until the specified timeout is exceeded.

If you call this function from a cooperative task, you should specify only kDurationImmediate for the timeout length; other waits will cause the task to block. 

Also see the function MPSignalSemaphore. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPWaitOnSemaphore (
   MPSemaphoreID semaphore,
   Duration timeout
);

/*MPDeleteSemaphore

Removes a semaphore. 

OSStatus MPDeleteSemaphore (
   MPSemaphoreID semaphore
);
Parameters
semaphore

The ID of the semaphore you want to remove. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

Calling this function unblocks all tasks waiting on the semaphore and the tasks’ respective MPWaitOnSemaphore calls will return with the result code kMPDeletedErr.

Also see the function MPCreateSemaphore. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

OSStatus MPDeleteSemaphore (
   MPSemaphoreID semaphore
);

/*_MPIsFullyInitialized

Indicates whether Multiprocessing Services is available for use.

Boolean _MPIsFullyInitialized ();
Parameters
Return Value
Discussion

Checking for the availability of the MP API is rather ugly. This is a historical problem, caused by the original implementation letting itself get prepared when it really wasn't usable and complicated by some important clients then depending on weak linking to "work". (And further complicated by CFM not supporting "deferred" imports, which is how many programmers think weak imports work.)

The end result is that the MP API library may get prepared by CFM but be totally unusable. This means that if you import from the MP API library, you cannot simply check for a resolved import to decide if MP services are available. Worse, if you explicitly prepare the MP API library you cannot assume that a noErr result from GetSharedLibrary means that MP services are available.
If you import from the MP API library you must do the following:

Use the MPLibraryIsLoaded macro (or equivalent code in languages other than C) to tell if the MP API services are available. It is not sufficient to simply check that an imported symbol is resolved as is commonly done for other libraries. The macro expands to the expression: ( ( (UInt32)_MPIsFullyInitialized != (UInt32)kUnresolvedCFragSymbolAddress  )  &&
              ( _MPIsFullyInitialized () ) )

This code checks if the imported symbol _MPIsFullyInitialized is resolved and, if resolved, calls it. Both parts must succeed for the MP API services to be available.
If you explicitly prepare the MP API library you must use code similar to the following example to tell if the MP API services are available. It is not sufficient to depend on just a noErr result from GetSharedLibrary. OSErr err;
Boolean mpIsAvailable = false;
CFragConnectionID connID = kInvalidID;
MPIsFullyInitializedProc    mpIsFullyInitialized    = NULL;
 
err = GetSharedLibrary  ( "\pMPLibrary", kCompiledCFragArch,                             kReferenceCFrag, &connID, NULL,  NULL );
 
if ( err == noErr ) {
err = FindSymbol ( connID, "\p_MPIsFullyInitialized",
                    (Ptr *) &mpIsFullyInitialized, NULL );
}
 
if ( err == noErr ) {mpIsAvailable = (* mpIsFullyInitialized) ();
    }

Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

//extern Boolean 
//_MPIsFullyInitialized(void)                                   //AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER;


Boolean _MPIsFullyInitialized ();

#define MPLibraryIsLoaded()     \
            ( ( (UInt32)_MPIsFullyInitialized != (UInt32)kMPUnresolvedCFragSymbolAddress ) &&   \
              ( _MPIsFullyInitialized () ) )

/*MPCreateTask

Creates a preemptive task.

Modified

OSStatus MPCreateTask (
   TaskProc entryPoint,
   void * parameter,
   ByteCount stackSize,
   MPQueueID notifyQueue,
   void * terminationParameter1,
   void * terminationParameter2,
   MPTaskOptions options,
   MPTaskID * task
);
Parameters
entryPoint

A pointer to the task function. The task function should take a single 32-bit parameter and return a value of type OSStatus. 
parameter

The parameter to pass to the task function. 
stackSize

The size of the stack assigned to the task. Note that you should be careful not to exceed the bounds of the stack, since stack overflows may not be detected. Specifying zero for the size will result in a default stack size of 4KB. 

Note that in Mac OS X prior to version 10.1, this parameter is ignored, and all stacks have the default size of 512 KB. Versions 10.1 and later do not have this limitation.

notifyQueue

The ID of the message queue to which the system will send a message when the task terminates. You specify the first 64-bits of the message in the parameters terminationParameter1 and terminationParameter2 respectively. The last 32-bits contain the result code of the task function. 
terminationParameter1

A 32-bit value that is sent to the message queue specified by the parameter notifyQueue when the task terminates.
terminationParameter2

A 32-bit value that is sent to the message queue specified by the parameter notifyQueue when the task terminates.
options

Optional attributes of the preemptive task. See Task Creation Options for a list of possible values. 
task

On return, task points to the ID of the newly created task. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If MPCreateTask could not create the task because some critical resource was not available, the function returns kMPInsufficientResourcesErr. Usually this is due to lack of memory to allocate the internal data structures associated with the task or the stack. The function also returns kMPInsufficientResourcesErr if any reserved option bits are set.
Discussion

Tasks are created in the unblocked state, ready for execution. A task can terminate in the following ways:
By returning from its entry point 
By calling MPExit
When specified as the target of an MPTerminateTask call 
If a hardware-detected exception or programming exception occurs and no exception handler is installed 
If the application calls ExitToShell 

Task resources (its stack, active timers, internal structures related to the task, and so on) are reclaimed by the system when the task terminates. The task's address space is inherited from the process address space. All existing tasks are terminated when the owning process terminates.

To set the relative processor weight to be assigned to a task, use the function MPSetTaskWeight.

See also the function MPTerminateTask. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Modified in Carbon. Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Carbon Porting Notes

In Mac OS X prior to version 10.1, the stackSize parameter is ignored, and all stacks have the default size of 512 KB. Versions 10.1 and later do not have this limitation. 
Declared In
Multiprocessing.h*/
OSStatus MPCreateTask (
   TaskProc entryPoint,
   void * parameter,
   ByteCount stackSize,
   MPQueueID notifyQueue,
   void * terminationParameter1,
   void * terminationParameter2,
   MPTaskOptions options,
   MPTaskID * task
);

/*MPTerminateTask

Terminates an existing task.

OSStatus MPTerminateTask (
   MPTaskID task,
   OSStatus terminationStatus
);
Parameters
task

The ID of the task you wish to terminate. 
terminationStatus

A 32-bit value of type OSStatus indicating termination status. This value is sent to the termination status message queue you specified in MPCreateTask in place of the task function’s result code. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If the task to be terminated is already in the process of termination, MPTerminateTask returns kMPInsufficientResourcesErr. You do not need to take any additional action if this occurs.
Discussion

You should be very careful when calling MPTerminateTask. As defined, this call will asynchronously and abruptly terminate a task, potentially leaving whatever structures or resources it was operating upon in an indeterminate state. Mac OS X exacerbates this problem, as MP tasks can use many more system services that are not expecting client threads to asynchronously terminate, and these services do not take the rather complicated steps necessary to protect against, or recover from, such a situation.

However, there are situations in which calling MPTerminateTask is useful and relatively safe. One such situation is when your application or service is quitting and you know that the task you wish to terminate is waiting on an MP synchonization construct (queue, event, semaphore or critical region). While you could do this more cleanly by waking the task and causing it to exit on its own, doing so may not always be practical.

For example, suppose you have several service tasks performing background processing for your application. These service tasks wait on a queue, onto which the applicaton places requests for processing. When the task is done with a request, it notifies another queue, which the application polls. Since the main application task is placing items on the shared queue, and receiving notifications when the requests are done, it can track whether or not there are outstanding requests being processed. If all outstanding requests have, in fact, been processed, it is relatively safe to terminate a task (or all tasks) waiting on the request queue.

You should not assume that the task has completed termination when this call returns; the proper way to synchronize with task termination is to wait on the termination queue (specified in MPCreateTask ) until a message appears. Because task termination is a multistage activity, it is possible for a preemptive task to attempt to terminate a task that is already undergoing termination. In such cases, MPTerminateTask returns kMPInsufficientResourcesErr.

Note that Multiprocessing Services resources (event groups, queues, semaphores, and critical regions) owned by a preemptive task are not released when that task terminates. If a task has a critical region locked when it terminates, the critical region remains in the locked state. Multiprocessing Services resources no longer needed should be explicitly deleted by the task that handles the termination message. All Multiprocessing Services resources created by tasks are released when their owning process (that is, the host application) terminates. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPTerminateTask (
   MPTaskID task,
   OSStatus terminationStatus
);


/*MPTaskIsPreemptive

Determines whether a task is preemptively scheduled. 

Boolean MPTaskIsPreemptive (
   MPTaskID taskID
);
Parameters
taskID

The task you want to check. Pass kMPNoID or kInvalidID if you want to specify the current task. 
Return Value

If true, the task is preemptively scheduled. If false, the task is cooperatively scheduled. 
Discussion

If you have code that may be called from either cooperative or preemptive tasks, that code can call MPTaskIsPreemptive if its actions should differ depending on its execution environment. 

Note that you can call this function from an interrupt handler. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

Boolean MPTaskIsPreemptive (
   MPTaskID taskID
);

/*MPCurrentTaskID

Obtains the task ID of the currently-executing preemptive task

MPTaskID MPCurrentTaskID ();
Parameters
Return Value

The task ID of the current preemptive task. See the description of the MPTaskID data type.
Discussion

Returns the ID of the current preemptive task. If called from a cooperative task, this function returns an ID which is different than the ID of any preemptive task. Nonpreemptive processes may or may not have different task IDs for each application; future implementations of this API may behave differently in this regard.

Note that you can call this function from an interrupt handler. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
MPTaskID MPCurrentTaskID ();

/*MPDelayUntil

Blocks the calling task until a specified time. 

OSStatus MPDelayUntil (
   AbsoluteTime * expirationTime
);
Parameters
expirationTime

The time to unblock the task. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

You cannot call this function from a cooperative task. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPDelayUntil (
   AbsoluteTime * expirationTime
);

/*_MPLibraryVersion

Determines the Multiprocessin g Services library version.

void _MPLibraryVersion (
   char ** versionCString,
   UInt32 * major,
   UInt32 * minor,
   UInt32 * release,
   UInt32 * revision
);
Parameters
versionCString
major
minor
release
revision
Return Value
Discussion
Version Notes
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
void _MPLibraryVersion (
   char ** versionCString,
   UInt32 * major,
   UInt32 * minor,
   UInt32 * release,
   UInt32 * revision
);


/*MPDeleteQueue

Deletes a message queue.

OSStatus MPDeleteQueue (
   MPQueueID queue
);
Parameters
queue

The ID of the message queue you want to delete. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

After calling MPDeleteQueue, the specified queue ID becomes invalid, and all internal resources associated with the queue (including queued messages) are reclaimed. Any tasks waiting on the queue are unblocked and their respective MPWaitOnQueue calls will return with the result code kMPDeletedErr.

Also see the function MPCreateQueue. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPDeleteQueue (
   MPQueueID queue
);

/*MPWaitOnQueue

Obtains a message from a specified message queue. 

OSStatus MPWaitOnQueue (
   MPQueueID queue,
   void ** param1,
   void ** param2,
   void ** param3,
   Duration timeout
);
Parameters
queue

The ID of the message queue from which to receive the notification. 
param1

A pointer to a 32-bit variable. On return, this variable contains the first 32-bits of the notification message. Pass NULL if you do not need this portion of the message. 
param2

A pointer to a 32-bit variable. On return, the variable contains the second 32-bits of the notification message. Pass NULL if you do not need this portion of the message.
param3

A pointer to a 32-bit variable. On return, the variable contains the third 32-bits of the notification message. Pass NULL if you do not need this portion of the message.
timeout

The time to wait for a notification before timing out. See Timer Duration Constants for a list of constants you can use to specify the wait interval. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

This function receives a message from the specified message queue. If no messages are currently available, the timeout specifies how long the function should wait for one. Tasks waiting on the queue are handled in a first in, first out manner; that is, the first task to wait on the queue receives the message from the MPNotifyQueue call. 

After calling this function, when a message appears, it is removed from the queue and the three fields, param1, param2, and param3 are set to the values specified by the message text. Note these parameters are pointers to variables to be set with the message text.

If you call this function from a cooperative task, you should specify only kDurationImmediate for the timeout length; other waits will cause the task to block. 

Also see the function MPNotifyQueue. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPWaitOnQueue (
   MPQueueID queue,
   void ** param1,
   void ** param2,
   void ** param3,
   Duration timeout
);

/*MPCreateQueue

Creates a message queue.

OSStatus MPCreateQueue (
   MPQueueID * queue
);
Parameters
queue

On return, the variable contains the ID of the newly created message queue. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If a queue could not be created, MPCreateQueue returns kMPInsufficientResourcesErr.
Discussion

This call creates a message queue, which can be used to notify (that is, send) and wait for (that is, receive) messages consisting of three 32-bit words in a preemptively safe manner.

Message queues are created from dynamically allocated internal resources. Other tasks may be competing for these resources so it is possible this function may not be able to create a queue. 

See also the functions MPDeleteQueue and MPSetQueueReserve. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPCreateQueue (
   MPQueueID * queue
);

/*MPAllocateAligned

Allocates a nonrelocatable memory block.

Modified

LogicalAddress MPAllocateAligned (
   ByteCount size,
   UInt8 alignment,
   OptionBits options
);
Parameters
size

The size, in bytes, of the memory block to allocate. 
alignment

The desired alignment of the allocated memory block. See Memory Allocation Alignment Constants for a list of possible values to pass. Note that there will be a minimum alignment regardless of the requested alignment. If the requested memory block is 4 bytes or smaller, the block will be at least 4-byte aligned. If the requested block is greater than 4 bytes, the block will be at least 8-byte aligned. 
options

Any optional information to use with this call. See Memory Allocation Option Constants for a list of possible values to pass. 
Return Value

A pointer to the allocated memory. If the function cannot allocate the requested memory or the requested alignment, the returned address is NULL. 
Discussion

The memory referenced by the returned address is guaranteed to be accessible by the application's cooperative task and any preemptive tasks that it creates, but not by other applications or their preemptive tasks. Any existing nonglobal heap blocks are freed when the application terminates. As with all shared memory, you must explicitly synchronize access to allocated heap blocks using a notification mechanism.

You can replicate the effect of the older MPAllocate function by calling MPAllocateAligned with 32-byte alignment and no options. 

Also see the function MPFree. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Modified in Carbon. Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Carbon Porting Notes

Mac OS X does not support allocation of global (cross address space) or resident memory with this function. In addition, passing the kMPAllocateNoGrowthMask constant in the options parameter has no effect under Mac OS X, since memory allocation is done with sparse heaps.
Declared In
Multiprocessing.h*/

LogicalAddress MPAllocateAligned (
   ByteCount size,
   UInt8 alignment,
   OptionBits options
);

/*MPFree

Frees memory allocated by MPAllocateAligned. 

void MPFree (
   LogicalAddress object
);
Parameters
object

A pointer to the memory you want to release. 
Return Value
Discussion

Also see the function MPAllocateAligned. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

void MPFree (
   LogicalAddress object
);

/*MPGetAllocatedBlockSize

Returns the size of a memory block.

ByteCount MPGetAllocatedBlockSize (
   LogicalAddress object
);
Parameters
object

The address of the memory block whose size you want to determine. 
Return Value

The size of the allocated memory block, in bytes. 
Discussion
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

ByteCount MPGetAllocatedBlockSize (
   LogicalAddress object
);

/*MPCreateTimer

Creates a timer.

OSStatus MPCreateTimer (
   MPTimerID * timerID
);
Parameters
timerID

On return, the timerID contains the ID of the newly created timer. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

You can use a timer to notify an event, queue, or semaphore after a specified amount of time has elapsed. 

Timer objects are created from dynamically-allocated internal resources. Other tasks may be competing for these resources so it is possible this function may not be able to create one.

To specify the notification mechanism to signal, use the function MPSetTimerNotify.

Also see the functions MPDeleteTimer and MPArmTimer. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPCreateTimer (
   MPTimerID * timerID
);

/*MPSetTimerNotify

Sets the notification information associated with a timer. 

OSStatus MPSetTimerNotify (
   MPTimerID timerID,
   MPOpaqueID anID,
   void * notifyParam1,
   void * notifyParam2,
   void * notifyParam3
);
Parameters
timerID

The ID of the timer whose notification information you want to set. 
notificationID

The ID of the notification mechanism to associate with the timer. This value should be the ID of an event group, a message queue, or a semaphore. 
notifyParam1

If anID specifies an event group, this parameter should contain the flags to set in the event group when the timer expires. If anID specifies a message queue, this parameter should contain the first 32-bits of the message to be sent to the message queue when the timer expires. 
notifyParam2

If anID specifies a message queue, this parameter should contain the second 32-bits of the message to be sent to the message queue when the timer expires. Pass NULL if you don’t need this parameter.
notifyParam3

If anID specifies a message queue, this parameter should contain the third 32-bits of the message sent to the message queue when the timer expires. Pass NULL if you don’t need this parameter.
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

When the timer expires, Multiprocessing Services checks the notification ID, and if it is valid, notifies the related notification mechanisms (that is, event groups, queues, or semaphores) you had specified in your MPSetTimerNotify calls. 

You can specify multiple notification mechanisms by calling this function several times. For example, you can call MPSetTimerNotify to specify a message queue and then call it again to specify a semaphore. When the timer expires, a message is sent to the message queue and the appropriate semaphore is signaled. You cannot, however, specify more than one notification per notification mechanism (for example, if you call MPSetTimerNotify twice, specifying different messages or message queues in each call, the second call will overwrite the first). Note that if a call to MPSetTimerNotify returns an error, any previous calls specifying the same timer are still valid; previously set notifications will still be notified when the timer expires. 

You can set the notification information at any time. If the timer is armed, it will modify the notification parameters dynamically. If the timer is disarmed, it will modify the notification parameters to be used for the next MPArmTimer call. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

OSStatus MPSetTimerNotify (
   MPTimerID timerID,
   MPOpaqueID anID,
   void * notifyParam1,
   void * notifyParam2,
   void * notifyParam3
);

/*MPArmTimer

Arms the timer to expire at a given time. 

OSStatus MPArmTimer (
   MPTimerID timerID,
   AbsoluteTime * expirationTime,
   OptionBits options
);
Parameters
timerID

The ID of the timer you want to arm. 
expirationTime

A pointer to a value that specifies when you want the timer to expire. Note that if you arm the timer with a time that has already passed, the timer expires immediately. 
options

Any optional actions. See Timer Option Masks for a list of possible values. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If the timer has already expired, the reset does not take place and the function returns kMPInsufficientResourcesErr.
Discussion

The expiration time is an absolute time, which you can generate by calling the Driver Services Library function UpTime. When the timer expires, a notification is sent to the notification mechanism specified in the last MPSetTimerNotify call. If the specified notification ID has become invalid, no action is taken when the timer expires. The timer itself is deleted when it expires unless you specified the kMPPreserveTimerID option in the options parameter.

Also see the function MPCancelTimer. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPArmTimer (
   MPTimerID timerID,
   AbsoluteTime * expirationTime,
   OptionBits options
);

/*MPCancelTimer

Cancels an armed timer. 

OSStatus MPCancelTimer (
   MPTimerID timerID,
   AbsoluteTime * timeRemaining
);
Parameters
timerID

The ID of the armed timer you want to cancel. 
timeRemaining

On return, the timeRemaining contains the time remaining before the timer would have expired. 
Return Value

A result code. See "Multiprocessing Services Result Codes". If the timer has already expired, this function returns kMPInsufficientResourcesErr.
Discussion

Also see the function MPArmTimer. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

OSStatus MPCancelTimer (
   MPTimerID timerID,
   AbsoluteTime * timeRemaining
);

/*MPDeleteTimer

Removes a timer. 

OSStatus MPDeleteTimer (
   MPTimerID timerID
);
Parameters
timerID

The ID of the timer you want to remove. 
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

After deletion, the timer ID becomes invalid, and all internal resources associated with the timer are reclaimed.

Also see the function MPCreateTimer. 
Version Notes

Introduced with Multiprocessing Services 2.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 2.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/
OSStatus MPDeleteTimer (
   MPTimerID timerID
);

/*MPNotifyQueue

Sends a message to the specified message queue.

OSStatus MPNotifyQueue (
   MPQueueID queue,
   void * param1,
   void * param2,
   void * param3
);
Parameters
queue

The queue ID of the message queue you want to notify. 
param1

The first 32-bits of the message to send. 
param2

The second 32-bits of the message to send.
param3

The third 32-bits of the message to send.
Return Value

A result code. See "Multiprocessing Services Result Codes".
Discussion

This function sends a message to the specified queue, which consist of the three parameters, param1, param2, and param3. The system does not interpret the three 32-bit words which comprise the text of the message. If tasks are waiting on the specified queue, the first waiting task is unblocked and the task’s MPWaitOnQueue function completes.

Depending on the queue mode, the system either allocates messages dynamically or assigns them to memory reserved for the queue. In either case, if no more memory is available for messages MPNotifyQueue returns kMPInsufficientResourcesErr.

You can call this function from an interrupt handler if messages are reserved on the queue. For more information about queueing modes and reserving messages, see MPSetQueueReserve.

Also see the function MPWaitOnQueue. 
Version Notes

Introduced with Multiprocessing Services 1.0. 
Availability
Available in CarbonLib 1.0 and later when MultiprocessingLib 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
Multiprocessing.h*/

OSStatus MPNotifyQueue (
   MPQueueID queue,
   void * param1,
   void * param2,
   void * param3
);


#ifdef __cplusplus
}
#endif

#endif