2010-04-25 00:31:27 +00:00
/*
2010-04-24 21:37:39 +00:00
* Copyright ( C ) 2007 - 2009 Gabest
* http : //www.gabest.org
*
* This Program 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 2 , or ( at your option )
* any later version .
2010-04-25 00:31:27 +00:00
*
2010-04-24 21:37:39 +00:00
* This Program 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 .
2010-04-25 00:31:27 +00:00
*
2010-04-24 21:37:39 +00:00
* You should have received a copy of the GNU General Public License
* along with GNU Make ; see the file COPYING . If not , write to
2012-09-09 18:16:11 +00:00
* the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA USA .
2010-04-24 21:37:39 +00:00
* http : //www.gnu.org/copyleft/gpl.html
*
*/
2011-02-19 03:36:30 +00:00
# include "stdafx.h"
2010-04-24 21:37:39 +00:00
# include "GSThread.h"
2011-12-27 09:15:35 +00:00
# ifdef _WINDOWS
InitializeConditionVariablePtr pInitializeConditionVariable ;
WakeConditionVariablePtr pWakeConditionVariable ;
WakeAllConditionVariablePtr pWakeAllConditionVariable ;
SleepConditionVariableSRWPtr pSleepConditionVariableSRW ;
2012-02-08 16:57:14 +00:00
InitializeSRWLockPtr pInitializeSRWLock ;
2011-12-27 09:15:35 +00:00
AcquireSRWLockExclusivePtr pAcquireSRWLockExclusive ;
2012-01-18 11:47:31 +00:00
TryAcquireSRWLockExclusivePtr pTryAcquireSRWLockExclusive ;
2011-12-27 09:15:35 +00:00
ReleaseSRWLockExclusivePtr pReleaseSRWLockExclusive ;
2012-02-08 16:57:14 +00:00
AcquireSRWLockSharedPtr pAcquireSRWLockShared ;
TryAcquireSRWLockSharedPtr pTryAcquireSRWLockShared ;
ReleaseSRWLockSharedPtr pReleaseSRWLockShared ;
2011-12-27 09:15:35 +00:00
class InitCondVar
{
HMODULE m_kernel32 ;
public :
InitCondVar ( )
{
m_kernel32 = LoadLibrary ( " kernel32.dll " ) ; // should not call LoadLibrary from DllMain, but kernel32.dll is the only one guaranteed to be loaded already
pInitializeConditionVariable = ( InitializeConditionVariablePtr ) GetProcAddress ( m_kernel32 , " InitializeConditionVariable " ) ;
pWakeConditionVariable = ( WakeConditionVariablePtr ) GetProcAddress ( m_kernel32 , " WakeConditionVariable " ) ;
pWakeAllConditionVariable = ( WakeAllConditionVariablePtr ) GetProcAddress ( m_kernel32 , " WakeAllConditionVariable " ) ;
pSleepConditionVariableSRW = ( SleepConditionVariableSRWPtr ) GetProcAddress ( m_kernel32 , " SleepConditionVariableSRW " ) ;
pInitializeSRWLock = ( InitializeSRWLockPtr ) GetProcAddress ( m_kernel32 , " InitializeSRWLock " ) ;
pAcquireSRWLockExclusive = ( AcquireSRWLockExclusivePtr ) GetProcAddress ( m_kernel32 , " AcquireSRWLockExclusive " ) ;
2012-01-18 11:47:31 +00:00
pTryAcquireSRWLockExclusive = ( TryAcquireSRWLockExclusivePtr ) GetProcAddress ( m_kernel32 , " TryAcquireSRWLockExclusive " ) ;
2011-12-27 09:15:35 +00:00
pReleaseSRWLockExclusive = ( ReleaseSRWLockExclusivePtr ) GetProcAddress ( m_kernel32 , " ReleaseSRWLockExclusive " ) ;
2012-02-08 16:57:14 +00:00
pAcquireSRWLockShared = ( AcquireSRWLockSharedPtr ) GetProcAddress ( m_kernel32 , " AcquireSRWLockShared " ) ;
pTryAcquireSRWLockShared = ( TryAcquireSRWLockSharedPtr ) GetProcAddress ( m_kernel32 , " TryAcquireSRWLockShared " ) ;
pReleaseSRWLockShared = ( ReleaseSRWLockSharedPtr ) GetProcAddress ( m_kernel32 , " ReleaseSRWLockShared " ) ;
2011-12-27 09:15:35 +00:00
}
virtual ~ InitCondVar ( )
{
FreeLibrary ( m_kernel32 ) ;
}
} ;
static InitCondVar s_icv ;
# endif
2010-04-24 21:37:39 +00:00
GSThread : : GSThread ( )
{
2011-02-19 03:36:30 +00:00
# ifdef _WINDOWS
m_ThreadId = 0 ;
m_hThread = NULL ;
# else
# endif
2010-04-24 21:37:39 +00:00
}
GSThread : : ~ GSThread ( )
{
CloseThread ( ) ;
}
2011-02-19 03:36:30 +00:00
# ifdef _WINDOWS
DWORD WINAPI GSThread : : StaticThreadProc ( void * lpParam )
2010-04-24 21:37:39 +00:00
{
( ( GSThread * ) lpParam ) - > ThreadProc ( ) ;
return 0 ;
}
2011-02-19 03:36:30 +00:00
# else
void * GSThread : : StaticThreadProc ( void * param )
{
( ( GSThread * ) param ) - > ThreadProc ( ) ;
2014-11-18 13:40:29 +00:00
# ifndef _STD_THREAD_ // exit is done implicitly by std::thread
2011-02-19 03:36:30 +00:00
pthread_exit ( NULL ) ;
2014-11-18 13:40:29 +00:00
# endif
2011-02-19 03:36:30 +00:00
return NULL ;
}
# endif
2010-04-24 21:37:39 +00:00
void GSThread : : CreateThread ( )
{
2011-02-19 03:36:30 +00:00
# ifdef _WINDOWS
m_hThread = : : CreateThread ( NULL , 0 , StaticThreadProc , ( void * ) this , 0 , & m_ThreadId ) ;
# else
2014-11-18 13:40:29 +00:00
# ifdef _STD_THREAD_
t = new thread ( StaticThreadProc , ( void * ) this ) ;
# else
2011-02-19 03:36:30 +00:00
pthread_attr_init ( & m_thread_attr ) ;
pthread_create ( & m_thread , & m_thread_attr , StaticThreadProc , ( void * ) this ) ;
2014-11-18 13:40:29 +00:00
# endif
2011-02-19 03:36:30 +00:00
# endif
2010-04-24 21:37:39 +00:00
}
void GSThread : : CloseThread ( )
{
2011-02-19 03:36:30 +00:00
# ifdef _WINDOWS
2010-04-24 21:37:39 +00:00
if ( m_hThread ! = NULL )
{
if ( WaitForSingleObject ( m_hThread , 5000 ) ! = WAIT_OBJECT_0 )
{
2014-01-25 14:25:48 +00:00
printf ( " GSdx: WARNING: GSThread Thread did not close itself in time. Assuming hung. Terminating. \n " ) ;
2010-04-24 21:37:39 +00:00
TerminateThread ( m_hThread , 1 ) ;
}
CloseHandle ( m_hThread ) ;
m_hThread = NULL ;
m_ThreadId = 0 ;
}
2011-02-19 03:36:30 +00:00
# else
2015-01-15 13:54:38 +00:00
// Should be tested on windows too one day, native handle should be disabled there though, or adapted to windows thread
2014-11-18 13:40:29 +00:00
# ifdef _STD_THREAD_
2015-01-15 13:54:38 +00:00
# define _NATIVE_HANDLE_ // Using std::thread native handle, allows to just use posix stuff.
# ifdef _NATIVE_HANDLE_ // std::thread join seems to be bugged, have to test it again every now and then, it did work at some point(gcc 5), seems there is bug in system lib...
pthread_t m_thread = t - > native_handle ( ) ;
void * ret = NULL ;
pthread_join ( m_thread , & ret ) ;
/* We are sure thread is dead, not so bad.
* Still no way to to delete that crap though . . . Really , wtf is this standard ? ?
* I guess we will have to wait that someone debug either the implementation or change standard .
* There should be a moderate memory leak for now , I am trying to find a way to fix it .
* 3 kinox
*/
# else
2014-11-18 13:40:29 +00:00
if ( t - > joinable ( ) )
{
t - > join ( ) ;
}
delete ( t ) ;
2015-01-15 13:54:38 +00:00
# endif
2014-11-18 13:40:29 +00:00
# else
2011-02-19 03:36:30 +00:00
void * ret = NULL ;
pthread_join ( m_thread , & ret ) ;
pthread_attr_destroy ( & m_thread_attr ) ;
2014-11-18 13:40:29 +00:00
# endif
2011-02-19 03:36:30 +00:00
# endif
2010-04-24 21:37:39 +00:00
}