Skip to content

Commit 4039c73

Browse files
committed
Adjust spin.c's spinlock emulation so that 0 is not a valid spinlock value.
We've had repeated troubles over the years with failures to initialize spinlocks correctly; see 6b93fcd for a recent example. Most of the time, on most platforms, such oversights can escape notice because all-zeroes is the expected initial content of an slock_t variable. The only platform we have where the initialized state of an slock_t isn't zeroes is HPPA, and that's practically gone in the wild. To make it easier to catch such errors without needing one of those, adjust the --disable-spinlocks code so that zero is not a valid value for an slock_t for it. In passing, remove a bunch of unnecessary #include's from spin.c; commit daa7527 removed all the intermodule coupling that made them necessary.
1 parent 5fdda1c commit 4039c73

File tree

1 file changed

+22
-8
lines changed
  • src/backend/storage/lmgr

1 file changed

+22
-8
lines changed

src/backend/storage/lmgr/spin.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
*/
2323
#include "postgres.h"
2424

25-
#include "access/xlog.h"
26-
#include "miscadmin.h"
27-
#include "replication/walsender.h"
28-
#include "storage/lwlock.h"
2925
#include "storage/pg_sema.h"
3026
#include "storage/spin.h"
3127

@@ -85,21 +81,35 @@ SpinlockSemaInit(PGSemaphore spinsemas)
8581
}
8682

8783
/*
88-
* s_lock.h hardware-spinlock emulation
84+
* s_lock.h hardware-spinlock emulation using semaphores
85+
*
86+
* We map all spinlocks onto a set of NUM_SPINLOCK_SEMAPHORES semaphores.
87+
* It's okay to map multiple spinlocks onto one semaphore because no process
88+
* should ever hold more than one at a time. We just need enough semaphores
89+
* so that we aren't adding too much extra contention from that.
90+
*
91+
* slock_t is just an int for this implementation; it holds the spinlock
92+
* number from 1..NUM_SPINLOCK_SEMAPHORES. We intentionally ensure that 0
93+
* is not a valid value, so that testing with this code can help find
94+
* failures to initialize spinlocks.
8995
*/
9096

9197
void
9298
s_init_lock_sema(volatile slock_t *lock, bool nested)
9399
{
94100
static int counter = 0;
95101

96-
*lock = (++counter) % NUM_SPINLOCK_SEMAPHORES;
102+
*lock = ((++counter) % NUM_SPINLOCK_SEMAPHORES) + 1;
97103
}
98104

99105
void
100106
s_unlock_sema(volatile slock_t *lock)
101107
{
102-
PGSemaphoreUnlock(&SpinlockSemaArray[*lock]);
108+
int lockndx = *lock;
109+
110+
if (lockndx <= 0 || lockndx > NUM_SPINLOCK_SEMAPHORES)
111+
elog(ERROR, "invalid spinlock number: %d", lockndx);
112+
PGSemaphoreUnlock(&SpinlockSemaArray[lockndx - 1]);
103113
}
104114

105115
bool
@@ -113,8 +123,12 @@ s_lock_free_sema(volatile slock_t *lock)
113123
int
114124
tas_sema(volatile slock_t *lock)
115125
{
126+
int lockndx = *lock;
127+
128+
if (lockndx <= 0 || lockndx > NUM_SPINLOCK_SEMAPHORES)
129+
elog(ERROR, "invalid spinlock number: %d", lockndx);
116130
/* Note that TAS macros return 0 if *success* */
117-
return !PGSemaphoreTryLock(&SpinlockSemaArray[*lock]);
131+
return !PGSemaphoreTryLock(&SpinlockSemaArray[lockndx - 1]);
118132
}
119133

120134
#endif /* !HAVE_SPINLOCKS */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy