mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-27 07:06:00 +00:00
104 lines
2.5 KiB
C++
104 lines
2.5 KiB
C++
|
// VFSAtomic.cpp - atomic operations and thread locking
|
||
|
// For conditions of distribution and use, see copyright notice in VFS.h
|
||
|
|
||
|
/** --- Atomic operations and thread safety ---
|
||
|
* You may want to add your own implementation if thread safety is needed.
|
||
|
* If not, just leave everything like it is.
|
||
|
|
||
|
* If you are on windows, Interlocked[In/De]crement is faster than
|
||
|
explicit mutex locking for integer operations.
|
||
|
|
||
|
* TODO: The actual locking that is done in the tree when VFS_THREADSAFE is defined
|
||
|
is rather crude for the time beeing; a somewhat more efficient ReadWriteLock
|
||
|
implementation would be nice to have, someday.
|
||
|
|
||
|
* If you can, leave VFS_THREADSAFE undefined and do the locking externally,
|
||
|
it will probably have much better performance than if each and every operation
|
||
|
does a lock and unlock call.
|
||
|
(For a rather I/O based library this should not really make a difference, anyway.
|
||
|
But don't say you haven't been warned :) )
|
||
|
*/
|
||
|
|
||
|
#include "VFSInternal.h"
|
||
|
#include "VFSAtomic.h"
|
||
|
|
||
|
// for Interlocked[In/De]crement, if required
|
||
|
#if defined(_WIN32) && defined(VFS_THREADSAFE)
|
||
|
# define WIN32_LEAN_AND_MEAN
|
||
|
# include <windows.h>
|
||
|
#endif
|
||
|
|
||
|
VFS_NAMESPACE_START
|
||
|
|
||
|
#ifdef VFS_THREADSAFE
|
||
|
static Mutex mtx;
|
||
|
#endif
|
||
|
|
||
|
int Atomic_Incr(volatile int &i)
|
||
|
{
|
||
|
#ifdef VFS_THREADSAFE
|
||
|
# ifdef _WIN32
|
||
|
volatile LONG* dp = (volatile LONG*) &i;
|
||
|
return InterlockedIncrement( dp );
|
||
|
# else
|
||
|
Guard g(mtx);
|
||
|
# endif
|
||
|
#endif
|
||
|
return ++i;
|
||
|
}
|
||
|
|
||
|
int Atomic_Decr(volatile int &i)
|
||
|
{
|
||
|
#ifdef VFS_THREADSAFE
|
||
|
# ifdef _WIN32
|
||
|
volatile LONG* dp = (volatile LONG*) &i;
|
||
|
return InterlockedDecrement( dp );
|
||
|
# else
|
||
|
Guard g(mtx);
|
||
|
# endif
|
||
|
#endif
|
||
|
return --i;
|
||
|
}
|
||
|
|
||
|
/* Implement your Mutex class here.
|
||
|
Important: The mutex must be re-entrant/recursive,
|
||
|
means it must be possible to lock it from the same thread multiple times.
|
||
|
*/
|
||
|
Mutex::Mutex()
|
||
|
{
|
||
|
// implement your own if needed. Remove the trap below when you are done.
|
||
|
// This is to prevent people from defining VFS_THREADSAFE and expecting everything to work just like that :)
|
||
|
#ifdef VFS_THREADSAFE
|
||
|
#error VFSAtomic: Hey, you forgot to implement the mutex class, cant guarantee thread safety! Either undef VFS_THREADSAFE or read the docs and get your hands dirty.
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Mutex::~Mutex()
|
||
|
{
|
||
|
// implement your own if needed
|
||
|
}
|
||
|
|
||
|
void Mutex::Lock(void)
|
||
|
{
|
||
|
// implement your own if needed
|
||
|
}
|
||
|
|
||
|
void Mutex::Unlock(void)
|
||
|
{
|
||
|
// implement your own if needed
|
||
|
}
|
||
|
|
||
|
Guard::Guard(Mutex& m)
|
||
|
: _m(m)
|
||
|
{
|
||
|
_m.Lock();
|
||
|
}
|
||
|
|
||
|
Guard::~Guard()
|
||
|
{
|
||
|
_m.Unlock();
|
||
|
}
|
||
|
|
||
|
|
||
|
VFS_NAMESPACE_END
|