1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * spin.h |
4 | * Hardware-independent implementation of spinlocks. |
5 | * |
6 | * |
7 | * The hardware-independent interface to spinlocks is defined by the |
8 | * typedef "slock_t" and these macros: |
9 | * |
10 | * void SpinLockInit(volatile slock_t *lock) |
11 | * Initialize a spinlock (to the unlocked state). |
12 | * |
13 | * void SpinLockAcquire(volatile slock_t *lock) |
14 | * Acquire a spinlock, waiting if necessary. |
15 | * Time out and abort() if unable to acquire the lock in a |
16 | * "reasonable" amount of time --- typically ~ 1 minute. |
17 | * |
18 | * void SpinLockRelease(volatile slock_t *lock) |
19 | * Unlock a previously acquired lock. |
20 | * |
21 | * bool SpinLockFree(slock_t *lock) |
22 | * Tests if the lock is free. Returns true if free, false if locked. |
23 | * This does *not* change the state of the lock. |
24 | * |
25 | * Callers must beware that the macro argument may be evaluated multiple |
26 | * times! |
27 | * |
28 | * Load and store operations in calling code are guaranteed not to be |
29 | * reordered with respect to these operations, because they include a |
30 | * compiler barrier. (Before PostgreSQL 9.5, callers needed to use a |
31 | * volatile qualifier to access data protected by spinlocks.) |
32 | * |
33 | * Keep in mind the coding rule that spinlocks must not be held for more |
34 | * than a few instructions. In particular, we assume it is not possible |
35 | * for a CHECK_FOR_INTERRUPTS() to occur while holding a spinlock, and so |
36 | * it is not necessary to do HOLD/RESUME_INTERRUPTS() in these macros. |
37 | * |
38 | * These macros are implemented in terms of hardware-dependent macros |
39 | * supplied by s_lock.h. There is not currently any extra functionality |
40 | * added by this header, but there has been in the past and may someday |
41 | * be again. |
42 | * |
43 | * |
44 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
45 | * Portions Copyright (c) 1994, Regents of the University of California |
46 | * |
47 | * src/include/storage/spin.h |
48 | * |
49 | *------------------------------------------------------------------------- |
50 | */ |
51 | #ifndef SPIN_H |
52 | #define SPIN_H |
53 | |
54 | #include "storage/s_lock.h" |
55 | #ifndef HAVE_SPINLOCKS |
56 | #include "storage/pg_sema.h" |
57 | #endif |
58 | |
59 | |
60 | #define SpinLockInit(lock) S_INIT_LOCK(lock) |
61 | |
62 | #define SpinLockAcquire(lock) S_LOCK(lock) |
63 | |
64 | #define SpinLockRelease(lock) S_UNLOCK(lock) |
65 | |
66 | #define SpinLockFree(lock) S_LOCK_FREE(lock) |
67 | |
68 | |
69 | extern int SpinlockSemas(void); |
70 | extern Size SpinlockSemaSize(void); |
71 | |
72 | #ifndef HAVE_SPINLOCKS |
73 | extern void SpinlockSemaInit(void); |
74 | extern PGSemaphore *SpinlockSemaArray; |
75 | #endif |
76 | |
77 | #endif /* SPIN_H */ |
78 | |