PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_sema.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct PGSemaphoreDataPGSemaphore
 

Functions

Size PGSemaphoreShmemSize (int maxSemas)
 
void PGReserveSemaphores (int maxSemas, int port)
 
PGSemaphore PGSemaphoreCreate (void)
 
void PGSemaphoreReset (PGSemaphore sema)
 
void PGSemaphoreLock (PGSemaphore sema)
 
void PGSemaphoreUnlock (PGSemaphore sema)
 
bool PGSemaphoreTryLock (PGSemaphore sema)
 

Typedef Documentation

Definition at line 34 of file pg_sema.h.

Function Documentation

void PGReserveSemaphores ( int  maxSemas,
int  port 
)

Definition at line 193 of file posix_sema.c.

References elog, malloc, maxSemaSets, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaKey, nextSemaNumber, nextSemKey, NULL, numSemaSets, numSems, numSharedSemas, on_shmem_exit(), PANIC, PGSemaphoreShmemSize(), ReleaseSemaphores(), SEMAS_PER_SET, and ShmemAllocUnlocked().

Referenced by CreateSharedMemoryAndSemaphores().

194 {
195 #ifdef USE_NAMED_POSIX_SEMAPHORES
196  mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *));
197  if (mySemPointers == NULL)
198  elog(PANIC, "out of memory");
199 #else
200 
201  /*
202  * We must use ShmemAllocUnlocked(), since the spinlock protecting
203  * ShmemAlloc() won't be ready yet. (This ordering is necessary when we
204  * are emulating spinlocks with semaphores.)
205  */
208 #endif
209 
210  numSems = 0;
211  maxSems = maxSemas;
212  nextSemKey = port * 1000;
213 
215 }
static int numSems
Definition: posix_sema.c:59
#define PANIC
Definition: elog.h:53
#define malloc(a)
Definition: header.h:50
static PGSemaphore sharedSemas
Definition: posix_sema.c:57
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
static void ReleaseSemaphores(int status, Datum arg)
Definition: posix_sema.c:223
static int port
Definition: pg_regress.c:89
static int maxSems
Definition: posix_sema.c:60
static int nextSemKey
Definition: posix_sema.c:61
void * ShmemAllocUnlocked(Size size)
Definition: shmem.c:227
#define NULL
Definition: c.h:229
struct PGSemaphoreData * PGSemaphore
Definition: pg_sema.h:34
Size PGSemaphoreShmemSize(int maxSemas)
Definition: posix_sema.c:158
#define elog
Definition: elog.h:219
PGSemaphore PGSemaphoreCreate ( void  )

Definition at line 245 of file posix_sema.c.

References Assert, elog, ereport, errmsg(), IpcSemaphoreCreate(), IpcSemaphoreInitialize(), IsUnderPostmaster, maxSemaSets, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaNumber, NULL, numSemaSets, numSems, numSharedSemas, PANIC, PG_SEM_REF, PosixSemaphoreCreate(), SEMAS_PER_SET, PGSemaphoreData::semId, PGSemaphoreData::semNum, and TRUE.

Referenced by InitProcGlobal(), and SpinlockSemaInit().

246 {
247  PGSemaphore sema;
248  sem_t *newsem;
249 
250  /* Can't do this in a backend, because static state is postmaster's */
252 
253  if (numSems >= maxSems)
254  elog(PANIC, "too many semaphores created");
255 
256 #ifdef USE_NAMED_POSIX_SEMAPHORES
257  newsem = PosixSemaphoreCreate();
258  /* Remember new sema for ReleaseSemaphores */
259  mySemPointers[numSems] = newsem;
260  sema = (PGSemaphore) newsem;
261 #else
262  sema = &sharedSemas[numSems];
263  newsem = PG_SEM_REF(sema);
264  PosixSemaphoreCreate(newsem);
265 #endif
266 
267  numSems++;
268 
269  return sema;
270 }
static void PosixSemaphoreCreate(sem_t *sem)
Definition: posix_sema.c:128
static int numSems
Definition: posix_sema.c:59
#define PANIC
Definition: elog.h:53
static PGSemaphore sharedSemas
Definition: posix_sema.c:57
bool IsUnderPostmaster
Definition: globals.c:101
static int maxSems
Definition: posix_sema.c:60
#define Assert(condition)
Definition: c.h:676
struct PGSemaphoreData * PGSemaphore
Definition: pg_sema.h:34
#define PG_SEM_REF(x)
Definition: posix_sema.c:50
#define elog
Definition: elog.h:219
void PGSemaphoreLock ( PGSemaphore  sema)

Definition at line 303 of file posix_sema.c.

References CHECK_FOR_INTERRUPTS, EINTR, elog, ereport, errmsg(), FALSE, FATAL, PG_SEM_REF, pgwin32_dispatch_queued_signals(), pgwin32_signal_event, PGSemaphoreData::semId, PGSemaphoreData::semNum, and TRUE.

