PostgreSQL Source Code git master
s_lock.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SpinDelayStatus
 

Macros

#define S_LOCK(lock)    (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
 
#define S_LOCK_FREE(lock)   (*(lock) == 0)
 
#define USE_DEFAULT_S_UNLOCK
 
#define S_UNLOCK(lock)   s_unlock(lock)
 
#define S_INIT_LOCK(lock)   S_UNLOCK(lock)
 
#define SPIN_DELAY()   ((void) 0)
 
#define TAS(lock)   tas(lock)
 
#define TAS_SPIN(lock)   TAS(lock)
 
#define DEFAULT_SPINS_PER_DELAY   100
 
#define init_local_spin_delay(status)   init_spin_delay(status, __FILE__, __LINE__, __func__)
 

Functions

void s_unlock (volatile slock_t *lock)
 
int tas (volatile slock_t *lock)
 
int s_lock (volatile slock_t *lock, const char *file, int line, const char *func)
 
void set_spins_per_delay (int shared_spins_per_delay)
 
int update_spins_per_delay (int shared_spins_per_delay)
 
static void init_spin_delay (SpinDelayStatus *status, const char *file, int line, const char *func)
 
void perform_spin_delay (SpinDelayStatus *status)
 
void finish_spin_delay (SpinDelayStatus *status)
 

Macro Definition Documentation

◆ DEFAULT_SPINS_PER_DELAY

#define DEFAULT_SPINS_PER_DELAY   100

Definition at line 720 of file s_lock.h.

◆ init_local_spin_delay

#define init_local_spin_delay (   status)    init_spin_delay(status, __FILE__, __LINE__, __func__)

Definition at line 751 of file s_lock.h.

◆ S_INIT_LOCK

#define S_INIT_LOCK (   lock)    S_UNLOCK(lock)

Definition at line 695 of file s_lock.h.

◆ S_LOCK

#define S_LOCK (   lock)     (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)

Definition at line 664 of file s_lock.h.

◆ S_LOCK_FREE

#define S_LOCK_FREE (   lock)    (*(lock) == 0)

Definition at line 669 of file s_lock.h.

◆ S_UNLOCK

#define S_UNLOCK (   lock)    s_unlock(lock)

Definition at line 691 of file s_lock.h.

◆ SPIN_DELAY

#define SPIN_DELAY ( )    ((void) 0)

Definition at line 699 of file s_lock.h.

◆ TAS

#define TAS (   lock)    tas(lock)

Definition at line 706 of file s_lock.h.

◆ TAS_SPIN

#define TAS_SPIN (   lock)    TAS(lock)

Definition at line 710 of file s_lock.h.

◆ USE_DEFAULT_S_UNLOCK

#define USE_DEFAULT_S_UNLOCK

Definition at line 689 of file s_lock.h.

Function Documentation

◆ finish_spin_delay()

void finish_spin_delay ( SpinDelayStatus status)

Definition at line 186 of file s_lock.c.

187{
188 if (status->cur_delay == 0)
189 {
190 /* we never had to delay */
193 }
194 else
195 {
198 }
199}
#define Min(x, y)
Definition: c.h:961
#define Max(x, y)
Definition: c.h:955
#define MAX_SPINS_PER_DELAY
Definition: s_lock.c:58
#define MIN_SPINS_PER_DELAY
Definition: s_lock.c:57
static int spins_per_delay
Definition: s_lock.c:72

References SpinDelayStatus::cur_delay, Max, MAX_SPINS_PER_DELAY, Min, MIN_SPINS_PER_DELAY, and spins_per_delay.

Referenced by LockBufHdr(), LWLockWaitListLock(), s_lock(), and WaitBufHdrUnlocked().

◆ init_spin_delay()

static void init_spin_delay ( SpinDelayStatus status,
const char *  file,
int  line,
const char *  func 
)
inlinestatic

Definition at line 740 of file s_lock.h.

742{
743 status->spins = 0;
744 status->delays = 0;
745 status->cur_delay = 0;
746 status->file = file;
747 status->line = line;
748 status->func = func;
749}
const char * file
Definition: s_lock.h:734
const char * func
Definition: s_lock.h:736

References SpinDelayStatus::cur_delay, SpinDelayStatus::delays, SpinDelayStatus::file, SpinDelayStatus::func, SpinDelayStatus::line, and SpinDelayStatus::spins.

Referenced by s_lock().

◆ perform_spin_delay()

void perform_spin_delay ( SpinDelayStatus status)

Definition at line 126 of file s_lock.c.

