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))
424 static __inline__
int
430 __asm__ __volatile__(
431 " lwarx %0,0,%3,1 \n"
442 :
"=&b"(_t),
"=r"(_res),
"+m"(*lock)
452 #define S_UNLOCK(lock) \
455 __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
456 *((volatile slock_t *) (lock)) = 0; \
462 #if defined(__mips__) && !defined(__sgi)
463 #define HAS_TEST_AND_SET
467 #define TAS(lock) tas(lock)
483 #define MIPS_SET_MIPS2 " .set mips2 \n"
485 #define MIPS_SET_MIPS2
488 static __inline__
int
495 __asm__ __volatile__(
507 :
"=&r" (_res),
"=&r" (_tmp),
"+R" (*_l)
514 #define S_UNLOCK(lock) \
517 __asm__ __volatile__( \
520 " .set noreorder \n" \
527 *((volatile slock_t *) (lock)) = 0; \
533 #if defined(__hppa) || defined(__hppa__)
541 #define HAS_TEST_AND_SET
548 #define TAS_ACTIVE_WORD(lock) ((volatile int *) (((uintptr_t) (lock) + 15) & ~15))
550 static __inline__
int
553 volatile int *lockword = TAS_ACTIVE_WORD(lock);
571 __asm__ __volatile__(
572 " ldcwx 0(0,%2),%0 \n"
573 :
"=r"(lockval),
"+m"(*lockword)
576 return (lockval == 0);
579 #define S_UNLOCK(lock) \
581 __asm__ __volatile__("" : : : "memory"); \
582 *TAS_ACTIVE_WORD(lock) = -1; \
585 #define S_INIT_LOCK(lock) \
587 volatile slock_t *lock_ = (lock); \
588 lock_->sema[0] = -1; \
589 lock_->sema[1] = -1; \
590 lock_->sema[2] = -1; \
591 lock_->sema[3] = -1; \
594 #define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
606 #if !defined(HAS_TEST_AND_SET)
608 #if defined(HAVE_GCC__SYNC_INT32_TAS)
609 #define HAS_TEST_AND_SET
611 #define TAS(lock) tas(lock)
615 static __inline__
int
618 return __sync_lock_test_and_set(lock, 1);
621 #define S_UNLOCK(lock) __sync_lock_release(lock)
623 #elif defined(HAVE_GCC__SYNC_CHAR_TAS)
624 #define HAS_TEST_AND_SET
626 #define TAS(lock) tas(lock)
630 static __inline__
int
633 return __sync_lock_test_and_set(lock, 1);
636 #define S_UNLOCK(lock) __sync_lock_release(lock)
653 #if !defined(S_UNLOCK)
654 #define S_UNLOCK(lock) \
655 do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0)
667 #if !defined(HAS_TEST_AND_SET)
673 #define HAS_TEST_AND_SET
675 #include <sys/atomic_op.h>
679 #define TAS(lock) _check_lock((slock_t *) (lock), 0, 1)
680 #define S_UNLOCK(lock) _clear_lock((slock_t *) (lock), 0)
686 #if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
687 #define HAS_TEST_AND_SET
689 #if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
698 #define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
705 #define HAS_TEST_AND_SET
706 #define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
708 #define SPIN_DELAY() spin_delay()
714 static __forceinline
void
720 static __forceinline
void
729 #pragma intrinsic(_ReadWriteBarrier)
731 #define S_UNLOCK(lock) \
732 do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
741 #ifndef HAS_TEST_AND_SET
742 #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.
761 #define S_LOCK_FREE(lock) s_lock_free_sema(lock)
762 #define S_UNLOCK(lock) s_unlock_sema(lock)
763 #define S_INIT_LOCK(lock) s_init_lock_sema(lock, false)
764 #define TAS(lock) tas_sema(lock)
775 #define S_LOCK(lock) \
776 (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
779 #if !defined(S_LOCK_FREE)
780 #define S_LOCK_FREE(lock) (*(lock) == 0)
783 #if !defined(S_UNLOCK)
800 #define USE_DEFAULT_S_UNLOCK
801 extern void s_unlock(
volatile slock_t *lock);
802 #define S_UNLOCK(lock) s_unlock(lock)
805 #if !defined(S_INIT_LOCK)
806 #define S_INIT_LOCK(lock) S_UNLOCK(lock)
809 #if !defined(SPIN_DELAY)
810 #define SPIN_DELAY() ((void) 0)
814 extern int tas(
volatile slock_t *lock);
817 #define TAS(lock) tas(lock)
820 #if !defined(TAS_SPIN)
821 #define TAS_SPIN(lock) TAS(lock)
829 extern int s_lock(
volatile slock_t *lock,
const char *file,
int line,
const char *func);
832 #define DEFAULT_SPINS_PER_DELAY 100
853 const char *file,
int line,
const char *func)
863 #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)
PGDLLIMPORT slock_t dummy_spinlock
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)