115 lines
2.1 KiB
C++
115 lines
2.1 KiB
C++
/*
|
|
* If you're going to use threads, remember this:
|
|
*
|
|
* Threads suck.
|
|
*
|
|
* If there's any way to avoid them, take it! Threaded code an order of
|
|
* magnitude more complicated, harder to debug and harder to make robust.
|
|
*
|
|
* That said, here are a few helpers for when they're unavoidable. (Use
|
|
* SDL for the rest.)
|
|
*/
|
|
|
|
#include "global.h"
|
|
|
|
#include "RageThreads.h"
|
|
#include "RageTimer.h"
|
|
#include "RageLog.h"
|
|
#include "RageUtil.h"
|
|
|
|
RageMutex::RageMutex()
|
|
{
|
|
Locked = 0;
|
|
mut = SDL_CreateMutex();
|
|
mutwait = SDL_CreateMutex();
|
|
}
|
|
|
|
RageMutex::~RageMutex()
|
|
{
|
|
SDL_DestroyMutex(mut);
|
|
SDL_DestroyMutex(mutwait);
|
|
}
|
|
|
|
void RageMutex::Lock()
|
|
{
|
|
while(1)
|
|
{
|
|
SDL_LockMutex(mut);
|
|
if(!Locked || LockedBy == SDL_ThreadID())
|
|
{
|
|
if(!Locked)
|
|
{
|
|
/* This mutex is now locked. */
|
|
SDL_LockMutex(mutwait);
|
|
LockedBy = SDL_ThreadID();
|
|
} /* (else it was already locked and we're just increasing the counter) */
|
|
Locked++;
|
|
SDL_UnlockMutex(mut);
|
|
return;
|
|
}
|
|
|
|
SDL_UnlockMutex(mut);
|
|
|
|
/* Someone else is locking it. Wait until it's available and try again. */
|
|
SDL_LockMutex(mutwait);
|
|
SDL_UnlockMutex(mutwait);
|
|
}
|
|
}
|
|
|
|
void RageMutex::Unlock()
|
|
{
|
|
SDL_LockMutex(mut);
|
|
ASSERT(Locked);
|
|
ASSERT(LockedBy == SDL_ThreadID());
|
|
|
|
Locked--;
|
|
if(!Locked)
|
|
{
|
|
LockedBy = 0;
|
|
SDL_UnlockMutex(mutwait);
|
|
}
|
|
|
|
SDL_UnlockMutex(mut);
|
|
}
|
|
|
|
LockMutex::LockMutex(RageMutex &mut, const char *file_, int line_):
|
|
mutex(mut),
|
|
file(file_),
|
|
line(line_),
|
|
locked_at(RageTimer::GetTimeSinceStart())
|
|
{
|
|
mutex.Lock();
|
|
locked = true;
|
|
}
|
|
|
|
LockMutex::~LockMutex()
|
|
{
|
|
if(locked)
|
|
mutex.Unlock();
|
|
}
|
|
|
|
void LockMutex::Unlock()
|
|
{
|
|
ASSERT(locked);
|
|
locked = false;
|
|
|
|
mutex.Unlock();
|
|
|
|
if(file && locked_at != -1)
|
|
{
|
|
float dur = RageTimer::GetTimeSinceStart() - locked_at;
|
|
if(dur > 0.015)
|
|
LOG->Trace(ssprintf("Lock at %s:%i took %f", file, line, dur));
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
File: RageThreads
|
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
|
Glenn Maynard
|
|
-----------------------------------------------------------------------------
|
|
*/
|