2018-07-06 14:11:38 +00:00
|
|
|
#ifndef BASE_TL_THREADING_H
|
|
|
|
#define BASE_TL_THREADING_H
|
2011-12-30 15:02:22 +00:00
|
|
|
|
|
|
|
#include "../system.h"
|
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
/*
|
|
|
|
atomic_inc - should return the value after increment
|
|
|
|
atomic_dec - should return the value after decrement
|
|
|
|
atomic_compswap - should return the value before the eventual swap
|
2013-04-02 14:53:57 +00:00
|
|
|
sync_barrier - creates a full hardware fence
|
2012-01-01 14:56:28 +00:00
|
|
|
*/
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
#if defined(__GNUC__)
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
inline unsigned atomic_inc(volatile unsigned *pValue)
|
|
|
|
{
|
2013-04-02 14:53:57 +00:00
|
|
|
return __sync_add_and_fetch(pValue, 1);
|
2012-01-01 14:56:28 +00:00
|
|
|
}
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
inline unsigned atomic_dec(volatile unsigned *pValue)
|
|
|
|
{
|
2013-04-02 14:53:57 +00:00
|
|
|
return __sync_add_and_fetch(pValue, -1);
|
2012-01-01 14:56:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned atomic_compswap(volatile unsigned *pValue, unsigned comperand, unsigned value)
|
|
|
|
{
|
|
|
|
return __sync_val_compare_and_swap(pValue, comperand, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void sync_barrier()
|
|
|
|
{
|
|
|
|
__sync_synchronize();
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
#include <intrin.h>
|
|
|
|
|
2013-04-03 09:44:06 +00:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include <windows.h>
|
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
inline unsigned atomic_inc(volatile unsigned *pValue)
|
|
|
|
{
|
|
|
|
return _InterlockedIncrement((volatile long *)pValue);
|
|
|
|
}
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2012-01-01 14:56:28 +00:00
|
|
|
inline unsigned atomic_dec(volatile unsigned *pValue)
|
|
|
|
{
|
|
|
|
return _InterlockedDecrement((volatile long *)pValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned atomic_compswap(volatile unsigned *pValue, unsigned comperand, unsigned value)
|
|
|
|
{
|
|
|
|
return _InterlockedCompareExchange((volatile long *)pValue, (long)value, (long)comperand);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void sync_barrier()
|
|
|
|
{
|
2013-04-03 09:44:06 +00:00
|
|
|
MemoryBarrier();
|
2012-01-01 14:56:28 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
#error missing atomic implementation for this compiler
|
|
|
|
#endif
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2017-08-31 17:13:55 +00:00
|
|
|
class semaphore
|
|
|
|
{
|
|
|
|
SEMAPHORE sem;
|
|
|
|
public:
|
|
|
|
semaphore() { sphore_init(&sem); }
|
|
|
|
~semaphore() { sphore_destroy(&sem); }
|
|
|
|
void wait() { sphore_wait(&sem); }
|
|
|
|
void signal() { sphore_signal(&sem); }
|
|
|
|
};
|
2011-12-30 15:02:22 +00:00
|
|
|
|
|
|
|
class lock
|
|
|
|
{
|
|
|
|
friend class scope_lock;
|
|
|
|
|
|
|
|
LOCK var;
|
|
|
|
|
|
|
|
void take() { lock_wait(var); }
|
2015-04-07 17:07:38 +00:00
|
|
|
void release() { lock_unlock(var); }
|
2011-12-30 15:02:22 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
lock()
|
|
|
|
{
|
|
|
|
var = lock_create();
|
|
|
|
}
|
|
|
|
|
|
|
|
~lock()
|
|
|
|
{
|
|
|
|
lock_destroy(var);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class scope_lock
|
|
|
|
{
|
|
|
|
lock *var;
|
|
|
|
public:
|
|
|
|
scope_lock(lock *l)
|
|
|
|
{
|
|
|
|
var = l;
|
|
|
|
var->take();
|
|
|
|
}
|
|
|
|
|
|
|
|
~scope_lock()
|
|
|
|
{
|
|
|
|
var->release();
|
|
|
|
}
|
|
|
|
};
|
2018-07-06 14:11:38 +00:00
|
|
|
|
|
|
|
#endif // BASE_TL_THREADING_H
|