/****************************************************************************************


		MCSMP.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Emil
		Date:	3/27/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		10/18/99	Yann		SetAtomicCounterValue was returning an int32 on the Mac
		7/29/99		Eml			Atomic Counter fix
		6/10/99		Ian			Array API changes.
		04/23/99	Eml/scooper	stub MakeSMPProcess
		4/22/99		Eml			Reverted to old TLS mechanism. New one could not work on the Mac
		5/27/98		Eml			include MCOSConfig.h

*****************************************************************************************/

#ifndef __MCSMP__
#define __MCSMP__

#include "MCArray.h"
#include "MCBasicTypes.h"
#include "MCOSConfig.h"

#include "MCSMPCriticalSection.h"
#include "MCSMPAtomicCounter.h"


//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// Core SMP Calls
//
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

class TMCLocalStorage;
class TMCSemaphore;

#define kSMPNotAvailable 0

extern boolean gForceSMP;


enum ESmpThreadPriority
{
	kLowPriority			= 0,	//for background threads (like news download)
	kNormalPriority,				//standard priority (the application)
	kHighPriority,					//for greedy threads (like rendering thread)

	kInvalidPriority		= 0xFFFFFFFF
};



#ifdef qSMP

//Real definitions of SMP calls when qSMP is defined


class TMCLocalStorageDataPtrArray;

extern int32 gNumberOfProcessors;

void	InitSysDepSMP(boolean enable);
void	TerminateSysDepSMP(void);
void*	GetPlaformSMPData();
void*	GetMacSMPTLSIndex();

void InitSMP(boolean enable);
void TerminateSMP(void);
void FinishTerminateSMP();


//************************************************************************


typedef void (*DeleteProc)(void **privData);

TMCLocalStorage* NewTLS();
TMCLocalStorage* NewTLSWithDelete(DeleteProc deleteProc);
void DeleteTLS(TMCLocalStorage* aTLS);
void SetTLS(TMCLocalStorage* &aTLS, void * value);
void * GetTLS(TMCLocalStorage* aTLS);
boolean IsTLSValid();

boolean* GetSMPAbortFlag();

boolean IsInMainSMPProcess();

int32 GetNumberOfProcessors();
#if MAC
boolean IsSystemSafe();
#else
int32	GetCurrentSMPThreadID(); // This fucntion is only used for assertion therefor not developed for the MAC
#define IsSystemSafe() true
#endif

#define kWaitForEver 0xFFFFFFFF  // Infinite timeout

TMCSemaphore * NewSemaphore(int32 maxValue, int32 initialValue);
void DeleteSemaphore(TMCSemaphore * event);
void SignalSemaphore(TMCSemaphore * event);

// Wait for a semaphore to be signaled. waitTime is the time out time in milliseconds.
// Use kWaitForEver if you want to wait forever.
boolean WaitForSemaphore(TMCSemaphore * event,int32 waitTime);

int32 AtomicExchange(int32 * variable, int32 newValue);

#else // if qSMP

#error "You must define qSMP !!!"

/*
//Stubbed definitions of SMP calls when qSMP is not defined

//typedef int32 TMCCriticalSection;

#define MakeSMPProcess(a, b, c, d, e, f, g) 0 //MakeRProcess(a, b, c, d, e, nil)
#define PauseSMPProcess PauseRProcess
#define ResumeSMPProcess ResumeRProcess
#define LockSMPProcess LockRProcess
#define UnlockSMPProcess UnlockRProcess
#define KillSMPProcess KillRProcess
#define ExistsSMPProcess ExistsRProcess
#define ScheduleSMPProcess ScheduleRProcess
#define ForceScheduleSMPProcess ForceScheduleRProcess
#define InitSMP(x)
#define TerminateSMP()


************************************************************************

#define NewTLS() nil
#define NewTLSWithDelete(x) nil
#define DeleteTLS(x)
#define SetTLS(x, y) (x)=(TMCLocalStorage*)(y)
#define GetTLS(x) ((void*)x)
#define GetSMPAbortFlag() NULL

#define IsInMainSMPProcess() true
#define IsSystemSafe() true
#define GetNumberOfProcessors() 1

#define NewSemaphore(x, y) nil
#define DeleteSemaphore(x)
#define SignalSemaphore(x);
#define WaitForSemaphore(x, y) false

#define AtomicExchange(x, y) *(x);*(x)=(y)
*/
#endif


#endif

