#ifndef  THREADS_H
#define THREADS_H

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

#ifndef MIXEDMODE_H
#include <CarbonCore/MixedMode.h>
#endif

#ifndef MACERRORS_H
#include <CarbonCore/MacErrors.h>
#endif


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

#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*Thread Option Constants


typedef UInt32 ThreadOptions;
enum {
   kNewSuspend = (1 << 0),
   kUsePremadeThread = (1 << 1),
   kCreateIfNeeded = (1 << 2),
   kFPUNotNeeded = (1 << 3),
   kExactMatchThread = (1 << 4)
};
Constants
kNewSuspend

Begin a new thread in the stopped state.

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

Use a thread from the existing supply.

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

Create a new thread if one with the proper style and stack size requirements does not exist.

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

Do not save the FPU context. This saves time when switching contexts. Note, however, that for PowerPC threads, the Thread Manager always saves the FPU registers regardless of how you set this option. Because the PowerPC microprocessor uses the FPU registers for optimizations, they could contain necessary information.

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

Allocate a thread from the pool only if it exactly matches the stack-size request. Without this option, a thread is allocated that best fits the request—that is, a thread whose stack is greater than or equal to the requested size. 

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

When you create or allocate a new thread with the NewThread function, you can specify thread options that define certain characteristics of the thread, using the values described here. To specify more than one option, you sum them together and pass them as a single parameter to the NewThread function.

The ThreadOptions data type defines the thread options.*/

typedef UInt32 ThreadOptions;
enum {
   kNewSuspend = (1 << 0),
   kUsePremadeThread = (1 << 1),
   kCreateIfNeeded = (1 << 2),
   kFPUNotNeeded = (1 << 3),
   kExactMatchThread = (1 << 4)
};


/*Thread ID Constants

The ThreadID data type defines the thread ID. 

typedef UInt32 ThreadID;
enum {
   kNoThreadID = 0,
   kCurrentThreadID = 1,
   kApplicationThreadID = 2
};
Constants
kNoThreadID

Indicates no thread; for example, you can use a function such as SetThreadState to put the current thread in the stopped state and pass kNoThreadID to indicate that you don’t care which thread runs next.

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

Identifies the currently executing thread.

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

Identifies the main application thread this is the cooperative thread that the Thread Manager creates at launch time. You cannot dispose of this thread. All applications—even those that are not aware of the Thread Manager—have one main application thread. The Thread Manager assumes that the main application thread is responsible for event gathering when an operating-system event occurs, the Thread Manager schedules the main application thread as the next thread to execute. 

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

The Thread Manager assigns a thread ID to each thread that you create or allocate with the NewThread function. The thread ID uniquely identifies a thread within an application context. You can use the thread ID in functions that schedule execution of a particular thread, dispose of a thread, and get and set information about a thread; for example, you pass the thread ID to functions such as YieldToThread , DisposeThread , and GetThreadState . 

In addition to the specific thread IDs that the NewThread function returns, you can use the three Thread Manager constants described here.*/

typedef UInt32 ThreadID;
enum {
   kNoThreadID = 0,
   kCurrentThreadID = 1,
   kApplicationThreadID = 2
};

/*Thread Style Constants


typedef UInt32 ThreadStyle;
enum {
   kCooperativeThread = 1L << 0,
   kPreemptiveThread = 1L << 1
};
Constants
kCooperativeThread

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

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

Historically, the Thread Manager defined two types of threads to run in an application context: cooperative and preemptive, but now it supports only cooperative threads.

Although the Thread Manager only supports a single type of thread, many Thread Manager functions (for historical reasons) require you to use the thread type to specify the type of the thread. 

The ThreadStyle data type specifies the type of a thread. 

Because there is only one type of thread (cooperative) the thread type accepts a single value, kCooperativeThread.*/

typedef UInt32 ThreadStyle;
enum {
   kCooperativeThread = 1L << 0,
   kPreemptiveThread = 1L << 1
};

/*ThreadEntryProcPtr

Defines a pointer to a thread entry callback function. Your thread entry callback function provides an entry point to a thread that you create in your application.

typedef voidPtr (*ThreadEntryProcPtr)
(
   void * threadParam
);

If you name your function MyThreadEntryProc, you would declare it like this:

voidPtr MyThreadEntryProcPtr (
   void * threadParam
);
Parameters
threadParam

A pointer to a void data structure passed to this function by the NewThread function. 
Return Value
Discussion

When you create or allocate a new thread with the NewThread function, you pass the name of this entry function. You also pass a parameter that the Thread Manager passes on to the MyThreadEntryCallback function. You can use this parameter to pass thread-specific information to the newly created or allocated thread. For example, you could pass something like A5 information or the address of a window to update. Or you could use this parameter to specify local storage for a thread that other threads could access. 

When the code in a thread finishes executing, the Thread Manager automatically calls the DisposeThread function to dispose of the thread. The MyThreadEntryCallback function passes its function result to DisposeThread. The DisposeThread function passes this result back to the NewThread function that called MyThreadEntryCallback to begin with.

This mechanism allows you to spawn a thread that does some work and then continue with your original thread. When the spawned thread is finished doing its work—for example a calculation—it returns the result to the original thread.*/

