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
129 typedef unsigned char slock_t;
131 #define TAS(lock) tas(lock)
133 static __inline__
int
134 tas(
volatile slock_t *lock)
149 __asm__ __volatile__(
155 :
"+q"(_res),
"+m"(*lock)
161 #define SPIN_DELAY() spin_delay()
163 static __inline__
void
189 __asm__ __volatile__(
197 #define HAS_TEST_AND_SET
199 typedef unsigned char slock_t;
201 #define TAS(lock) tas(lock)
212 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
214 static __inline__
int
215 tas(
volatile slock_t *lock)
219 __asm__ __volatile__(
222 :
"+q"(_res),
"+m"(*lock)
228 #define SPIN_DELAY() spin_delay()
230 static __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)
258 static __inline__
int
259 tas(
volatile slock_t *lock)
261 return __sync_lock_test_and_set(lock, 1);
264 #define S_UNLOCK(lock) __sync_lock_release(lock)
271 #if defined(__aarch64__)
273 #define SPIN_DELAY() spin_delay()
275 static __inline__
void
278 __asm__ __volatile__(
288 #if defined(__s390__) || defined(__s390x__)
289 #define HAS_TEST_AND_SET
291 typedef unsigned int slock_t;
293 #define TAS(lock) tas(lock)
295 static __inline__
int
296 tas(
volatile slock_t *lock)
300 __asm__ __volatile__(
302 :
"+d"(_res),
"+m"(*lock)
311 #if defined(__sparc__)
318 #define HAS_TEST_AND_SET
320 typedef unsigned char slock_t;
322 #define TAS(lock) tas(lock)
324 static __inline__
int
325 tas(
volatile slock_t *lock)
334 __asm__ __volatile__(
335 " ldstub [%2], %0 \n"
336 :
"=r"(_res),
"+m"(*lock)
339 #if defined(__sparcv7) || defined(__sparc_v7__)
344 #elif defined(__sparcv8) || defined(__sparc_v8__)
346 __asm__ __volatile__ (
"stbar \n":::
"memory");
352 __asm__ __volatile__ (
"membar #LoadStore | #LoadLoad \n":::
"memory");
357 #if defined(__sparcv7) || defined(__sparc_v7__)
363 #elif defined(__sparcv8) || defined(__sparc_v8__)
365 #define S_UNLOCK(lock) \
368 __asm__ __volatile__ ("stbar \n":::"memory"); \
369 *((volatile slock_t *) (lock)) = 0; \
376 #define S_UNLOCK(lock) \
379 __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \
380 *((volatile slock_t *) (lock)) = 0; \
388 #if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
389 #define HAS_TEST_AND_SET
391 typedef unsigned int slock_t;
393 #define TAS(lock) tas(lock)
396 #define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
409 static __inline__
int
410 tas(
volatile slock_t *lock)
415 __asm__ __volatile__(
416 " lwarx %0,0,%3,1 \n"
429 :
"=&b"(_t),
"=r"(_res),
"+m"(*lock)
439 #define S_UNLOCK(lock) \
442 __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
443 *((volatile slock_t *) (lock)) = 0; \
449 #if defined(__mips__) && !defined(__sgi)
450 #define HAS_TEST_AND_SET
452 typedef unsigned int slock_t;
454 #define TAS(lock) tas(lock)
470 #define MIPS_SET_MIPS2 " .set mips2 \n"
472 #define MIPS_SET_MIPS2
475 static __inline__
int
476 tas(
volatile slock_t *lock)
478 volatile slock_t *_l = lock;
482 __asm__ __volatile__(
494 :
"=&r" (_res),
"=&r" (_tmp),
"+R" (*_l)
501 #define S_UNLOCK(lock) \
504 __asm__ __volatile__( \
507 " .set noreorder \n" \
514 *((volatile slock_t *) (lock)) = 0; \
528 #if !defined(HAS_TEST_AND_SET)
530 #if defined(HAVE_GCC__SYNC_INT32_TAS)
531 #define HAS_TEST_AND_SET
533 #define TAS(lock) tas(lock)
537 static __inline__
int
538 tas(
volatile slock_t *lock)
540 return __sync_lock_test_and_set(lock, 1);
543 #define S_UNLOCK(lock) __sync_lock_release(lock)
545 #elif defined(HAVE_GCC__SYNC_CHAR_TAS)
546 #define HAS_TEST_AND_SET
548 #define TAS(lock) tas(lock)
550 typedef char slock_t;
552 static __inline__
int
553 tas(
volatile slock_t *lock)
555 return __sync_lock_test_and_set(lock, 1);
558 #define S_UNLOCK(lock) __sync_lock_release(lock)
575 #if !defined(S_UNLOCK)
576 #define S_UNLOCK(lock) \
577 do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0)
589 #if !defined(HAS_TEST_AND_SET)
593 #if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
594 #define HAS_TEST_AND_SET
596 #if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
597 typedef unsigned int slock_t;
599 typedef unsigned char slock_t;
602 extern slock_t pg_atomic_cas(
volatile slock_t *lock, slock_t with,
605 #define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
610 typedef LONG slock_t;
612 #define HAS_TEST_AND_SET
613 #define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
615 #define SPIN_DELAY() spin_delay()
621 static __forceinline
void
627 static __forceinline
void
636 #pragma intrinsic(_ReadWriteBarrier)
638 #define S_UNLOCK(lock) \
639 do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
648 #ifndef HAS_TEST_AND_SET
649 #error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.
658 #define S_LOCK(lock) \
659 (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
662 #if !defined(S_LOCK_FREE)
663 #define S_LOCK_FREE(lock) (*(lock) == 0)
666 #if !defined(S_UNLOCK)
683 #define USE_DEFAULT_S_UNLOCK
684 extern void s_unlock(
volatile slock_t *lock);
685 #define S_UNLOCK(lock) s_unlock(lock)
688 #if !defined(S_INIT_LOCK)
689 #define S_INIT_LOCK(lock) S_UNLOCK(lock)
692 #if !defined(SPIN_DELAY)
693 #define SPIN_DELAY() ((void) 0)
697 extern int tas(
volatile slock_t *lock);
700 #define TAS(lock) tas(lock)
703 #if !defined(TAS_SPIN)
704 #define TAS_SPIN(lock) TAS(lock)
711 extern int s_lock(
volatile slock_t *lock,
const char *file,
int line,
const char *func);
714 #define DEFAULT_SPINS_PER_DELAY 100
735 const char *file,
int line,
const char *func)
745 #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)