93#error "s_lock.h may not be included from frontend code"
96#if defined(__GNUC__) || defined(__INTEL_COMPILER)
127#define HAS_TEST_AND_SET
129typedef unsigned char slock_t;
131#define TAS(lock) tas(lock)
134tas(
volatile slock_t *lock)
149 __asm__ __volatile__(
155:
"+q"(_res),
"+m"(*lock)
161#define SPIN_DELAY() spin_delay()
163static __inline__
void
189 __asm__ __volatile__(
197#define HAS_TEST_AND_SET
199typedef unsigned char slock_t;
201#define TAS(lock) tas(lock)
212#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
215tas(
volatile slock_t *lock)
219 __asm__ __volatile__(
222:
"+q"(_res),
"+m"(*lock)
228#define SPIN_DELAY() spin_delay()
230static __inline__
void
237 __asm__ __volatile__(
250#if defined(__arm__) || defined(__arm) || defined(__aarch64__)
251#ifdef HAVE_GCC__SYNC_INT32_TAS
252#define HAS_TEST_AND_SET
254#define TAS(lock) tas(lock)
259tas(
volatile slock_t *lock)
261 return __sync_lock_test_and_set(lock, 1);
264#define S_UNLOCK(lock) __sync_lock_release(lock)
266#if defined(__aarch64__)
272#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
274#define SPIN_DELAY() spin_delay()
276static __inline__
void
284 __asm__ __volatile__(
294#if defined(__s390__) || defined(__s390x__)
295#define HAS_TEST_AND_SET
297typedef unsigned int slock_t;
299#define TAS(lock) tas(lock)
302tas(
volatile slock_t *lock)
306 __asm__ __volatile__(
308:
"+d"(_res),
"+m"(*lock)
317#if defined(__sparc__)
324#define HAS_TEST_AND_SET
326typedef unsigned char slock_t;
328#define TAS(lock) tas(lock)
331tas(
volatile slock_t *lock)
340 __asm__ __volatile__(
341 " ldstub [%2], %0 \n"
342:
"=r"(_res),
"+m"(*lock)
345#if defined(__sparcv7) || defined(__sparc_v7__)
350#elif defined(__sparcv8) || defined(__sparc_v8__)
352 __asm__ __volatile__ (
"stbar \n":::
"memory");
358 __asm__ __volatile__ (
"membar #LoadStore | #LoadLoad \n":::
"memory");
363#if defined(__sparcv7) || defined(__sparc_v7__)
369#elif defined(__sparcv8) || defined(__sparc_v8__)
371#define S_UNLOCK(lock) \
374 __asm__ __volatile__ ("stbar \n":::"memory"); \
375 *((volatile slock_t *) (lock)) = 0; \
382#define S_UNLOCK(lock) \
385 __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \
386 *((volatile slock_t *) (lock)) = 0; \
394#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
395#define HAS_TEST_AND_SET
397typedef unsigned int slock_t;
399#define TAS(lock) tas(lock)
402#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
416tas(
volatile slock_t *lock)
421 __asm__ __volatile__(
435:
"=&b"(_t),
"=r"(_res),
"+m"(*lock)
445#define S_UNLOCK(lock) \
448 __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
449 *((volatile slock_t *) (lock)) = 0; \
455#if defined(__mips__) && !defined(__sgi)
456#define HAS_TEST_AND_SET
458typedef unsigned int slock_t;
460#define TAS(lock) tas(lock)
476#define MIPS_SET_MIPS2 " .set mips2 \n"
478#define MIPS_SET_MIPS2
482tas(
volatile slock_t *lock)
484 volatile slock_t *_l = lock;
488 __asm__ __volatile__(
500:
"=&r" (_res),
"=&r" (_tmp),
"+R" (*_l)
507#define S_UNLOCK(lock) \
510 __asm__ __volatile__( \
513 " .set noreorder \n" \
520 *((volatile slock_t *) (lock)) = 0; \
534#if !defined(HAS_TEST_AND_SET)
536#if defined(HAVE_GCC__SYNC_INT32_TAS)
537#define HAS_TEST_AND_SET
539#define TAS(lock) tas(lock)
544tas(
volatile slock_t *lock)
546 return __sync_lock_test_and_set(lock, 1);
549#define S_UNLOCK(lock) __sync_lock_release(lock)
551#elif defined(HAVE_GCC__SYNC_CHAR_TAS)
552#define HAS_TEST_AND_SET
554#define TAS(lock) tas(lock)
559tas(
volatile slock_t *lock)
561 return __sync_lock_test_and_set(lock, 1);
564#define S_UNLOCK(lock) __sync_lock_release(lock)
581#if !defined(S_UNLOCK)
582#define S_UNLOCK(lock) \
583 do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0)
595#if !defined(HAS_TEST_AND_SET)
599#if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
600#define HAS_TEST_AND_SET
602#if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
603typedef unsigned int slock_t;
605typedef unsigned char slock_t;
608extern slock_t pg_atomic_cas(
volatile slock_t *lock, slock_t with,
611#define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
618#define HAS_TEST_AND_SET
619#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
621#define SPIN_DELAY() spin_delay()
627static __forceinline
void
633static __forceinline
void
642#pragma intrinsic(_ReadWriteBarrier)
644#define S_UNLOCK(lock) \
645 do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
654#ifndef HAS_TEST_AND_SET
655#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.
664#define S_LOCK(lock) \
665 (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
668#if !defined(S_LOCK_FREE)
669#define S_LOCK_FREE(lock) (*(lock) == 0)
672#if !defined(S_UNLOCK)
689#define USE_DEFAULT_S_UNLOCK
690extern void s_unlock(
volatile slock_t *lock);
691#define S_UNLOCK(lock) s_unlock(lock)
694#if !defined(S_INIT_LOCK)
695#define S_INIT_LOCK(lock) S_UNLOCK(lock)
698#if !defined(SPIN_DELAY)
699#define SPIN_DELAY() ((void) 0)
703extern int tas(
volatile slock_t *lock);
706#define TAS(lock) tas(lock)
709#if !defined(TAS_SPIN)
710#define TAS_SPIN(lock) TAS(lock)
717extern int s_lock(
volatile slock_t *lock,
const char *file,
int line,
const char *func);
720#define DEFAULT_SPINS_PER_DELAY 100
741 const char *file,
int line,
const char *func)
751#define init_local_spin_delay(status) init_spin_delay(status, __FILE__, __LINE__, __func__)
static int cmp(const chr *x, const chr *y, size_t len)
void set_spins_per_delay(int shared_spins_per_delay)
void perform_spin_delay(SpinDelayStatus *status)
int tas(volatile slock_t *lock)
static void init_spin_delay(SpinDelayStatus *status, const char *file, int line, const char *func)
void finish_spin_delay(SpinDelayStatus *status)
int s_lock(volatile slock_t *lock, const char *file, int line, const char *func)
void s_unlock(volatile slock_t *lock)
int update_spins_per_delay(int shared_spins_per_delay)