forked from KolibriOS/kolibrios
ac054a24fe
git-svn-id: svn://kolibrios.org@6109 a494cfbc-eb01-0410-851d-a64ba20cac60
111 lines
2.1 KiB
C
111 lines
2.1 KiB
C
#ifndef __LBSYNC_H__
|
|
#define __LBSYNC_H__
|
|
|
|
#define FUTEX_INIT 0
|
|
#define FUTEX_DESTROY 1
|
|
#define FUTEX_WAIT 2
|
|
#define FUTEX_WAKE 3
|
|
|
|
#define exchange_acquire(ptr, new) \
|
|
__atomic_exchange_4((ptr), (new), __ATOMIC_ACQUIRE)
|
|
|
|
#define exchange_release(ptr, new) \
|
|
__atomic_exchange_4((ptr), (new), __ATOMIC_RELEASE)
|
|
|
|
|
|
typedef struct
|
|
{
|
|
volatile int lock;
|
|
int handle;
|
|
}mutex_t;
|
|
|
|
static inline int mutex_init(mutex_t *mutex)
|
|
{
|
|
int handle;
|
|
|
|
mutex->lock = 0;
|
|
|
|
__asm__ volatile(
|
|
"int $0x40\t"
|
|
:"=a"(handle)
|
|
:"a"(77),"b"(FUTEX_INIT),"c"(mutex));
|
|
mutex->handle = handle;
|
|
|
|
return handle;
|
|
};
|
|
|
|
static inline int mutex_destroy(mutex_t *mutex)
|
|
{
|
|
int retval;
|
|
|
|
__asm__ volatile(
|
|
"int $0x40\t"
|
|
:"=a"(retval)
|
|
:"a"(77),"b"(FUTEX_DESTROY),"c"(mutex->handle));
|
|
|
|
return retval;
|
|
};
|
|
|
|
static inline void mutex_lock(mutex_t *mutex)
|
|
{
|
|
int tmp;
|
|
|
|
if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
|
|
return;
|
|
|
|
while (exchange_acquire (&mutex->lock, 2) != 0)
|
|
{
|
|
__asm__ volatile(
|
|
"int $0x40\t\n"
|
|
:"=a"(tmp)
|
|
:"a"(77),"b"(FUTEX_WAIT),
|
|
"c"(mutex->handle),"d"(2),"S"(0));
|
|
}
|
|
};
|
|
|
|
static inline int mutex_lock_timeout(mutex_t *mutex, int timeout)
|
|
{
|
|
int tmp = 0;
|
|
|
|
if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
|
|
return 1;
|
|
|
|
while (exchange_acquire (&mutex->lock, 2) != 0)
|
|
{
|
|
__asm__ __volatile__(
|
|
"int $0x40\t"
|
|
:"=a"(tmp)
|
|
:"a"(77),"b"(FUTEX_WAIT),
|
|
"c"(mutex->handle),"d"(2),"S"(timeout));
|
|
|
|
if(++tmp == 0)
|
|
break;
|
|
}
|
|
return tmp ;
|
|
};
|
|
|
|
static inline int mutex_trylock (mutex_t *mutex)
|
|
{
|
|
int zero = 0;
|
|
|
|
return __atomic_compare_exchange_4(&mutex->lock, &zero, 1,0,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED);
|
|
};
|
|
|
|
static inline void mutex_unlock(mutex_t *mutex)
|
|
{
|
|
int prev;
|
|
|
|
prev = exchange_release (&mutex->lock, 0);
|
|
|
|
if (prev != 1)
|
|
{
|
|
__asm__ volatile(
|
|
"int $0x40\t"
|
|
:"=a"(prev)
|
|
:"a"(77),"b"(FUTEX_WAKE),
|
|
"c"(mutex->handle),"d"(1));
|
|
};
|
|
};
|
|
|
|
#endif
|