/*==================================================================================================
	CAPThread.h

	$Log: CAPThread.h,v $
	Revision 1.12  2004/10/28 01:20:23  dwyatt
	[a radar for each of our projects] CAPThread.h requires unistd.h
	
	Revision 1.11  2004/08/26 08:13:33  jcm10
	finish bring up on Windows
	
	Revision 1.10  2004/08/26 04:42:02  jcm10
	add initial Windows support
	
	Revision 1.9  2004/08/23 06:23:25  jcm10
	make it build on Windows
	
	Revision 1.8  2004/03/02 22:13:38  dwyatt
	add option to set fixed priority
	
	Revision 1.7  2003/11/22 00:08:06  dwyatt
	preliminary Win work
	
	Revision 1.6  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.5  2002/09/17 18:55:55  luke
	[2999188] fixed SetPriority(...) mechanism to work with new Mach API's.
	Also added call to get current scheduled priority of thread.
	
	Revision 1.4  2002/05/18 01:12:33  bills
	back out mistaken commit
	
	Revision 1.3  2002/05/18 01:06:09  bills
	moved files to public utils
	
	Revision 1.2  2002/04/18 02:20:12  jcm10
	clean up the header inclusion
	
	Revision 1.1  2002/03/01 01:52:40  jcm10
	moved here from ../Utility
	
	Revision 1.6  2001/08/24 18:40:39  jcm10
	revamp the implementation to better reflect how mach works
	
	Revision 1.5  2001/01/16 22:23:57  jcm10
	support the time constraint thread scheduling policy
	
	Revision 1.4  2001/01/08 23:51:04  jcm10
	remove #pragma once, since gcc claims it to be obsolete and issues an annoying warning to that effect when all warnings are enabled
	
	Revision 1.3  2000/09/13 02:07:08  jcm10
	use CoreAudioTypes.h instead of <CoreServices/CoreServices.h>
	
	Revision 1.2  2000/09/12 23:14:16  jcm10
	add SetSchedulingPolicy
	
	Revision 1.1  2000/08/24 23:35:53  jcm10
	First checked in
	
	Revision 0.0  2000/01/01 12:34:56  jcm10
	created
		
	$NoKeywords: $
==================================================================================================*/
#if !defined(__CAPThread_h__)
#define __CAPThread_h__

//==================================================================================================
//	Includes
//==================================================================================================

//	System Includes
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <CoreAudio/CoreAudioTypes.h>
#else
	#include <CoreAudioTypes.h>
#endif

#if TARGET_OS_MAC
	#include <pthread.h>
	#include <unistd.h>
#elif TARGET_OS_WIN32
	#include <windows.h>
#else
	#error	Unsupported operating system
#endif

//==================================================================================================
//	CAPThread
//
//	This class wraps a pthread and a Win32 thread.
//	caution: long-running fixed priority threads can make the system unresponsive
//==================================================================================================

class	CAPThread
{

//	Types
public:
	typedef void*			(*ThreadRoutine)(void* inParameter);

//	Constants
public:
	enum
	{
#if	TARGET_OS_MAC
							kMinThreadPriority = 1,
							kMaxThreadPriority = 63,
							kDefaultThreadPriority = 31
#elif TARGET_OS_WIN32
							kMinThreadPriority = 1,
							kMaxThreadPriority = 31,
							kDefaultThreadPriority = THREAD_PRIORITY_NORMAL
#endif
	};

//	Construction/Destruction
public:
							CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority = kDefaultThreadPriority, bool inFixedPriority=false);
							CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible);
	virtual					~CAPThread();

//	Properties
public:
#if TARGET_OS_MAC
	pthread_t				GetPThread() const { return mPThread; }
	bool					IsCurrentThread() const { return (0 != mPThread) && (pthread_self() == mPThread); }
	bool					IsRunning() const { return 0 != mPThread; }
#elif TARGET_OS_WIN32
	HANDLE					GetThreadHandle() const { return mThreadHandle; }
	UInt32					GetThreadID() const { return mThreadID; }
	bool					IsCurrentThread() const { return (0 != mThreadID) && (GetCurrentThreadId() == mThreadID); }
	bool					IsRunning() const { return 0 != mThreadID; }
#endif

	bool					IsTimeShareThread() const { return !mTimeConstraintSet; }
	bool					IsTimeConstraintThread() const { return mTimeConstraintSet; }

	UInt32					GetPriority() const { return mPriority; }
    UInt32					GetScheduledPriority();
    void					SetPriority(UInt32 inPriority, bool inFixedPriority=false);

	void					GetTimeConstraints(UInt32& outPeriod, UInt32& outComputation, UInt32& outConstraint, bool& outIsPreemptible) const { outPeriod = mPeriod; outComputation = mComputation; outConstraint = mConstraint; outIsPreemptible = mIsPreemptible; }
	void					SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible);
	void					ClearTimeConstraints() { SetPriority(mPriority); }
		
//	Actions
public:
	virtual void			Start();

//	Implementation
protected:
#if TARGET_OS_MAC
	static void*			Entry(CAPThread* inCAPThread);
    static UInt32			getScheduledPriority(pthread_t inThread, int inPriorityKind);
#elif TARGET_OS_WIN32
	static UInt32 WINAPI	Entry(CAPThread* inCAPThread);
#endif

#if	TARGET_OS_MAC
	pthread_t				mPThread;
    UInt32					mSpawningThreadPriority;
#elif TARGET_OS_WIN32
	HANDLE					mThreadHandle;
	UInt32					mThreadID;
#endif
	ThreadRoutine			mThreadRoutine;
	void*					mThreadParameter;
	SInt32					mPriority;
	UInt32					mPeriod;
	UInt32					mComputation;
	UInt32					mConstraint;
	bool					mIsPreemptible;
	bool					mTimeConstraintSet;
    bool					mFixedPriority;
};

#endif
