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.

Function Documentation

◆ s_check_valid()

static void s_check_valid ( int  lockndx)
inlinestatic

Definition at line 114 of file spin.c.

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

References elog(), ERROR, NUM_EMULATION_SEMAPHORES, and unlikely.

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

◆ s_init_lock_sema()

void s_init_lock_sema ( volatile slock_t lock,
bool  nested 
)

Definition at line 121 of file spin.c.

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 */
147 
148  *lock = idx;
149 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
unsigned int uint32
Definition: c.h:452
#define NUM_ATOMICS_SEMAPHORES
#define NUM_SPINLOCK_SEMAPHORES
static void s_check_valid(int lockndx)
Definition: spin.c:114

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().

◆ s_lock_free_sema()

bool s_lock_free_sema ( volatile slock_t lock)

Definition at line 162 of file spin.c.

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 }

References elog(), and ERROR.

◆ s_unlock_sema()

void s_unlock_sema ( volatile slock_t lock)

Definition at line 152 of file spin.c.

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
PGSemaphore * SpinlockSemaArray
Definition: spin.c:42

References PGSemaphoreUnlock(), s_check_valid(), and SpinlockSemaArray.

◆ SpinlockSemaInit()

void SpinlockSemaInit ( void  )

Definition at line 77 of file spin.c.

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 }
int i
Definition: isn.c:73
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:262
void * ShmemAllocUnlocked(Size size)
Definition: shmem.c:247
Size SpinlockSemaSize(void)
Definition: spin.c:55
int SpinlockSemas(void)
Definition: spin.c:64

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

Referenced by CreateSharedMemoryAndSemaphores().

◆ SpinlockSemas()

int SpinlockSemas ( void  )

Definition at line 64 of file spin.c.

65 {
67 }

References NUM_EMULATION_SEMAPHORES.

Referenced by CalculateShmemSize(), and SpinlockSemaInit().

◆ SpinlockSemaSize()

Size SpinlockSemaSize ( void  )

Definition at line 55 of file spin.c.

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

References NUM_EMULATION_SEMAPHORES.

Referenced by CalculateShmemSize(), and SpinlockSemaInit().

◆ tas_sema()

int tas_sema ( volatile slock_t lock)

Definition at line 170 of file spin.c.

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 }
bool PGSemaphoreTryLock(PGSemaphore sema)
Definition: posix_sema.c:365

References PGSemaphoreTryLock(), s_check_valid(), and SpinlockSemaArray.

Variable Documentation

◆ SpinlockSemaArray

PGSemaphore* SpinlockSemaArray

Definition at line 42 of file spin.c.

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