static inline int // return old value
atomic_add(volatile int *count, int add)
{
#ifdef __linux__
__asm__ __volatile__(
"lock xadd %0, (%1);"
: "=a"(add)
: "r"(count), "a"(add)
: "memory"
);
#else
#error "not done yet "
#endif
return add;
}
static inline int // return old value
atomic_swap(volatile void *lockword, int value)
{
#ifdef __linux__
__asm__ __volatile__(
"lock xchg %0, (%1);"
: "=a"(value)
: "r"(lockword), "a"(value)
: "memory"
);
#else
#error "not done yet "
#endif
return value;
}
static inline int // return old value
atomic_comp_swap(volatile void *lockword,
int exchange,
int comperand)
{
#ifdef __linux__
__asm__ __volatile__(
"lock cmpxchg %1, (%2)"
:"=a"(comperand)
:"d"(exchange), "r"(lockword), "a"(comperand)
);
#else
__asm {
mov eax, comperand
mov edx, exchange
mov ecx, lockword
lock cmpxchg [ecx], edx
mov comperand, eax
}
#endif /* #ifdef __linux__ */
return comperand;
}
static inline void
spin_lock(volatile int *lock)
{
int l;
int i = 10;
int id = thread_getid();
for (l=atomic_comp_swap(lock, id, 0);
l!=0 && l!=id;
l=atomic_comp_swap(lock, id, 0)
) {
if (i --) {
nop();
}
else {
i = 10;
thread_yield();
}
}
}
static inline bool
spin_unlock(volatile int *lock)
{
int id = thread_getid();
return id == atomic_comp_swap(lock, 0, id);
}
static inline bool
spin_trylock(volatile int *lock)
{
int id = thread_getid();
int owner = atomic_comp_swap(lock, id, 0);
return (owner==0 || owner==id);
}
static inline int
token_acquire(volatile int *token, int id)
{
return atomic_comp_swap(token, id, 0);
}
static inline int
token_release(volatile int *token, int id)
{
return atomic_comp_swap(token, 0, id);
}
static inline int
token_transfer(volatile int *token, int oldid, int newid)
{
return atomic_comp_swap(token, newid, oldid);
}
static inline int
token_set(volatile int *token, int id)
{
return atomic_comp_swap(token, id, *token);
}
#define DECLARE_SINGLETON(classname) \
public: \
static classname * Instance() { \
if (NULL != sm_pInstance) { \
return sm_pInstance; \
} \
spin_lock(&sm_lock); \
if (NULL == sm_pInstance) { \
sm_pInstance = new classname(); \
} \
spin_unlock(&sm_lock); \
return sm_pInstance; \
} \
static bool IsCreated() { \
bool b; \
spin_lock(&sm_lock); \
b = (NULL != sm_pInstance); \
spin_unlock(&sm_lock); \
return b; \
} \
protected: \
classname(); \
static classname * sm_pInstance; \
static volatile int sm_lock; \
private:
#define IMPLEMENT_SINGLETON(classname) \
classname* classname::sm_pInstance = NULL; \
volatile int classname::sm_lock = 0; \
classname::classname() {}
#define IMPLEMENT_SINGLETON_WITHOUT_CTOR(classname) \
volatile int classname::sm_lock = 0; \
classname * classname::sm_pInstance = NULL;