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
224 tas(
volatile slock_t *lock)
226 register slock_t _res = 1;
228 __asm__ __volatile__(
231 :
"+q"(_res),
"+m"(*lock)
237 #define SPIN_DELAY() spin_delay()
239 static __inline__
void
246 __asm__ __volatile__(
253 #if defined(__ia64__) || defined(__ia64)
274 #define HAS_TEST_AND_SET
278 #define TAS(lock) tas(lock)
281 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
283 #ifndef __INTEL_COMPILER
285 static __inline__
int
286 tas(
volatile slock_t *lock)
290 __asm__ __volatile__(
292 :
"=r"(ret),
"+m"(*lock)
300 static __inline__
int
301 tas(
volatile slock_t *lock)
305 ret = _InterlockedExchange(lock,1);
311 #define S_UNLOCK(lock) \
312 do { __memory_barrier(); *(lock) = 0; } while (0)
323 #if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64)
324 #ifdef HAVE_GCC__SYNC_INT32_TAS
325 #define HAS_TEST_AND_SET
327 #define TAS(lock) tas(lock)
331 static __inline__
int
332 tas(
volatile slock_t *lock)
334 return __sync_lock_test_and_set(lock, 1);
337 #define S_UNLOCK(lock) __sync_lock_release(lock)
344 #if defined(__s390__) || defined(__s390x__)
345 #define HAS_TEST_AND_SET
349 #define TAS(lock) tas(lock)
351 static __inline__
int
352 tas(
volatile slock_t *lock)
356 __asm__ __volatile__(
358 :
"+d"(_res),
"+m"(*lock)
367 #if defined(__sparc__)
374 #define HAS_TEST_AND_SET
378 #define TAS(lock) tas(lock)
380 static __inline__
int
381 tas(
volatile slock_t *lock)
383 register slock_t _res;
390 __asm__ __volatile__(
391 " ldstub [%2], %0 \n"
392 :
"=r"(_res),
"+m"(*lock)
395 #if defined(__sparcv7) || defined(__sparc_v7__)
400 #elif defined(__sparcv8) || defined(__sparc_v8__)
402 __asm__ __volatile__ (
"stbar \n":::
"memory");
408 __asm__ __volatile__ (
"membar #LoadStore | #LoadLoad \n":::
"memory");
413 #if defined(__sparcv7) || defined(__sparc_v7__)
419 #elif defined(__sparcv8) || defined(__sparc_v8__)
421 #define S_UNLOCK(lock) \
424 __asm__ __volatile__ ("stbar \n":::"memory"); \
425 *((volatile slock_t *) (lock)) = 0; \
432 #define S_UNLOCK(lock) \
435 __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \
436 *((volatile slock_t *) (lock)) = 0; \
444 #if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
445 #define HAS_TEST_AND_SET
449 #define TAS(lock) tas(lock)
452 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
465 static __inline__
int
466 tas(
volatile slock_t *lock)
471 __asm__ __volatile__(
472 #ifdef USE_PPC_LWARX_MUTEX_HINT
473 " lwarx %0,0,%3,1 \n"
484 #ifdef USE_PPC_LWSYNC
491 :
"=&r"(_t),
"=r"(_res),
"+m"(*lock)
501 #ifdef USE_PPC_LWSYNC
502 #define S_UNLOCK(lock) \
505 __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
506 *((volatile slock_t *) (lock)) = 0; \
509 #define S_UNLOCK(lock) \
512 __asm__ __volatile__ (" sync \n" ::: "memory"); \
513 *((volatile slock_t *) (lock)) = 0; \
521 #if (defined(__mc68000__) || defined(__m68k__)) && defined(__linux__)
522 #define HAS_TEST_AND_SET
526 #define TAS(lock) tas(lock)
528 static __inline__
int
529 tas(
volatile slock_t *lock)
533 __asm__ __volatile__(
537 :
"=d"(rv),
"+m"(*lock)
551 #define HAS_TEST_AND_SET
555 #define TAS(lock) tas(lock)
557 static __inline__
int
558 tas(
volatile slock_t *lock)
562 __asm__ __volatile__(
564 " bbssi $0, (%2), 1f \n"
567 :
"=&r"(_res),
"+m"(*lock)
576 #if defined(__mips__) && !defined(__sgi)
579 #define HAS_TEST_AND_SET
583 #define TAS(lock) tas(lock)
585 static __inline__
int
586 tas(
volatile slock_t *lock)
588 register volatile slock_t *_l = lock;
592 __asm__ __volatile__(
604 :
"=&r" (_res),
"=&r" (_tmp),
"+R" (*_l)
611 #define S_UNLOCK(lock) \
614 __asm__ __volatile__( \
617 " .set noreorder \n" \
624 *((volatile slock_t *) (lock)) = 0; \
630 #if defined(__m32r__) && defined(HAVE_SYS_TAS_H)
631 #define HAS_TEST_AND_SET
637 #define TAS(lock) tas(lock)
643 #define HAS_TEST_AND_SET
647 #define TAS(lock) tas(lock)
649 static __inline__
int
650 tas(
volatile slock_t *lock)
659 __asm__ __volatile__(
663 :
"=z"(_res),
"+m"(*lock)
675 #if defined(__m68k__) && !defined(__linux__)
676 #define HAS_TEST_AND_SET
691 #if !defined(S_UNLOCK)
692 #define S_UNLOCK(lock) \
693 do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0)
706 #if !defined(HAS_TEST_AND_SET)
709 #if defined(USE_UNIVEL_CC)
710 #define HAS_TEST_AND_SET
714 #define TAS(lock) tas(lock)
717 tas(
volatile slock_t *
s_lock)
732 #
if defined(__hppa) || defined(__hppa__)
743 #define HAS_TEST_AND_SET
750 #define TAS_ACTIVE_WORD(lock) ((volatile int *) (((uintptr_t) (lock) + 15) & ~15))
752 #if defined(__GNUC__)
754 static __inline__
int
755 tas(
volatile slock_t *lock)
757 volatile int *lockword = TAS_ACTIVE_WORD(lock);
758 register int lockval;
760 __asm__ __volatile__(
761 " ldcwx 0(0,%2),%0 \n"
762 :
"=r"(lockval),
"+m"(*lockword)
765 return (lockval == 0);
777 #define S_UNLOCK(lock) \
779 __asm__ __volatile__("" : : : "memory"); \
780 *TAS_ACTIVE_WORD(lock) = -1; \
785 #define S_INIT_LOCK(lock) \
787 volatile slock_t *lock_ = (lock); \
788 lock_->sema[0] = -1; \
789 lock_->sema[1] = -1; \
790 lock_->sema[2] = -1; \
791 lock_->sema[3] = -1; \
794 #define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
799 #if defined(__hpux) && defined(__ia64) && !defined(__GNUC__)
813 #define HAS_TEST_AND_SET
817 #include <ia64/sys/inline.h>
818 #define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
820 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
821 #define S_UNLOCK(lock) \
822 do { _Asm_mf(); (*(lock)) = 0; } while (0)
830 #define HAS_TEST_AND_SET
832 #include <sys/atomic_op.h>
836 #define TAS(lock) _check_lock((slock_t *) (lock), 0, 1)
837 #define S_UNLOCK(lock) _clear_lock((slock_t *) (lock), 0)
843 #if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
844 #define HAS_TEST_AND_SET
846 #if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
852 extern slock_t pg_atomic_cas(
volatile slock_t *lock, slock_t with,
855 #define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
859 #ifdef WIN32_ONLY_COMPILER
862 #define HAS_TEST_AND_SET
863 #define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
865 #define SPIN_DELAY() spin_delay()
871 static __forceinline
void
877 static __forceinline
void
886 #pragma intrinsic(_ReadWriteBarrier)
888 #define S_UNLOCK(lock) \
889 do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
898 #ifndef HAS_TEST_AND_SET
899 #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 [email protected].
916 extern int tas_sema(
volatile slock_t *lock);
918 #define S_LOCK_FREE(lock) s_lock_free_sema(lock)
919 #define S_UNLOCK(lock) s_unlock_sema(lock)
920 #define S_INIT_LOCK(lock) s_init_lock_sema(lock, false)
921 #define TAS(lock) tas_sema(lock)
932 #define S_LOCK(lock) \
933 (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, PG_FUNCNAME_MACRO) : 0)
936 #if !defined(S_LOCK_FREE)
937 #define S_LOCK_FREE(lock) (*(lock) == 0)
940 #if !defined(S_UNLOCK)
957 #define USE_DEFAULT_S_UNLOCK
958 extern void s_unlock(
volatile slock_t *lock);
959 #define S_UNLOCK(lock) s_unlock(lock)
962 #if !defined(S_INIT_LOCK)
963 #define S_INIT_LOCK(lock) S_UNLOCK(lock)
966 #if !defined(SPIN_DELAY)
967 #define SPIN_DELAY() ((void) 0)
971 extern int tas(
volatile slock_t *lock);
974 #define TAS(lock) tas(lock)
977 #if !defined(TAS_SPIN)
978 #define TAS_SPIN(lock) TAS(lock)
986 extern int s_lock(
volatile slock_t *lock,
const char *file,
int line,
const char *func);
989 #define DEFAULT_SPINS_PER_DELAY 100
1010 const char *file,
int line,
const char *func)
1015 status->
file = file;
1016 status->
line = line;
1017 status->
func = func;
1020 #define init_local_spin_delay(status) init_spin_delay(status, __FILE__, __LINE__, PG_FUNCNAME_MACRO)
void s_init_lock_sema(volatile slock_t *lock, bool nested)
int update_spins_per_delay(int shared_spins_per_delay)
void perform_spin_delay(SpinDelayStatus *status)
int s_lock(volatile slock_t *lock, const char *file, int line, const char *func)
void finish_spin_delay(SpinDelayStatus *status)
int tas_sema(volatile slock_t *lock)
static void init_spin_delay(SpinDelayStatus *status, const char *file, int line, const char *func)
void s_unlock_sema(volatile slock_t *lock)
bool s_lock_free_sema(volatile slock_t *lock)
void set_spins_per_delay(int shared_spins_per_delay)
static void static void status(const char *fmt,...) pg_attribute_printf(1
static int cmp(const chr *x, const chr *y, size_t len)