renaming some OPTYap files in order to have a more consistent name organization
This commit is contained in:
127
OPTYap/locks_x86.h
Normal file
127
OPTYap/locks_x86.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/************************************************************************
|
||||
** **
|
||||
** The YapTab/YapOr/OPTYap systems **
|
||||
** **
|
||||
** YapTab extends the Yap Prolog engine to support sequential tabling **
|
||||
** YapOr extends the Yap Prolog engine to support or-parallelism **
|
||||
** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
|
||||
** **
|
||||
** **
|
||||
** Yap Prolog was developed at University of Porto, Portugal **
|
||||
** **
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
** Atomic locks for X86 **
|
||||
************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int lock;
|
||||
} spinlock_t;
|
||||
|
||||
static inline int
|
||||
spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
char tmp = 1;
|
||||
__asm__ __volatile__(
|
||||
"xchgb %b0, %1"
|
||||
: "=q"(tmp), "=m"(lock->lock)
|
||||
: "0"(tmp) : "memory");
|
||||
return tmp == 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
/* To unlock we move 0 to the lock.
|
||||
* On i386 this needs to be a locked operation
|
||||
* to avoid Pentium Pro errata 66 and 92.
|
||||
*/
|
||||
#if defined(__x86_64__)
|
||||
__asm__ __volatile__("" : : : "memory");
|
||||
*(unsigned char*)&lock->lock = 0;
|
||||
#else
|
||||
char tmp = 0;
|
||||
__asm__ __volatile__(
|
||||
"xchgb %b0, %1"
|
||||
: "=q"(tmp), "=m"(lock->lock)
|
||||
: "0"(tmp) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TRY_LOCK(LOCK_VAR) spin_trylock((spinlock_t *)(LOCK_VAR))
|
||||
|
||||
#define INIT_LOCK(LOCK_VAR) ((LOCK_VAR) = 0)
|
||||
#define LOCK(LOCK_VAR) do { \
|
||||
if (TRY_LOCK(&(LOCK_VAR))) break; \
|
||||
while (IS_LOCKED(LOCK_VAR)) continue; \
|
||||
} while (1)
|
||||
#define IS_LOCKED(LOCK_VAR) ((LOCK_VAR) != 0)
|
||||
#define IS_UNLOCKED(LOCK_VAR) ((LOCK_VAR) == 0)
|
||||
#define UNLOCK(LOCK_VAR) spin_unlock((spinlock_t *)&(LOCK_VAR))
|
||||
|
||||
/* This code has been copied from the sources of the Linux kernel */
|
||||
|
||||
/*
|
||||
* On x86, we implement read-write locks as a 32-bit counter
|
||||
* with the high bit (sign) being the "contended" bit.
|
||||
*
|
||||
* The inline assembly is non-obvious. Think about it.
|
||||
*
|
||||
* Changed to use the same technique as rw semaphores. See
|
||||
* semaphore.h for details. -ben
|
||||
*/
|
||||
/* the spinlock helpers are in arch/i386/kernel/semaphore.S */
|
||||
|
||||
typedef struct { unsigned long a[100]; } __dummy_lock_t;
|
||||
#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
|
||||
|
||||
typedef struct { volatile unsigned int lock; } rwlock_t;
|
||||
|
||||
#define RW_LOCK_BIAS 0x01000000
|
||||
#define RW_LOCK_BIAS_STR "0x01000000"
|
||||
|
||||
#define RW_LOCK_UNLOCKED RW_LOCK_BIAS
|
||||
|
||||
#define __build_read_lock(rw, helper) \
|
||||
asm volatile("lock\n" \
|
||||
"subl $1,(%0)\n\t" \
|
||||
"js 2f\n" \
|
||||
"1:\n" \
|
||||
".section .text.lock,\"ax\"\n" \
|
||||
"2:\tcall __read_lock_failed\n\t" \
|
||||
"jmp 1b\n" \
|
||||
".previous" \
|
||||
::"a" (rw) : "memory")
|
||||
|
||||
#define __build_write_lock(rw, helper) \
|
||||
asm volatile("lock\n"\
|
||||
"subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
|
||||
"jnz 2f\n" \
|
||||
"1:\n" \
|
||||
".section .text.lock,\"ax\"\n" \
|
||||
"2:\tcall __write_lock_failed\n\t" \
|
||||
"jmp 1b\n" \
|
||||
".previous" \
|
||||
::"a" (rw) : "memory")
|
||||
|
||||
static inline void read_lock(rwlock_t *rw)
|
||||
{
|
||||
__build_read_lock(rw, "__read_lock_failed");
|
||||
}
|
||||
|
||||
static inline void write_lock(rwlock_t *rw)
|
||||
{
|
||||
__build_write_lock(rw, "__write_lock_failed");
|
||||
}
|
||||
|
||||
|
||||
#define READ_LOCK(X) read_lock(&(X))
|
||||
#define WRITE_LOCK(X) write_lock(&(X))
|
||||
|
||||
#define READ_UNLOCK(rw) asm volatile("lock ; incl %0" :"=m" (__dummy_lock(&(rw))))
|
||||
#define WRITE_UNLOCK(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" (__dummy_lock(&(rw))))
|
||||
|
||||
#define INIT_RWLOCK(RW) (RW).lock = RW_LOCK_UNLOCKED
|
||||
|
||||
|
||||
Reference in New Issue
Block a user