PostgreSQL Source Code  git master
spin.c File Reference
#include "postgres.h"
#include "storage/pg_sema.h"
#include "storage/shmem.h"
#include "storage/spin.h"
Include dependency graph for spin.c:

Go to the source code of this file.

Macros

#define NUM_EMULATION_SEMAPHORES   (NUM_SPINLOCK_SEMAPHORES + NUM_ATOMICS_SEMAPHORES)
 

Functions

Size SpinlockSemaSize (void)
 
int SpinlockSemas (void)
 
void SpinlockSemaInit (void)
 
static void s_check_valid (int lockndx)
 
void s_init_lock_sema (volatile slock_t *lock, bool nested)
 
void s_unlock_sema (volatile slock_t *lock)
 
bool s_lock_free_sema (volatile slock_t *lock)
 
int tas_sema (volatile slock_t *lock)
 

Variables

PGSemaphoreSpinlockSemaArray
 

Macro Definition Documentation

◆ NUM_EMULATION_SEMAPHORES

#define NUM_EMULATION_SEMAPHORES   (NUM_SPINLOCK_SEMAPHORES + NUM_ATOMICS_SEMAPHORES)

Definition at line 37 of file spin.c.

Referenced by s_check_valid(), SpinlockSemas(), and SpinlockSemaSize().

Function Documentation

◆ s_check_valid()

static void s_check_valid ( int  lockndx)
inlinestatic

Definition at line 114 of file spin.c.

References elog, ERROR, NUM_EMULATION_SEMAPHORES, and unlikely.

Referenced by s_init_lock_sema(), s_unlock_sema(), and tas_sema().

115 {
116  if (unlikely(lockndx <= 0 || lockndx > NUM_EMULATION_SEMAPHORES))
117  elog(ERROR, "invalid spinlock number: %d", lockndx);
118 }
#define NUM_EMULATION_SEMAPHORES
Definition: spin.c:37
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214
#define unlikely(x)
Definition: c.h:206

◆ s_init_lock_sema()

void s_init_lock_sema ( volatile slock_t lock,
bool  nested 
)

Definition at line 121 of file spin.c.

References idx(), NUM_ATOMICS_SEMAPHORES, NUM_SPINLOCK_SEMAPHORES, and s_check_valid().

Referenced by pg_atomic_init_flag_impl(), pg_atomic_init_u32_impl(), and pg_atomic_init_u64_impl().

122 {
123  static uint32 counter = 0;
124  uint32 offset;
125  uint32 sema_total;
126  uint32 idx;
127 
128  if (nested)
129  {
130  /*
131  * To allow nesting atomics inside spinlocked sections, use a
132  * different spinlock. See comment above.
133  */
134  offset = 1 + NUM_SPINLOCK_SEMAPHORES;
135  sema_total = NUM_ATOMICS_SEMAPHORES;
136  }
137  else
138  {
139  offset = 1;
140  sema_total = NUM_SPINLOCK_SEMAPHORES;
141  }
142 
143  idx = (counter++ % sema_total) + offset;
144 
145  /* double check we did things correctly */
146  s_check_valid(idx);
147 
148  *lock = idx;
149 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
static void s_check_valid(int lockndx)
Definition: spin.c:114
unsigned int uint32
Definition: c.h:367
#define NUM_ATOMICS_SEMAPHORES
#define NUM_SPINLOCK_SEMAPHORES

◆ s_lock_free_sema()

bool s_lock_free_sema ( volatile slock_t lock)

Definition at line 162 of file spin.c.

References elog, and ERROR.

163 {
164  /* We don't currently use S_LOCK_FREE anyway */
165  elog(ERROR, "spin.c does not support S_LOCK_FREE()");
166  return false;
167 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214

◆ s_unlock_sema()

void s_unlock_sema ( volatile slock_t lock)

Definition at line 152 of file spin.c.

References PGSemaphoreUnlock(), and s_check_valid().

153 {
154  int lockndx = *lock;
155 
156  s_check_valid(lockndx);
157 
158  PGSemaphoreUnlock(SpinlockSemaArray[lockndx - 1]);
159 }
void PGSemaphoreUnlock(PGSemaphore sema)
Definition: posix_sema.c:340
static void s_check_valid(int lockndx)
Definition: spin.c:114
PGSemaphore * SpinlockSemaArray
Definition: spin.c:42

◆ SpinlockSemaInit()

void SpinlockSemaInit ( void  )

Definition at line 77 of file spin.c.

References i, PGSemaphoreCreate(), ShmemAllocUnlocked(), SpinlockSemas(), and SpinlockSemaSize().

Referenced by CreateSharedMemoryAndSemaphores().

78 {
79  PGSemaphore *spinsemas;
80  int nsemas = SpinlockSemas();
81  int i;
82 
83  /*
84  * We must use ShmemAllocUnlocked(), since the spinlock protecting
85  * ShmemAlloc() obviously can't be ready yet.
86  */
88  for (i = 0; i < nsemas; ++i)
89  spinsemas[i] = PGSemaphoreCreate();
90  SpinlockSemaArray = spinsemas;
91 }
Size SpinlockSemaSize(void)
Definition: spin.c:55
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:262
int SpinlockSemas(void)
Definition: spin.c:64
void * ShmemAllocUnlocked(Size size)
Definition: shmem.c:247
int i
PGSemaphore * SpinlockSemaArray
Definition: spin.c:42

◆ SpinlockSemas()

int SpinlockSemas ( void  )

Definition at line 64 of file spin.c.

References NUM_EMULATION_SEMAPHORES.

Referenced by CreateSharedMemoryAndSemaphores(), and SpinlockSemaInit().

65 {
67 }
#define NUM_EMULATION_SEMAPHORES
Definition: spin.c:37

◆ SpinlockSemaSize()

Size SpinlockSemaSize ( void  )

Definition at line 55 of file spin.c.

References NUM_EMULATION_SEMAPHORES.

Referenced by CreateSharedMemoryAndSemaphores(), and SpinlockSemaInit().

56 {
57  return NUM_EMULATION_SEMAPHORES * sizeof(PGSemaphore);
58 }
#define NUM_EMULATION_SEMAPHORES
Definition: spin.c:37
struct PGSemaphoreData * PGSemaphore
Definition: pg_sema.h:34

◆ tas_sema()

int tas_sema ( volatile slock_t lock)

Definition at line 170 of file spin.c.

References PGSemaphoreTryLock(), and s_check_valid().

171 {
172  int lockndx = *lock;
173 
174  s_check_valid(lockndx);
175 
176  /* Note that TAS macros return 0 if *success* */
177  return !PGSemaphoreTryLock(SpinlockSemaArray[lockndx - 1]);
178 }
static void s_check_valid(int lockndx)
Definition: spin.c:114
PGSemaphore * SpinlockSemaArray
Definition: spin.c:42
bool PGSemaphoreTryLock(PGSemaphore sema)
Definition: posix_sema.c:365

Variable Documentation

◆ SpinlockSemaArray

PGSemaphore* SpinlockSemaArray

Definition at line 42 of file spin.c.

Referenced by PostmasterMarkPIDForWorkerNotify().