/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/drivers/wintel32/core/threading/wintel32threadmanager.cpp

*/

#include "drivers/wintel32/device.hpp"
#include "sgx/core/core.hpp"
#include "drivers/wintel32/core/threading/threading.hpp"

CSGXThreadManager *CDriverWintel32ThreadManager::create() 
{
    if (ms_pSingleton == NULL) {
        ms_pSingleton = SGX_STATIC_CAST(CSGXThreadManager *, new CDriverWintel32ThreadManager());
    }
	return ms_pSingleton;
}

unsigned long __stdcall startThread(LPVOID usr)
{
	CSGXThread *pThread = SGX_STATIC_CAST(CSGXThread *, usr);
	tMEM_SIZE returnValue = pThread->start();
	SGX_UNUSED(returnValue);
	return 0L;
}

CSGXThread *CDriverWintel32ThreadManager::create(CSGXThread *pThread) 
{
	// TODO Use the information in m_pCPU to determine on which
	// processor this thread starts.
	pThread->m_SystemID = (tMEM_SIZE)CreateThread(NULL, 10000, startThread, pThread, 0L, NULL);
	return pThread;
}

CSGXThread *CDriverWintel32ThreadManager::create(cbThreadFunction cb, void *pUserData, sgxCPU *pCPU) 
{
	CSGXThread *pThread = new CSGXThread(pCPU);
	pThread->m_pUserData = pUserData;
	pThread->m_CallbackToStartThread = cb;
	return create(pThread);
}

void CDriverWintel32ThreadManager::destroy(CSGXThread *pThread) 
{
	TerminateThread(SGX_REINTERPRET_CAST(HANDLE, pThread->m_SystemID), 0);
}

// Wintel can also support GetCurrentThread