127{
128 /* CPU-specific delay each time through the loop */
129 SPIN_DELAY();
130
131 /* Block the process every spins_per_delay tries */
132 if (++(status->spins) >= spins_per_delay)
133 {
134 if (++(status->delays) > NUM_DELAYS)
135 s_lock_stuck(status->file, status->line, status->func);
136
137 if (status->cur_delay == 0) /* first time to delay? */
138 status->cur_delay = MIN_DELAY_USEC;
139
140 /*
141 * Once we start sleeping, the overhead of reporting a wait event is
142 * justified. Actively spinning easily stands out in profilers, but
143 * sleeping with an exponential backoff is harder to spot...
144 *
145 * We might want to report something more granular at some point, but
146 * this is better than nothing.
147 */
148 pgstat_report_wait_start(WAIT_EVENT_SPIN_DELAY);
149 pg_usleep(status->cur_delay);
151
152#if defined(S_LOCK_TEST)
153 fprintf(stdout, "*");
154 fflush(stdout);
155#endif
156
157 /* increase delay by a random fraction between 1X and 2X */
158 status->cur_delay += (int) (status->cur_delay *
160 /* wrap back to minimum delay when max is exceeded */
161 if (status->cur_delay > MAX_DELAY_USEC)
162 status->cur_delay = MIN_DELAY_USEC;
163
164 status->spins = 0;
165 }
166}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
static void const char fflush(stdout)
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
#define MIN_DELAY_USEC
Definition: s_lock.c:60
#define NUM_DELAYS
Definition: s_lock.c:59
#define MAX_DELAY_USEC
Definition: s_lock.c:61
static void s_lock_stuck(const char *file, int line, const char *func)
Definition: s_lock.c:79
#define SPIN_DELAY()
Definition: s_lock.h:699
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101

References SpinDelayStatus::cur_delay, SpinDelayStatus::delays, fflush(), SpinDelayStatus::file, fprintf, SpinDelayStatus::func, SpinDelayStatus::line, MAX_DELAY_USEC, MIN_DELAY_USEC, NUM_DELAYS, pg_global_prng_state, pg_prng_double(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), s_lock_stuck(), SPIN_DELAY, SpinDelayStatus::spins, spins_per_delay, and generate_unaccent_rules::stdout.

Referenced by LockBufHdr(), LWLockWaitListLock(), s_lock(), and WaitBufHdrUnlocked().

◆ s_lock()

int s_lock ( volatile slock_t *  lock,
const char *  file,
int  line,
const char *  func 
)

Definition at line 98 of file s_lock.c.

99{
100 SpinDelayStatus delayStatus;
101
102 init_spin_delay(&delayStatus, file, line, func);
103
104 while (TAS_SPIN(lock))
105 {
106 perform_spin_delay(&delayStatus);
107 }
108
109 finish_spin_delay(&delayStatus);
110
111 return delayStatus.delays;
112}
void perform_spin_delay(SpinDelayStatus *status)
Definition: s_lock.c:126
void finish_spin_delay(SpinDelayStatus *status)
Definition: s_lock.c:186
#define TAS_SPIN(lock)
Definition: s_lock.h:710
static void init_spin_delay(SpinDelayStatus *status, const char *file, int line, const char *func)
Definition: s_lock.h:740

References SpinDelayStatus::delays, finish_spin_delay(), init_spin_delay(), perform_spin_delay(), and TAS_SPIN.

Referenced by test_spinlock().

◆ s_unlock()

void s_unlock ( volatile slock_t *  lock)

Definition at line 116 of file s_lock.c.

117{
118 *lock = 0;
119}

◆ set_spins_per_delay()

void set_spins_per_delay ( int  shared_spins_per_delay)

Definition at line 207 of file s_lock.c.

208{
209 spins_per_delay = shared_spins_per_delay;
210}

References spins_per_delay.

Referenced by InitAuxiliaryProcess(), and InitProcess().

◆ tas()

int tas ( volatile slock_t *  lock)

◆ update_spins_per_delay()

int update_spins_per_delay ( int  shared_spins_per_delay)

Definition at line 218 of file s_lock.c.

219{
220 /*
221 * We use an exponential moving average with a relatively slow adaption
222 * rate, so that noise in any one backend's result won't affect the shared
223 * value too much. As long as both inputs are within the allowed range,
224 * the result must be too, so we need not worry about clamping the result.
225 *
226 * We deliberately truncate rather than rounding; this is so that single
227 * adjustments inside a backend can affect the shared estimate (see the
228 * asymmetric adjustment rules above).
229 */
230 return (shared_spins_per_delay * 15 + spins_per_delay) / 16;
231}

References spins_per_delay.

Referenced by AuxiliaryProcKill(), and ProcKill().