Referenced by LWLockAcquire(), LWLockAcquireOrWait(), LWLockDequeueSelf(), LWLockWaitForVar(), and ProcArrayGroupClearXid().

304 {
305  int errStatus;
306 
307  /* See notes in sysv_sema.c's implementation of PGSemaphoreLock. */
308  do
309  {
310  errStatus = sem_wait(PG_SEM_REF(sema));
311  } while (errStatus < 0 && errno == EINTR);
312 
313  if (errStatus < 0)
314  elog(FATAL, "sem_wait failed: %m");
315 }
#define FATAL
Definition: elog.h:52
#define EINTR
Definition: win32.h:285
#define PG_SEM_REF(x)
Definition: posix_sema.c:50
#define elog
Definition: elog.h:219
void PGSemaphoreReset ( PGSemaphore  sema)

Definition at line 278 of file posix_sema.c.

References EAGAIN, EINTR, elog, FATAL, IpcSemaphoreInitialize(), PG_SEM_REF, PGSemaphoreTryLock(), PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by InitAuxiliaryProcess(), and InitProcess().

279 {
280  /*
281  * There's no direct API for this in POSIX, so we have to ratchet the
282  * semaphore down to 0 with repeated trywait's.
283  */
284  for (;;)
285  {
286  if (sem_trywait(PG_SEM_REF(sema)) < 0)
287  {
288  if (errno == EAGAIN || errno == EDEADLK)
289  break; /* got it down to 0 */
290  if (errno == EINTR)
291  continue; /* can this happen? */
292  elog(FATAL, "sem_trywait failed: %m");
293  }
294  }
295 }
#define EAGAIN
Definition: win32.h:283
#define FATAL
Definition: elog.h:52
#define EINTR
Definition: win32.h:285
#define PG_SEM_REF(x)
Definition: posix_sema.c:50
#define elog
Definition: elog.h:219
Size PGSemaphoreShmemSize ( int  maxSemas)

Definition at line 158 of file posix_sema.c.

References mul_size().

Referenced by CreateSharedMemoryAndSemaphores(), and PGReserveSemaphores().

159 {
160 #ifdef USE_NAMED_POSIX_SEMAPHORES
161  /* No shared memory needed in this case */
162  return 0;
163 #else
164  /* Need a PGSemaphoreData per semaphore */
165  return mul_size(maxSemas, sizeof(PGSemaphoreData));
166 #endif
167 }
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
bool PGSemaphoreTryLock ( PGSemaphore  sema)

Definition at line 348 of file posix_sema.c.

References EAGAIN, EINTR, elog, ereport, errmsg(), EWOULDBLOCK, FATAL, IPC_NOWAIT, PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by PGSemaphoreReset(), and tas_sema().

349 {
350  int errStatus;
351 
352  /*
353  * Note: if errStatus is -1 and errno == EINTR then it means we returned
354  * from the operation prematurely because we were sent a signal. So we
355  * try and lock the semaphore again.
356  */
357  do
358  {
359  errStatus = sem_trywait(PG_SEM_REF(sema));
360  } while (errStatus < 0 && errno == EINTR);
361 
362  if (errStatus < 0)
363  {
364  if (errno == EAGAIN || errno == EDEADLK)
365  return false; /* failed to lock it */
366  /* Otherwise we got trouble */
367  elog(FATAL, "sem_trywait failed: %m");
368  }
369 
370  return true;
371 }
#define EAGAIN
Definition: win32.h:283
#define FATAL
Definition: elog.h:52
#define EINTR
Definition: win32.h:285
#define PG_SEM_REF(x)
Definition: posix_sema.c:50
#define elog
Definition: elog.h:219
void PGSemaphoreUnlock ( PGSemaphore  sema)

Definition at line 323 of file posix_sema.c.

References EINTR, elog, ereport, errmsg(), FATAL, NULL, PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by IpcSemaphoreCreate(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockDequeueSelf(), LWLockUpdateVar(), LWLockWaitForVar(), LWLockWakeup(), ProcArrayGroupClearXid(), and s_unlock_sema().

324 {
325  int errStatus;
326 
327  /*
328  * Note: if errStatus is -1 and errno == EINTR then it means we returned
329  * from the operation prematurely because we were sent a signal. So we
330  * try and unlock the semaphore again. Not clear this can really happen,
331  * but might as well cope.
332  */
333  do
334  {
335  errStatus = sem_post(PG_SEM_REF(sema));
336  } while (errStatus < 0 && errno == EINTR);
337 
338  if (errStatus < 0)
339  elog(FATAL, "sem_post failed: %m");
340 }
#define FATAL
Definition: elog.h:52
#define EINTR
Definition: win32.h:285
#define PG_SEM_REF(x)
Definition: posix_sema.c:50
#define elog
Definition: elog.h:219