//////////////////////////////////////////////////////////////////////////////
//
// Asura_Platform_MultithreadTypes.h
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
// Description:
//
//     PS3 base classes to provide data for multithreading primitives
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_PLATFORM_MULTITHREADTYPES_H___
#define ___ASURA_PLATFORM_MULTITHREADTYPES_H___ 1

#include "Debugging/Asura_Assert.h"

#include <sys/synchronization.h>
#include <sys/spinlock.h>

typedef sys_ppu_thread_t Asura_ThreadID;

class Asura_Platform_MutexData
{
public:

	Asura_Platform_MutexData()
    {
	    sys_lwmutex_attribute_t xMutexAttributes;
	    sys_lwmutex_attribute_initialize( xMutexAttributes );
	    sys_lwmutex_create( &m_xMutex, &xMutexAttributes );
    }

    ~Asura_Platform_MutexData()
    {
        sys_lwmutex_destroy( &m_xMutex );
    }

//protected:
//BW I need access to this to allow timeouts in some code (Asura_PS3_Graphics), maybe we should implement timeouts in the cross platform code.

	sys_lwmutex_t m_xMutex;
};

class Asura_Platform_SyncEvent
{
public:

	Asura_Platform_SyncEvent( const char* szName, bool bStartsSignalled )
	{
		sys_lwmutex_attribute_t xMutexAttributes;
		sys_lwcond_attribute_t	xCondAttributes;
		sys_lwmutex_attribute_initialize( xMutexAttributes );
		sys_lwmutex_create( &m_xMutex, &xMutexAttributes );

		sys_lwcond_attribute_initialize( xCondAttributes );
		sys_lwcond_create( &m_xCond, &m_xMutex, &xCondAttributes );

		if( bStartsSignalled )
		{
			sys_lwcond_signal( &m_xCond );
		}
	}

	~Asura_Platform_SyncEvent()
	{}

protected:
	sys_lwmutex_t	m_xMutex;
	sys_lwcond_t	m_xCond;
};

class Asura_Platform_Semaphore
{
public:

	Asura_Platform_Semaphore( const char* szName, u_int uInitialCount, u_int uMaxCount )
	{
		sys_semaphore_attribute_t xAttr;
		sys_semaphore_attribute_initialize(xAttr);

		int iResult = sys_semaphore_create(&m_xSemaphore, &xAttr, uInitialCount, uMaxCount);	  // Arbitrary max limit
		if (iResult < CELL_OK)
		{
			Asura_Assertf(false, ("Unable to initialise semaphore (%d)\n", iResult));
		}
	}

	~Asura_Platform_Semaphore()
	{
		int iResult = sys_semaphore_destroy(m_xSemaphore);
		if (iResult < CELL_OK)
		{
			Asura_Assertf(false, ("Unable to destroy semaphore (%d)\n", iResult));
		}
	}

protected:

	sys_semaphore_t m_xSemaphore;
};

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_PLATFORM_MULTITHREADTYPES_H___
