fix various races
This commit is contained in:
@@ -124,6 +124,7 @@ static int FindEmptyThreadSlot()
|
||||
if( g_ThreadSlots[entry].used )
|
||||
continue;
|
||||
|
||||
g_ThreadSlots[entry].used = true;
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -154,7 +155,6 @@ static void InitThreads()
|
||||
strcpy( g_ThreadSlots[slot].name, "Unknown thread" );
|
||||
g_ThreadSlots[slot].id = GetInvalidThreadId();
|
||||
sprintf( g_ThreadSlots[slot].ThreadFormattedOutput, "Unknown thread" );
|
||||
g_ThreadSlots[slot].used = true;
|
||||
g_pUnknownThreadSlot = &g_ThreadSlots[slot];
|
||||
|
||||
g_ThreadSlotsLock.Unlock();
|
||||
@@ -227,14 +227,12 @@ void RageThread::Create( int (*fn)(void *), void *data )
|
||||
strcpy( m_pSlot->name, name.c_str() );
|
||||
}
|
||||
|
||||
/* Start a thread using our own startup function. */
|
||||
m_pSlot->pImpl = MakeThread( fn, data );
|
||||
m_pSlot->id = m_pSlot->pImpl->GetThreadId();
|
||||
sprintf( m_pSlot->ThreadFormattedOutput, "Thread: %s", name.c_str() );
|
||||
|
||||
/* Only after everything in the slot is valid, mark the slot used, so all
|
||||
* "used" slots have a valid pImpl. */
|
||||
g_ThreadSlots[slotno].used = true;
|
||||
/* Start a thread using our own startup function. We pass the id to fill in,
|
||||
* to make sure it's set before the thread actually starts. (Otherwise, early
|
||||
* checkpoints might not have a completely set-up thread slot.) */
|
||||
m_pSlot->pImpl = MakeThread( fn, data, &m_pSlot->id );
|
||||
}
|
||||
|
||||
/* On startup, register the main thread's slot. We do this in a static constructor,
|
||||
@@ -249,7 +247,6 @@ static struct SetupMainThread
|
||||
sprintf( g_ThreadSlots[slot].ThreadFormattedOutput, "Thread: %s", g_ThreadSlots[slot].name );
|
||||
g_ThreadSlots[slot].pImpl = MakeThisThread();
|
||||
g_ThreadSlots[slot].id = RageThread::GetCurrentThreadID();
|
||||
g_ThreadSlots[slot].used = true;
|
||||
}
|
||||
} SetupMainThreadObj;
|
||||
|
||||
@@ -552,7 +549,7 @@ void RageMutex::Lock()
|
||||
#if defined(CRASH_HANDLER) && !defined(DARWIN)
|
||||
/* Don't leave g_ThreadSlotsLock when we call ForceCrashHandlerDeadlock. */
|
||||
g_ThreadSlotsLock.Lock();
|
||||
uint64_t CrashHandle = OtherSlot? OtherSlot->pImpl->GetCrashHandle():0;
|
||||
uint64_t CrashHandle = OtherSlot && OtherSlot->pImpl? OtherSlot->pImpl->GetCrashHandle():0;
|
||||
g_ThreadSlotsLock.Unlock();
|
||||
|
||||
/* Pass the crash handle of the other thread, so it can backtrace that thread. */
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
};
|
||||
|
||||
/* These functions must be implemented by the thread implementation. */
|
||||
ThreadImpl *MakeThread( int (*fn)(void *), void *data );
|
||||
ThreadImpl *MakeThread( int (*fn)(void *), void *data, uint64_t *piThreadID );
|
||||
ThreadImpl *MakeThisThread();
|
||||
MutexImpl *MakeMutex( RageMutex *pParent );
|
||||
SemaImpl *MakeSemaphore( int iInitialValue );
|
||||
|
||||
@@ -93,20 +93,32 @@ static void *StartThread( void *pData )
|
||||
pThis->MachThreadHandle = mach_thread_self();
|
||||
#endif
|
||||
|
||||
*pThis->m_piThreadID = pThis->GetThreadId();
|
||||
|
||||
fprintf(stderr, "set %i\n", (int) pThis->GetThreadId() );
|
||||
/* Tell MakeThread that we've set m_piThreadID, so it's safe to return. */
|
||||
sem_post( &pThis->m_StartFinishedSem );
|
||||
|
||||
return (void *) pThis->m_pFunc( pThis->m_pData );
|
||||
}
|
||||
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData )
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThreadID )
|
||||
{
|
||||
ThreadImpl_Pthreads *thread = new ThreadImpl_Pthreads;
|
||||
thread->m_pFunc = pFunc;
|
||||
thread->m_pData = pData;
|
||||
thread->m_piThreadID = piThreadID;
|
||||
sem_init( &thread->m_StartFinishedSem, 0, 0 );
|
||||
|
||||
int ret = pthread_create( &thread->thread, NULL, StartThread, thread );
|
||||
if( ret )
|
||||
RageException::Throw( "pthread_create: %s", strerror(ret) );
|
||||
|
||||
/* XXX: don't return until StartThread sets pid, etc */
|
||||
/* Don't return until StartThread sets m_piThreadID. */
|
||||
ret = sem_wait( &thread->m_StartFinishedSem );
|
||||
if( ret )
|
||||
RageException::Throw( "MakeThread(): sem_wait: %s", strerror(ret) );
|
||||
sem_destroy( &thread->m_StartFinishedSem );
|
||||
|
||||
return thread;
|
||||
}
|
||||
@@ -168,7 +180,6 @@ bool MutexImpl_Pthreads::Lock()
|
||||
int ret;
|
||||
do
|
||||
{
|
||||
CHECKPOINT;
|
||||
ret = pthread_mutex_lock( &mutex );
|
||||
}
|
||||
while( ret == -1 && ret == EINTR );
|
||||
@@ -240,7 +251,6 @@ bool SemaImpl_Pthreads::Wait()
|
||||
int ret;
|
||||
do
|
||||
{
|
||||
CHECKPOINT;
|
||||
ret = sem_wait( &sem );
|
||||
}
|
||||
while( ret == -1 && errno == EINTR );
|
||||
|
||||
@@ -26,8 +26,11 @@ public:
|
||||
thread_act_t MachThreadHandle;
|
||||
#endif
|
||||
|
||||
/* These are only used during initialization. */
|
||||
int (*m_pFunc)( void *pData );
|
||||
void *m_pData;
|
||||
uint64_t *m_piThreadID;
|
||||
sem_t m_StartFinishedSem;
|
||||
|
||||
void Halt( bool Kill );
|
||||
void Resume();
|
||||
|
||||
@@ -66,7 +66,7 @@ ThreadImpl *MakeThisThread()
|
||||
return thread;
|
||||
}
|
||||
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData )
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThreadID )
|
||||
{
|
||||
ThreadImpl_Win32 *thread = new ThreadImpl_Win32;
|
||||
thread->m_pFunc = pFunc;
|
||||
|
||||
Reference in New Issue
Block a user