/** ** Supermodel ** A Sega Model 3 Arcade Emulator. ** Copyright 2011 Bart Trzynadlowski, Nik Henson ** ** This file is part of Supermodel. ** ** Supermodel is free software: you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free ** Software Foundation, either version 3 of the License, or (at your option) ** any later version. ** ** Supermodel is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ** more details. ** ** You should have received a copy of the GNU General Public License along ** with Supermodel. If not, see . **/ /* * Thread.cpp * * SDL-based implementation of threading primitives. */ #include "Supermodel.h" #ifdef SUPERMODEL_OSX #include #include #else #include #include #endif void CThread::Sleep(UINT32 ms) { SDL_Delay(ms); } UINT32 CThread::GetTicks() { return SDL_GetTicks(); } CThread *CThread::CreateThread(const std::string &name, ThreadStart start, void *startParam) { SDL_Thread *impl = SDL_CreateThread(start, name.c_str(), startParam); if (impl == NULL) return NULL; return new CThread(name, impl); } CSemaphore *CThread::CreateSemaphore(UINT32 initVal) { SDL_sem *impl = SDL_CreateSemaphore(initVal); if (impl == NULL) return NULL; return new CSemaphore(impl); } CCondVar *CThread::CreateCondVar() { SDL_cond *impl = SDL_CreateCond(); if (impl == NULL) return NULL; return new CCondVar(impl); } CMutex *CThread::CreateMutex() { SDL_mutex *impl = SDL_CreateMutex(); if (impl == NULL) return NULL; return new CMutex(impl); } const char *CThread::GetLastError() { return SDL_GetError(); } CThread::CThread(const std::string &name, void *impl) : m_name(name), m_impl(impl) { // } CThread::~CThread() { // User should have called Wait() before thread object is destroyed if (nullptr != m_impl) { ErrorLog("Runaway thread error. A thread was not properly halted: %s\n", GetName()); } } const std::string &CThread::GetName() const { return m_name; } UINT32 CThread::GetId() { return SDL_GetThreadID((SDL_Thread*)m_impl); } int CThread::Wait() { int status; if (m_impl == NULL) return -1; SDL_WaitThread((SDL_Thread*)m_impl, &status); m_impl = NULL; return status; } CSemaphore::CSemaphore(void *impl) : m_impl(impl) { // } CSemaphore::~CSemaphore() { SDL_DestroySemaphore((SDL_sem*)m_impl); } UINT32 CSemaphore::GetValue() { return SDL_SemValue((SDL_sem*)m_impl); } bool CSemaphore::Wait() { return SDL_SemWait((SDL_sem*)m_impl) == 0; } bool CSemaphore::Post() { return SDL_SemPost((SDL_sem*)m_impl) == 0; } CCondVar::CCondVar(void *impl) : m_impl(impl) { // } CCondVar::~CCondVar() { SDL_DestroyCond((SDL_cond*)m_impl); } bool CCondVar::Wait(CMutex *mutex) { return SDL_CondWait((SDL_cond*)m_impl, (SDL_mutex*)mutex->m_impl) == 0; } bool CCondVar::Signal() { return SDL_CondSignal((SDL_cond*)m_impl) == 0; } bool CCondVar::SignalAll() { return SDL_CondBroadcast((SDL_cond*)m_impl) == 0; } CMutex::CMutex(void *impl) : m_impl(impl) { // } CMutex::~CMutex() { SDL_DestroyMutex((SDL_mutex*)m_impl); } bool CMutex::Lock() { return SDL_mutexP((SDL_mutex*)m_impl) == 0; } bool CMutex::Unlock() { return SDL_mutexV((SDL_mutex*)m_impl) == 0; }