typedef voidPtr (*ThreadEntryProcPtr)
(
   void * threadParam
);


/*ThreadEntryUPP


typedef ThreadEntryProcPtr ThreadEntryUPP;
Discussion

For more information, see the description of the ThreadEntryUPP () callback function.*/
typedef ThreadEntryProcPtr ThreadEntryUPP;

/*ThreadEntryTPP


typedef ThreadEntryUPP ThreadEntryTPP;
Discussion
Availability
Available in Mac OS X v10.0 and later.*/
typedef ThreadEntryUPP ThreadEntryTPP;

//function

/*DisposeThread

Deletes a thread when it finishes executing. 

OSErr DisposeThread (
   ThreadID threadToDump,
   void * threadResult,
   Boolean recycleThread
);
Parameters
threadToDump

The thread ID of the thread to delete. 
threadResult

A pointer to the thread’s result. The DisposeThread function places this result to an address which you originally specify with the threadResult parameter of the NewThread function when you create or allocate the thread. Pass a value of NULL if you are not interested in obtaining a function result. 
recycleThread

A Boolean value that specifies whether to return the thread to the allocation pool or to remove it entirely. Specify False to dispose of the thread entirely and True to return it to the thread pool. 
Return Value

A result code. See “Thread Manager Result Codes”.
Discussion

When a thread finishes executing, the Thread Manager automatically calls DisposeThread to delete it. Therefore, the only reason for you to explicitly call DisposeThread is to recycle a terminating thread. To do so, set the recycleThread parameter to True. The Thread Manager clears out the thread’s internal data structure, resets it, and puts the thread in the thread pool where it can be used again as necessary. 

The DisposeThread function sets the threadResult parameter to the thread’s function result. You allocate the storage for the thread result when you create or allocate a thread with the NewThread function.

You cannot explicitly dispose of the main application thread. If you attempt to do so, DisposeThread returns the threadProtocolErr result code.

When your application terminates, the Thread Manager calls DisposeThread to terminate any active threads. It terminates stopped and ready threads first but in no special order. It terminates the currently running thread last. This thread should always be the main application thread. 

To install a callback function to do special cleanup when a thread terminates, use the SetThreadTerminator function. 
Special Considerations

Active development with the Thread Manager is not recommended. The API is intended only for developers who are porting their applications to Mac OS X and whose code relies on the cooperative threading model. If you are writing a new Carbon application, you should use POSIX threads or the Multiprocessing Services API instead. See Multithreading Programming Topics for more information.
Availability
Available in Mac OS X v10.0 and later.
Declared In
Threads.h*/

OSErr DisposeThread (
   ThreadID threadToDump,
   void * threadResult,
   Boolean recycleThread
);

