100 #error "s_lock.h may not be included from frontend code"
103 #ifdef HAVE_SPINLOCKS
105 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
136 #define HAS_TEST_AND_SET
140 #define TAS(lock) tas(lock)
142 static __inline__
int
158 __asm__ __volatile__(
164 :
"+q"(_res),
"+m"(*lock)
170 #define SPIN_DELAY() spin_delay()
172 static __inline__
void
198 __asm__ __volatile__(
206 #define HAS_TEST_AND_SET
210 #define TAS(lock) tas(lock)
221 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
223 static __inline__
int
228 __asm__ __volatile__(
231 :
"+q"(_res),
"+m"(*lock)
237 #define SPIN_DELAY() spin_delay()
239 static __inline__
void
246 __asm__ __volatile__(
259 #if defined(__arm__) || defined(__arm) || defined(__aarch64__)
260 #ifdef HAVE_GCC__SYNC_INT32_TAS
261 #define HAS_TEST_AND_SET
263 #define TAS(lock) tas(lock)
267 static __inline__
int
270 return __sync_lock_test_and_set(lock, 1);
273 #define S_UNLOCK(lock) __sync_lock_release(lock)
280 #if defined(__aarch64__)
282 #define SPIN_DELAY() spin_delay()
284 static __inline__
void
287 __asm__ __volatile__(
297 #if defined(__s390__) || defined(__s390x__)
298 #define HAS_TEST_AND_SET
302 #define TAS(lock) tas(lock)
304 static __inline__
int
309 __asm__ __volatile__(
311 :
"+d"(_res),
"+m"(*lock)
320 #if defined(__sparc__)
327 #define HAS_TEST_AND_SET
331 #define TAS(lock) tas(lock)
333 static __inline__
int
343 __asm__ __volatile__(
344 " ldstub [%2], %0 \n"
345 :
"=r"(_res),
"+m"(*lock)
348 #if defined(__sparcv7) || defined(__sparc_v7__)
353 #elif defined(__sparcv8) || defined(__sparc_v8__)
355 __asm__ __volatile__ (
"stbar \n":::
"memory");
361 __asm__ __volatile__ (
"membar #LoadStore | #LoadLoad \n":::
"memory");
366 #if defined(__sparcv7) || defined(__sparc_v7__)
372 #elif defined(__sparcv8) || defined(__sparc_v8__)
374 #define S_UNLOCK(lock) \
377 __asm__ __volatile__ ("stbar \n":::"memory"); \
378 *((volatile slock_t *) (lock)) = 0; \
385 #define S_UNLOCK(lock) \
388 __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \
389 *((volatile slock_t *) (lock)) = 0; \
397 #if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
398 #define HAS_TEST_AND_SET
402 #define TAS(lock) tas(lock)
405 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
418 static __inline__
int
424 __asm__ __volatile__(
425 " lwarx %0,0,%3,1 \n"
438 :
"=&b"(_t),
"=r"(_res),
"+m"(*lock)
448 #define S_UNLOCK(lock) \
451 __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
452 *((volatile slock_t *) (lock)) = 0; \
458 #if defined(__mips__) && !defined(__sgi)
459 #define HAS_TEST_AND_SET
463 #define TAS(lock) tas(lock)
479 #define MIPS_SET_MIPS2 " .set mips2 \n"
481 #define MIPS_SET_MIPS2
484 static __inline__
int
491 __asm__ __volatile__(
503 :
"=&r" (_res),
"=&r" (_tmp),
"+R" (*_l)
510 #define S_UNLOCK(lock) \
513 __asm__ __volatile__( \
516 " .set noreorder \n" \
523 *((volatile slock_t *) (lock)) = 0; \
529 #if defined(__hppa) || defined(__hppa__)
537 #define HAS_TEST_AND_SET
544 #define TAS_ACTIVE_WORD(lock) ((volatile int *) (((uintptr_t) (lock) + 15) & ~15))
546 static __inline__
int
549 volatile int *lockword = TAS_ACTIVE_WORD(lock);
567 __asm__ __volatile__(
568 " ldcwx 0(0,%2),%0 \n"
569 :
"=r"(lockval),
"+m"(*lockword)
572 return (lockval == 0);
575 #define S_UNLOCK(lock) \
577 __asm__ __volatile__("" : : : "memory"); \
578 *TAS_ACTIVE_WORD(lock) = -1; \
581 #define S_INIT_LOCK(lock) \
583 volatile slock_t *lock_ = (lock); \
584 lock_->sema[0] = -1; \
585 lock_->sema[1] = -1; \
586 lock_->sema[2] = -1; \
587 lock_->sema[3] = -1; \
590 #define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
602 #if !defined(HAS_TEST_AND_SET)
604 #if defined(HAVE_GCC__SYNC_INT32_TAS)
605 #define HAS_TEST_AND_SET
607 #define TAS(lock) tas(lock)
611 static __inline__
int
614 return __sync_lock_test_and_set(lock, 1);
617 #define S_UNLOCK(lock) __sync_lock_release(lock)
619 #elif defined(HAVE_GCC__SYNC_CHAR_TAS)
620 #define HAS_TEST_AND_SET
622 #define TAS(lock) tas(lock)
626 static __inline__
int
629 return __sync_lock_test_and_set(lock, 1);
632 #define S_UNLOCK(lock) __sync_lock_release(lock)
649 #if !defined(S_UNLOCK)
650 #define S_UNLOCK(lock) \
651 do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0)
663 #if !defined(HAS_TEST_AND_SET)
667 #if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
668 #define HAS_TEST_AND_SET
670 #if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
679 #define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
686 #define HAS_TEST_AND_SET
687 #define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
689 #define SPIN_DELAY() spin_delay()
695 static __forceinline
void
701 static __forceinline
void
710 #pragma intrinsic(_ReadWriteBarrier)
712 #define S_UNLOCK(lock) \
713 do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
722 #ifndef HAS_TEST_AND_SET
723 #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@lists.postgresql.org.
742 #define S_LOCK_FREE(lock) s_lock_free_sema(lock)
743 #define S_UNLOCK(lock) s_unlock_sema(lock)
744 #define S_INIT_LOCK(lock) s_init_lock_sema(lock, false)
745 #define TAS(lock) tas_sema(lock)
756 #define S_LOCK(lock) \
757 (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
760 #if !defined(S_LOCK_FREE)
761 #define S_LOCK_FREE(lock) (*(lock) == 0)
764 #if !defined(S_UNLOCK)
781 #define USE_DEFAULT_S_UNLOCK
782 extern void s_unlock(
volatile slock_t *lock);
783 #define S_UNLOCK(lock) s_unlock(lock)
786 #if !defined(S_INIT_LOCK)
787 #define S_INIT_LOCK(lock) S_UNLOCK(lock)
790 #if !defined(SPIN_DELAY)
791 #define SPIN_DELAY() ((void) 0)
795 extern int tas(
volatile slock_t *lock);
798 #define TAS(lock) tas(lock)
801 #if !defined(TAS_SPIN)
802 #define TAS_SPIN(lock) TAS(lock)
809 extern int s_lock(
volatile slock_t *lock,
const char *file,
int line,
const char *func);
812 #define DEFAULT_SPINS_PER_DELAY 100
833 const char *file,
int line,
const char *func)
843 #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_sema(volatile slock_t *lock)
void s_unlock_sema(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_init_lock_sema(volatile slock_t *lock, bool nested)
int update_spins_per_delay(int shared_spins_per_delay)
bool s_lock_free_sema(volatile slock_t *lock)