/*NewThread

Creates a new thread or allocates one from the existing pool of threads.

Modified

OSErr NewThread (
   ThreadStyle threadStyle,
   ThreadEntryTPP threadEntry,
   void * threadParam,
   Size stackSize,
   ThreadOptions options,
   void ** threadResult,
   ThreadID * threadMade
);
Parameters
threadStyle

The type of thread to create. Cooperative is the only type that you can specify. Historically, the Thread Manger supported two types of threads, preemptive and cooperative, but the Thread Manager no longer supports preemptive threads. 
threadEntry

A pointer to the thread entry function. 
threadParam

A pointer to a value that the Thread Manager passes as a parameter to the thread entry function. Specify NULL if you are passing no information. 
stackSize

The stack size (in bytes) to allocate for this thread. This stack must be large enough to handle saved thread context, normal application stack usage, interrupt handling functions, and CPU exceptions. Specify a stack size of 0 (zero) to request the Thread Manager’s default stack size. 
options

Options that define characteristics of the new thread. See the Thread Option Constants data type for details on the options. You sum the options together to create a single options parameter. 
threadResult

On return, a pointer to the address of a location to hold the function result provided by the Thread Option Constants function when the thread terminates. Specify NULL for this parameter if you are not interested in the function result.
threadMade

On return, a pointer to the thread ID of the newly created or allocated thread. If there is an error, threadMade points to a value of kNoThreadID. 
Return Value

A result code. See “Thread Manager Result Codes”.
Discussion

The NewThread function obtains a thread ID that you can use in other Thread Manager functions to identify the thread. If you want to allocate a thread from the pool of threads, specify the kUsePremadeThread option of the options parameter. Otherwise, NewThread creates a new thread.

When you request a thread from the existing pool, the Thread Manager allocates one that best fits your specified stack size. If you specify the kExactMatchThread option of the options parameter, the Thread Manager allocates a thread whose stack exactly matches your stack-size requirement or, if it can’t allocate one because no such thread exists, it returns the threadTooManyReqsErr result code.

Before making any calls to NewThread, be certain that you first have called the Memory Manager function MaxApplZone to extend the application heap to its limit. You must call MaxApplZone from the main application thread before any other threads in your application run. 

When you call the NewThread function, you pass, as the threadEntry parameter, a pointer to the name of the entry function to the thread. When the newly created thread runs initially, it begins by executing this function.

You can use the threadParam parameter to pass thread-specific information to a newly created or allocated thread. In the data structure pointed to by this parameter, you could place something like A5 information or the address of a window to update. You could also use this parameter to specify a place for a thread’s local storage.

Be sure to create the storage for the threadResult parameter in a place that is guaranteed to be available when the thread terminates—for example, in an application global variable or in a local variable of the application’s main function (the main thread, by definition, cannot be disposed of so it is always available). Do not create the storage in a local variable of a subfunction that completes before the thread terminates or the storage will become invalid.

For Carbon applications, the pointer to your thread entry function must be a universal procedure pointer (UPP).

To dispose of a thread, use the DisposeThread function.

See the description of the Thread Option Constants data type for details on the characteristics you can specify in the options parameter.

For more information about the thread entry function, see the ThreadEntryProcPtr function. 
Special Considerations

Active development with the Thread Manager is not recommended. The API is intended only for developers who are porting their applications to Mac OS X and whose code relies on the cooperative threading model. If you are writing a new Carbon application, you should use POSIX threads or the Multiprocessing Services API instead. See Multithreading Programming Topics for more information.
Carbon Porting Notes

For Carbon applications, you must create and pass a universal procedure pointer (UPP) to specify the new thread callback. Use the NewThreadEntryUPP and DisposeThreadEntryUPP functions to create and remove the UPP.
Availability
Available in Mac OS X v10.0 and later.
Declared In
Threads.h*/

OSErr NewThread (
   ThreadStyle threadStyle,
   ThreadEntryTPP threadEntry,
   void * threadParam,
   Size stackSize,
   ThreadOptions options,
   void ** threadResult,
   ThreadID * threadMade
);

/*YieldToAnyThread

Relinquishes the current thread’s control.

OSErr YieldToAnyThread ();
Return Value

A result code. See “Thread Manager Result Codes”.
Discussion

The YieldToAnyThread function invokes the Thread Manager’s scheduling mechanism. The current thread relinquishes control and the Thread Manager schedules the next available thread.

The current thread is suspended in the ready state and awaits rescheduling when the CPU is available. When the suspended thread is scheduled again, YieldToAnyThread regains control and returns to the function that called it.

If you have installed a custom scheduler, the Thread Manager passes it the thread ID of the suspended thread.

In each thread you must make one or more strategically placed calls to relinquish control to another thread. You can either make this yield call or another yield call such as YieldToThread; or you can make a call such as SetThreadState to explicitly change the state of the thread.

Threads must yield in the CPU addressing mode (24-bit or 32-bit) in which the application was launched.

To relinquish control to a specific thread, use the YieldToThread function.

To change the state of a specified thread, use the SetThreadState function. 
Special Considerations

Active development with the Thread Manager is not recommended. The API is intended only for developers who are porting their applications to Mac OS X and whose code relies on the cooperative threading model. If you are writing a new Carbon application, you should use POSIX threads or the Multiprocessing Services API instead. See Multithreading Programming Topics for more information.
Availability
Available in Mac OS X v10.0 and later.
Declared In
Threads.h*/
OSErr YieldToAnyThread ();

/*NewThreadEntryUPP


ThreadEntryUPP NewThreadEntryUPP (
   ThreadEntryProcPtr userRoutine
);
Parameters
userRoutine
Return Value

See the description of the ThreadEntryUPP data type.
Special Considerations

Active development with the Thread Manager is not recommended. The API is intended only for developers who are porting their applications to Mac OS X and whose code relies on the cooperative threading model. If you are writing a new Carbon application, you should use POSIX threads or the Multiprocessing Services API instead. See Multithreading Programming Topics for more information.
Availability
Available in Mac OS X v10.0 and later.
Declared In
Threads.h*/

ThreadEntryUPP NewThreadEntryUPP (
   ThreadEntryProcPtr userRoutine
);


#ifdef __cplusplus
}
#endif

#endif