PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
proc.c File Reference
#include "postgres.h"
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "replication/slot.h"
#include "replication/syncrep.h"
#include "storage/condition_variable.h"
#include "storage/standby.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
#include "storage/spin.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
Include dependency graph for proc.c:

Go to the source code of this file.

Functions

static void RemoveProcFromArray (int code, Datum arg)
 
static void ProcKill (int code, Datum arg)
 
static void AuxiliaryProcKill (int code, Datum arg)
 
static void CheckDeadLock (void)
 
Size ProcGlobalShmemSize (void)
 
int ProcGlobalSemas (void)
 
void InitProcGlobal (void)
 
void InitProcess (void)
 
void InitProcessPhase2 (void)
 
void InitAuxiliaryProcess (void)
 
void PublishStartupProcessInformation (void)
 
void SetStartupBufferPinWaitBufId (int bufid)
 
int GetStartupBufferPinWaitBufId (void)
 
bool HaveNFreeProcs (int n)
 
bool IsWaitingForLock (void)
 
void LockErrorCleanup (void)
 
void ProcReleaseLocks (bool isCommit)
 
PGPROCAuxiliaryPidGetProc (int pid)
 
void ProcQueueInit (PROC_QUEUE *queue)
 
int ProcSleep (LOCALLOCK *locallock, LockMethod lockMethodTable)
 
PGPROCProcWakeup (PGPROC *proc, int waitStatus)
 
void ProcLockWakeup (LockMethod lockMethodTable, LOCK *lock)
 
void CheckDeadLockAlert (void)
 
void ProcWaitForSignal (uint32 wait_event_info)
 
void ProcSendSignal (int pid)
 
void BecomeLockGroupLeader (void)
 
bool BecomeLockGroupMember (PGPROC *leader, int pid)
 

Variables

int DeadlockTimeout = 1000
 
int StatementTimeout = 0
 
int LockTimeout = 0
 
int IdleInTransactionSessionTimeout = 0
 
bool log_lock_waits = false
 
PGPROCMyProc = NULL
 
PGXACTMyPgXact = NULL
 
NON_EXEC_STATIC slock_tProcStructLock = NULL
 
PROC_HDRProcGlobal = NULL
 
NON_EXEC_STATIC PGPROCAuxiliaryProcs = NULL
 
PGPROCPreparedXactProcs = NULL
 
static LOCALLOCKlockAwaited = NULL
 
static DeadLockState deadlock_state = DS_NOT_YET_CHECKED
 
static volatile sig_atomic_t got_deadlock_timeout
 

Function Documentation

PGPROC* AuxiliaryPidGetProc ( int  pid)

Definition at line 951 of file proc.c.

References AuxiliaryProcs, NULL, NUM_AUXILIARY_PROCS, PGPROC::pid, and result.

Referenced by pg_stat_get_activity().

952 {
953  PGPROC *result = NULL;
954  int index;
955 
956  if (pid == 0) /* never match dummy PGPROCs */
957  return NULL;
958 
959  for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
960  {
961  PGPROC *proc = &AuxiliaryProcs[index];
962 
963  if (proc->pid == pid)
964  {
965  result = proc;
966  break;
967  }
968  }
969  return result;
970 }
return result
Definition: formatting.c:1632
Definition: type.h:90
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
#define NULL
Definition: c.h:229
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
Definition: proc.h:94
int pid
Definition: proc.h:108
static void AuxiliaryProcKill ( int  code,
Datum  arg 
)
static

Definition at line 904 of file proc.c.

References Assert, AuxiliaryProcs, ConditionVariableCancelSleep(), DatumGetInt32, DisownLatch(), LWLockReleaseAll(), MyProc, NULL, NUM_AUXILIARY_PROCS, PG_USED_FOR_ASSERTS_ONLY, PGPROC::pid, PGPROC::procLatch, ProcStructLock, SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, SwitchBackToLocalLatch(), and update_spins_per_delay().

Referenced by InitAuxiliaryProcess().

905 {
906  int proctype = DatumGetInt32(arg);
908  PGPROC *proc;
909 
910  Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
911 
912  auxproc = &AuxiliaryProcs[proctype];
913 
914  Assert(MyProc == auxproc);
915 
916  /* Release any LW locks I am holding (see notes above) */
918 
919  /* Cancel any pending condition variable sleep, too */
921 
922  /*
923  * Reset MyLatch to the process local one. This is so that signal
924  * handlers et al can continue using the latch after the shared latch
925  * isn't ours anymore. After that clear MyProc and disown the shared
926  * latch.
927  */
929  proc = MyProc;
930  MyProc = NULL;
931  DisownLatch(&proc->procLatch);
932 
934 
935  /* Mark auxiliary proc no longer in use */
936  proc->pid = 0;
937 
938  /* Update shared estimate of spins_per_delay */
940 
942 }
#define DatumGetInt32(X)
Definition: postgres.h:478
PGPROC * MyProc
Definition: proc.c:67
PROC_HDR * ProcGlobal
Definition: proc.c:80
Latch procLatch
Definition: proc.h:103
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:264
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:250
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
int update_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:207
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
void DisownLatch(volatile Latch *latch)
Definition: latch.c:308
void * arg
void LWLockReleaseAll(void)
Definition: lwlock.c:1814
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:990
Definition: proc.h:94
int pid
Definition: proc.h:108
void BecomeLockGroupLeader ( void  )

Definition at line 1815 of file proc.c.

References Assert, dlist_push_head(), PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, and NULL.

Referenced by LaunchParallelWorkers().

1816 {
1817  LWLock *leader_lwlock;
1818 
1819  /* If we already did it, we don't need to do it again. */
1820  if (MyProc->lockGroupLeader == MyProc)
1821  return;
1822 
1823  /* We had better not be a follower. */
1825 
1826  /* Create single-member group, containing only ourselves. */
1827  leader_lwlock = LockHashPartitionLockByProc(MyProc);
1828  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1831  LWLockRelease(leader_lwlock);
1832 }
Definition: lwlock.h:32
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:300
dlist_head lockGroupMembers
Definition: proc.h:189
PGPROC * MyProc
Definition: proc.c:67
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
dlist_node lockGroupLink
Definition: proc.h:190
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:513
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
PGPROC * lockGroupLeader
Definition: proc.h:188
bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)

Definition at line 1845 of file proc.c.

References Assert, dlist_push_tail(), PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), NULL, and PGPROC::pid.

Referenced by ParallelWorkerMain().

1846 {
1847  LWLock *leader_lwlock;
1848  bool ok = false;
1849 
1850  /* Group leader can't become member of group */
1851  Assert(MyProc != leader);
1852 
1853  /* Can't already be a member of a group */
1855 
1856  /* PID must be valid. */
1857  Assert(pid != 0);
1858 
1859  /*
1860  * Get lock protecting the group fields. Note LockHashPartitionLockByProc
1861  * accesses leader->pgprocno in a PGPROC that might be free. This is safe
1862  * because all PGPROCs' pgprocno fields are set during shared memory
1863  * initialization and never change thereafter; so we will acquire the
1864  * correct lock even if the leader PGPROC is in process of being recycled.
1865  */
1866  leader_lwlock = LockHashPartitionLockByProc(leader);
1867  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1868 
1869  /* Is this the leader we're looking for? */
1870  if (leader->pid == pid && leader->lockGroupLeader == leader)
1871  {
1872  /* OK, join the group */
1873  ok = true;
1874  MyProc->lockGroupLeader = leader;
1876  }
1877  LWLockRelease(leader_lwlock);
1878 
1879  return ok;
1880 }
Definition: lwlock.h:32
dlist_head lockGroupMembers
Definition: proc.h:189
PGPROC * MyProc
Definition: proc.c:67
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:317
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
dlist_node lockGroupLink
Definition: proc.h:190
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:513
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
int pid
Definition: proc.h:108
PGPROC * lockGroupLeader
Definition: proc.h:188
static void CheckDeadLock ( void  )
static

Definition at line 1656 of file proc.c.

References Assert, deadlock_state, DeadLockCheck(), DS_HARD_DEADLOCK, i, PGPROC::links, LockHashPartitionLockByIndex, LockTagHashCode(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SHM_QUEUE::next, NULL, NUM_LOCK_PARTITIONS, SHM_QUEUE::prev, RemoveFromWaitQueue(), LOCK::tag, and PGPROC::waitLock.

Referenced by ProcSleep().

1657 {
1658  int i;
1659 
1660  /*
1661  * Acquire exclusive lock on the entire shared lock data structures. Must
1662  * grab LWLocks in partition-number order to avoid LWLock deadlock.
1663  *
1664  * Note that the deadlock check interrupt had better not be enabled
1665  * anywhere that this process itself holds lock partition locks, else this
1666  * will wait forever. Also note that LWLockAcquire creates a critical
1667  * section, so that this routine cannot be interrupted by cancel/die
1668  * interrupts.
1669  */
1670  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1672 
1673  /*
1674  * Check to see if we've been awoken by anyone in the interim.
1675  *
1676  * If we have, we can return and resume our transaction -- happy day.
1677  * Before we are awoken the process releasing the lock grants it to us so
1678  * we know that we don't have to wait anymore.
1679  *
1680  * We check by looking to see if we've been unlinked from the wait queue.
1681  * This is quicker than checking our semaphore's state, since no kernel
1682  * call is needed, and it is safe because we hold the lock partition lock.
1683  */
1684  if (MyProc->links.prev == NULL ||
1685  MyProc->links.next == NULL)
1686  goto check_done;
1687 
1688 #ifdef LOCK_DEBUG
1689  if (Debug_deadlocks)
1690  DumpAllLocks();
1691 #endif
1692 
1693  /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
1695 
1697  {
1698  /*
1699  * Oops. We have a deadlock.
1700  *
1701  * Get this process out of wait state. (Note: we could do this more
1702  * efficiently by relying on lockAwaited, but use this coding to
1703  * preserve the flexibility to kill some other transaction than the
1704  * one detecting the deadlock.)
1705  *
1706  * RemoveFromWaitQueue sets MyProc->waitStatus to STATUS_ERROR, so
1707  * ProcSleep will report an error after we return from the signal
1708  * handler.
1709  */
1710  Assert(MyProc->waitLock != NULL);
1712 
1713  /*
1714  * We're done here. Transaction abort caused by the error that
1715  * ProcSleep will raise will cause any other locks we hold to be
1716  * released, thus allowing other processes to wake up; we don't need
1717  * to do that here. NOTE: an exception is that releasing locks we
1718  * hold doesn't consider the possibility of waiters that were blocked
1719  * behind us on the lock we just failed to get, and might now be
1720  * wakable because we're not in front of them anymore. However,
1721  * RemoveFromWaitQueue took care of waking up any such processes.
1722  */
1723  }
1724 
1725  /*
1726  * And release locks. We do this in reverse order for two reasons: (1)
1727  * Anyone else who needs more than one of the locks will be trying to lock
1728  * them in increasing order; we don't want to release the other process
1729  * until it can get all the locks it needs. (2) This avoids O(N^2)
1730  * behavior inside LWLockRelease.
1731  */
1732 check_done:
1733  for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1735 }
PGPROC * MyProc
Definition: proc.c:67
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKTAG tag
Definition: lock.h:288
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define LockHashPartitionLockByIndex(i)
Definition: lock.h:501
static DeadLockState deadlock_state
Definition: proc.c:87
DeadLockState DeadLockCheck(PGPROC *proc)
Definition: deadlock.c:217
LOCK * waitLock
Definition: proc.h:135
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition: lock.c:490
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1761
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
int i
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
void CheckDeadLockAlert ( void  )

Definition at line 1743 of file proc.c.

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres().

1744 {
1745  int save_errno = errno;
1746 
1747  got_deadlock_timeout = true;
1748 
1749  /*
1750  * Have to set the latch again, even if handle_sig_alarm already did. Back
1751  * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1752  * ever would be a problem, but setting a set latch again is cheap.
1753  */
1754  SetLatch(MyLatch);
1755  errno = save_errno;
1756 }
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:90
void SetLatch(volatile Latch *latch)
Definition: latch.c:415
struct Latch * MyLatch
Definition: globals.c:51
int GetStartupBufferPinWaitBufId ( void  )

Definition at line 623 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery().

624 {
625  /* use volatile pointer to prevent code rearrangement */
626  volatile PROC_HDR *procglobal = ProcGlobal;
627 
628  return procglobal->startupBufferPinWaitBufId;
629 }
PROC_HDR * ProcGlobal
Definition: proc.c:80
Definition: proc.h:229
int startupBufferPinWaitBufId
Definition: proc.h:255
bool HaveNFreeProcs ( int  n)

Definition at line 637 of file proc.c.

References PROC_HDR::freeProcs, PGPROC::links, SHM_QUEUE::next, NULL, ProcStructLock, SpinLockAcquire, and SpinLockRelease.

Referenced by InitPostgres().

638 {
639  PGPROC *proc;
640 
642 
643  proc = ProcGlobal->freeProcs;
644 
645  while (n > 0 && proc != NULL)
646  {
647  proc = (PGPROC *) proc->links.next;
648  n--;
649  }
650 
652 
653  return (n <= 0);
654 }
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
#define NULL
Definition: c.h:229
PGPROC * freeProcs
Definition: proc.h:238
Definition: proc.h:94
void InitAuxiliaryProcess ( void  )

Definition at line 482 of file proc.c.

References PROC_HDR::allPgXact, Assert, AuxiliaryProcKill(), AuxiliaryProcs, PGPROC::backendId, PGPROC::databaseId, PGXACT::delayChkpt, dlist_is_empty(), elog, ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, i, Int32GetDatum, InvalidBackendId, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, IsBackgroundWorker, PGPROC::isBackgroundWorker, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, PGPROC::myProcLocks, MyProcPid, NULL, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, PGPROC::pgprocno, PGSemaphoreReset(), PGPROC::pid, PGPROC::procLatch, ProcStructLock, PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SHMQueueElemInit(), SHMQueueEmpty(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, STATUS_OK, SwitchToSharedLatch(), PGXACT::vacuumFlags, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStatus, PGXACT::xid, and PGXACT::xmin.

Referenced by AuxiliaryProcessMain().

483 {
484  PGPROC *auxproc;
485  int proctype;
486 
487  /*
488  * ProcGlobal should be set up already (if we are a backend, we inherit
489  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
490  */
491  if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
492  elog(PANIC, "proc header uninitialized");
493 
494  if (MyProc != NULL)
495  elog(ERROR, "you already exist");
496 
497  /*
498  * We use the ProcStructLock to protect assignment and releasing of
499  * AuxiliaryProcs entries.
500  *
501  * While we are holding the ProcStructLock, also copy the current shared
502  * estimate of spins_per_delay to local storage.
503  */
505 
507 
508  /*
509  * Find a free auxproc ... *big* trouble if there isn't one ...
510  */
511  for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
512  {
513  auxproc = &AuxiliaryProcs[proctype];
514  if (auxproc->pid == 0)
515  break;
516  }
517  if (proctype >= NUM_AUXILIARY_PROCS)
518  {
520  elog(FATAL, "all AuxiliaryProcs are in use");
521  }
522 
523  /* Mark auxiliary proc as in use by me */
524  /* use volatile pointer to prevent code rearrangement */
525  ((volatile PGPROC *) auxproc)->pid = MyProcPid;
526 
527  MyProc = auxproc;
528  MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno];
529 
531 
532  /*
533  * Initialize all fields of MyProc, except for those previously
534  * initialized by InitProcGlobal.
535  */
539  MyProc->fpVXIDLock = false;
547  MyPgXact->delayChkpt = false;
548  MyPgXact->vacuumFlags = 0;
549  MyProc->lwWaiting = false;
550  MyProc->lwWaitMode = 0;
551  MyProc->waitLock = NULL;
553 #ifdef USE_ASSERT_CHECKING
554  {
555  int i;
556 
557  /* Last process should have released all locks. */
558  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
560  }
561 #endif
562 
563  /*
564  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
565  * on it. That allows us to repoint the process latch, which so far
566  * points to process local one, to the shared one.
567  */
570 
571  /* Check that group locking fields are in a proper initial state. */
574 
575  /*
576  * We might be reusing a semaphore that belonged to a failed process. So
577  * be careful and reinitialize its value here. (This is not strictly
578  * necessary anymore, but seems like a good idea for cleanliness.)
579  */
581 
582  /*
583  * Arrange to clean up at process exit.
584  */
586 }
static void AuxiliaryProcKill(int code, Datum arg)
Definition: proc.c:904
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:196
int MyProcPid
Definition: globals.c:38
BackendId backendId
Definition: proc.h:112
dlist_head lockGroupMembers
Definition: proc.h:189
TransactionId xmin
Definition: proc.h:213
PGXACT * allPgXact
Definition: proc.h:234
PGPROC * MyProc
Definition: proc.c:67
TransactionId xid
Definition: proc.h:209
SHM_QUEUE links
Definition: proc.h:97
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:278
bool lwWaiting
Definition: proc.h:126
Oid roleId
Definition: proc.h:114
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 lwWaitMode
Definition: proc.h:127
bool fpVXIDLock
Definition: proc.h:180
#define PANIC
Definition: elog.h:53
Latch procLatch
Definition: proc.h:103
PGXACT * MyPgXact
Definition: proc.c:68
uint8 vacuumFlags
Definition: proc.h:218
bool IsBackgroundWorker
Definition: globals.c:102
bool isBackgroundWorker
Definition: proc.h:116
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:250
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:136
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
#define InvalidTransactionId
Definition: transam.h:31
Oid databaseId
Definition: proc.h:113
void OwnLatch(volatile Latch *latch)
Definition: latch.c:288
LOCK * waitLock
Definition: proc.h:135
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
#define STATUS_OK
Definition: c.h:975
bool delayChkpt
Definition: proc.h:220
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define SpinLockRelease(lock)
Definition: spin.h:64
#define InvalidBackendId
Definition: backendid.h:23
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
void SwitchToSharedLatch(void)
Definition: miscinit.c:245
int waitStatus
Definition: proc.h:101
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
#define Int32GetDatum(X)
Definition: postgres.h:485
int pgprocno
Definition: proc.h:109
#define InvalidLocalTransactionId
Definition: lock.h:70
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:156
#define elog
Definition: elog.h:219
PGSemaphore sem
Definition: proc.h:100
Definition: proc.h:94
int pid
Definition: proc.h:108
PGPROC * lockGroupLeader
Definition: proc.h:188
LocalTransactionId fpLocalTransactionId
Definition: proc.h:181
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
LocalTransactionId lxid
Definition: proc.h:105
void InitProcess ( void  )

Definition at line 287 of file proc.c.

References PROC_HDR::allPgXact, Assert, PROC_HDR::autovacFreeProcs, PGPROC::backendId, PROC_HDR::bgworkerFreeProcs, PGPROC::databaseId, PGXACT::delayChkpt, dlist_is_empty(), elog, ereport, errcode(), errmsg(), ERROR, FATAL, PGPROC::fpLocalTransactionId, PGPROC::fpVXIDLock, PROC_HDR::freeProcs, i, InitDeadLockChecking(), InitLWLockAccess(), INVALID_PGPROCNO, InvalidBackendId, InvalidLocalTransactionId, InvalidOid, InvalidTransactionId, IsAnyAutoVacuumProcess, IsAutoVacuumLauncherProcess(), IsAutoVacuumWorkerProcess(), IsBackgroundWorker, PGPROC::isBackgroundWorker, IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, MarkPostmasterChildActive(), PGPROC::myProcLocks, MyProcPid, SHM_QUEUE::next, NULL, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_init_u32(), PGPROC::pgprocno, PGSemaphoreReset(), PGPROC::pid, PROC_IS_AUTOVACUUM, PGPROC::procArrayGroupMember, PGPROC::procArrayGroupMemberXid, PGPROC::procArrayGroupNext, PGPROC::procgloballist, ProcKill(), PGPROC::procLatch, ProcStructLock, PGPROC::recoveryConflictPending, PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SHMQueueElemInit(), SHMQueueEmpty(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, STATUS_OK, SwitchToSharedLatch(), SYNC_REP_NOT_WAITING, PGPROC::syncRepLinks, PGPROC::syncRepState, PGXACT::vacuumFlags, PGPROC::wait_event_info, PGPROC::waitLock, PGPROC::waitLSN, PGPROC::waitProcLock, PGPROC::waitStatus, PGXACT::xid, and PGXACT::xmin.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), BootstrapModeMain(), PostgresMain(), and StartBackgroundWorker().

288 {
289  PGPROC *volatile * procgloballist;
290 
291  /*
292  * ProcGlobal should be set up already (if we are a backend, we inherit
293  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
294  */
295  if (ProcGlobal == NULL)
296  elog(PANIC, "proc header uninitialized");
297 
298  if (MyProc != NULL)
299  elog(ERROR, "you already exist");
300 
301  /* Decide which list should supply our PGPROC. */
303  procgloballist = &ProcGlobal->autovacFreeProcs;
304  else if (IsBackgroundWorker)
305  procgloballist = &ProcGlobal->bgworkerFreeProcs;
306  else
307  procgloballist = &ProcGlobal->freeProcs;
308 
309  /*
310  * Try to get a proc struct from the appropriate free list. If this
311  * fails, we must be out of PGPROC structures (not to mention semaphores).
312  *
313  * While we are holding the ProcStructLock, also copy the current shared
314  * estimate of spins_per_delay to local storage.
315  */
317 
319 
320  MyProc = *procgloballist;
321 
322  if (MyProc != NULL)
323  {
324  *procgloballist = (PGPROC *) MyProc->links.next;
326  }
327  else
328  {
329  /*
330  * If we reach here, all the PGPROCs are in use. This is one of the
331  * possible places to detect "too many backends", so give the standard
332  * error message. XXX do we need to give a different failure message
333  * in the autovacuum case?
334  */
336  ereport(FATAL,
337  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
338  errmsg("sorry, too many clients already")));
339  }
341 
342  /*
343  * Cross-check that the PGPROC is of the type we expect; if this were not
344  * the case, it would get returned to the wrong list.
345  */
346  Assert(MyProc->procgloballist == procgloballist);
347 
348  /*
349  * Now that we have a PGPROC, mark ourselves as an active postmaster
350  * child; this is so that the postmaster can detect it if we exit without
351  * cleaning up. (XXX autovac launcher currently doesn't participate in
352  * this; it probably should.)
353  */
356 
357  /*
358  * Initialize all fields of MyProc, except for those previously
359  * initialized by InitProcGlobal.
360  */
364  MyProc->fpVXIDLock = false;
368  MyProc->pid = MyProcPid;
369  /* backendId, databaseId and roleId will be filled in later */
374  MyPgXact->delayChkpt = false;
375  MyPgXact->vacuumFlags = 0;
376  /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
379  MyProc->lwWaiting = false;
380  MyProc->lwWaitMode = 0;
381  MyProc->waitLock = NULL;
383 #ifdef USE_ASSERT_CHECKING
384  {
385  int i;
386 
387  /* Last process should have released all locks. */
388  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
390  }
391 #endif
393 
394  /* Initialize fields for sync rep */
395  MyProc->waitLSN = 0;
398 
399  /* Initialize fields for group XID clearing. */
400  MyProc->procArrayGroupMember = false;
403 
404  /* Check that group locking fields are in a proper initial state. */
407 
408  /* Initialize wait event information. */
409  MyProc->wait_event_info = 0;
410 
411  /*
412  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
413  * on it. That allows us to repoint the process latch, which so far
414  * points to process local one, to the shared one.
415  */
418 
419  /*
420  * We might be reusing a semaphore that belonged to a failed process. So
421  * be careful and reinitialize its value here. (This is not strictly
422  * necessary anymore, but seems like a good idea for cleanliness.)
423  */
425 
426  /*
427  * Arrange to clean up at backend exit.
428  */
430 
431  /*
432  * Now that we have a PGPROC, we could try to acquire locks, so initialize
433  * local state needed for LWLocks, and the deadlock checker.
434  */
437 }
bool procArrayGroupMember
Definition: proc.h:162
static void ProcKill(int code, Datum arg)
Definition: proc.c:781
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:196
int MyProcPid
Definition: globals.c:38
BackendId backendId
Definition: proc.h:112
uint32 wait_event_info
Definition: proc.h:172
dlist_head lockGroupMembers
Definition: proc.h:189
TransactionId xmin
Definition: proc.h:213
PGXACT * allPgXact
Definition: proc.h:234
PGPROC * MyProc
Definition: proc.c:67
TransactionId xid
Definition: proc.h:209
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:278
bool lwWaiting
Definition: proc.h:126
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:31
PGPROC * bgworkerFreeProcs
Definition: proc.h:242
Oid roleId
Definition: proc.h:114
int errcode(int sqlerrcode)
Definition: elog.c:575
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 lwWaitMode
Definition: proc.h:127
bool fpVXIDLock
Definition: proc.h:180
#define PANIC
Definition: elog.h:53
PGPROC * autovacFreeProcs
Definition: proc.h:240
Latch procLatch
Definition: proc.h:103
PGXACT * MyPgXact
Definition: proc.c:68
uint8 vacuumFlags
Definition: proc.h:218
bool IsBackgroundWorker
Definition: globals.c:102
bool isBackgroundWorker
Definition: proc.h:116
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:250
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:136
void InitDeadLockChecking(void)
Definition: deadlock.c:143
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
bool recoveryConflictPending
Definition: proc.h:123
bool IsUnderPostmaster
Definition: globals.c:100
#define InvalidTransactionId
Definition: transam.h:31
Oid databaseId
Definition: proc.h:113
PGPROC ** procgloballist
Definition: proc.h:98
void OwnLatch(volatile Latch *latch)
Definition: latch.c:288
LOCK * waitLock
Definition: proc.h:135
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3360
#define ereport(elevel, rest)
Definition: elog.h:122
#define STATUS_OK
Definition: c.h:975
bool delayChkpt
Definition: proc.h:220
#define INVALID_PGPROCNO
Definition: proc.h:76
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:164
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define SpinLockRelease(lock)
Definition: spin.h:64
#define InvalidBackendId
Definition: backendid.h:23
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
void SwitchToSharedLatch(void)
Definition: miscinit.c:245
int waitStatus
Definition: proc.h:101
#define InvalidOid
Definition: postgres_ext.h:36
#define IsAnyAutoVacuumProcess()
Definition: autovacuum.h:53
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3354
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
PGPROC * freeProcs
Definition: proc.h:238
SHM_QUEUE syncRepLinks
Definition: proc.h:149
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
int pgprocno
Definition: proc.h:109
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define InvalidLocalTransactionId
Definition: lock.h:70
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:156
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:234
#define elog
Definition: elog.h:219
PGSemaphore sem
Definition: proc.h:100
int syncRepState
Definition: proc.h:148
Definition: proc.h:94
int pid
Definition: proc.h:108
XLogRecPtr waitLSN
Definition: proc.h:147
PGPROC * lockGroupLeader
Definition: proc.h:188
LocalTransactionId fpLocalTransactionId
Definition: proc.h:181
#define PROC_IS_AUTOVACUUM
Definition: proc.h:52
TransactionId procArrayGroupMemberXid
Definition: proc.h:170
void InitLWLockAccess(void)
Definition: lwlock.c:525
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
void MarkPostmasterChildActive(void)
Definition: pmsignal.c:223
LocalTransactionId lxid
Definition: proc.h:105
void InitProcessPhase2 ( void  )

Definition at line 447 of file proc.c.

References Assert, NULL, on_shmem_exit(), ProcArrayAdd(), and RemoveProcFromArray().

Referenced by InitPostgres().

448 {
449  Assert(MyProc != NULL);
450 
451  /*
452  * Add our PGPROC to the PGPROC array in shared memory.
453  */
455 
456  /*
457  * Arrange to clean that up at backend exit.
458  */
460 }
static void RemoveProcFromArray(int code, Datum arg)
Definition: proc.c:770
PGPROC * MyProc
Definition: proc.c:67
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void ProcArrayAdd(PGPROC *proc)
Definition: procarray.c:274
void InitProcGlobal ( void  )

Definition at line 162 of file proc.c.

References PROC_HDR::allPgXact, PROC_HDR::allProcCount, PROC_HDR::allProcs, Assert, PROC_HDR::autovacFreeProcs, autovacuum_max_workers, AuxiliaryProcs, PROC_HDR::bgworkerFreeProcs, PROC_HDR::checkpointerLatch, DEFAULT_SPINS_PER_DELAY, dlist_init(), PROC_HDR::freeProcs, i, InitSharedLatch(), INVALID_PGPROCNO, PGPROC::links, LWLockInitialize(), LWTRANCHE_PROC, max_prepared_xacts, MaxBackends, MaxConnections, MemSet, SHM_QUEUE::next, NULL, NUM_AUXILIARY_PROCS, NUM_LOCK_PARTITIONS, pg_atomic_init_u32(), PGPROC::pgprocno, PGSemaphoreCreate(), PROC_HDR::procArrayGroupFirst, PGPROC::procgloballist, ProcStructLock, PGPROC::sem, ShmemAlloc(), ShmemInitStruct(), SHMQueueInit(), SpinLockInit, PROC_HDR::spins_per_delay, PROC_HDR::startupBufferPinWaitBufId, PROC_HDR::startupProc, PROC_HDR::startupProcPid, and PROC_HDR::walwriterLatch.

Referenced by CreateSharedMemoryAndSemaphores().

163 {
164  PGPROC *procs;
165  PGXACT *pgxacts;
166  int i,
167  j;
168  bool found;
170 
171  /* Create the ProcGlobal shared structure */
172  ProcGlobal = (PROC_HDR *)
173  ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
174  Assert(!found);
175 
176  /*
177  * Initialize the data structures.
178  */
189 
190  /*
191  * Create and initialize all the PGPROC structures we'll need. There are
192  * five separate consumers: (1) normal backends, (2) autovacuum workers
193  * and the autovacuum launcher, (3) background workers, (4) auxiliary
194  * processes, and (5) prepared transactions. Each PGPROC structure is
195  * dedicated to exactly one of these purposes, and they do not move
196  * between groups.
197  */
198  procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
199  MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
200  ProcGlobal->allProcs = procs;
201  /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
203 
204  /*
205  * Also allocate a separate array of PGXACT structures. This is separate
206  * from the main PGPROC array so that the most heavily accessed data is
207  * stored contiguously in memory in as few cache lines as possible. This
208  * provides significant performance benefits, especially on a
209  * multiprocessor system. There is one PGXACT structure for every PGPROC
210  * structure.
211  */
212  pgxacts = (PGXACT *) ShmemAlloc(TotalProcs * sizeof(PGXACT));
213  MemSet(pgxacts, 0, TotalProcs * sizeof(PGXACT));
214  ProcGlobal->allPgXact = pgxacts;
215 
216  for (i = 0; i < TotalProcs; i++)
217  {
218  /* Common initialization for all PGPROCs, regardless of type. */
219 
220  /*
221  * Set up per-PGPROC semaphore, latch, and backendLock. Prepared xact
222  * dummy PGPROCs don't need these though - they're never associated
223  * with a real process
224  */
225  if (i < MaxBackends + NUM_AUXILIARY_PROCS)
226  {
227  procs[i].sem = PGSemaphoreCreate();
228  InitSharedLatch(&(procs[i].procLatch));
229  LWLockInitialize(&(procs[i].backendLock), LWTRANCHE_PROC);
230  }
231  procs[i].pgprocno = i;
232 
233  /*
234  * Newly created PGPROCs for normal backends, autovacuum and bgworkers
235  * must be queued up on the appropriate free list. Because there can
236  * only ever be a small, fixed number of auxiliary processes, no free
237  * list is used in that case; InitAuxiliaryProcess() instead uses a
238  * linear search. PGPROCs for prepared transactions are added to a
239  * free list by TwoPhaseShmemInit().
240  */
241  if (i < MaxConnections)
242  {
243  /* PGPROC for normal backend, add to freeProcs list */
244  procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
245  ProcGlobal->freeProcs = &procs[i];
246  procs[i].procgloballist = &ProcGlobal->freeProcs;
247  }
248  else if (i < MaxConnections + autovacuum_max_workers + 1)
249  {
250  /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
252  ProcGlobal->autovacFreeProcs = &procs[i];
254  }
255  else if (i < MaxBackends)
256  {
257  /* PGPROC for bgworker, add to bgworkerFreeProcs list */
259  ProcGlobal->bgworkerFreeProcs = &procs[i];
261  }
262 
263  /* Initialize myProcLocks[] shared memory queues. */
264  for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
265  SHMQueueInit(&(procs[i].myProcLocks[j]));
266 
267  /* Initialize lockGroupMembers list. */
268  dlist_init(&procs[i].lockGroupMembers);
269  }
270 
271  /*
272  * Save pointers to the blocks of PGPROC structures reserved for auxiliary
273  * processes and prepared transactions.
274  */
275  AuxiliaryProcs = &procs[MaxBackends];
277 
278  /* Create ProcStructLock spinlock, too */
279  ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
281 }
int slock_t
Definition: s_lock.h:888
Definition: proc.h:207
PGXACT * allPgXact
Definition: proc.h:234
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
#define SpinLockInit(lock)
Definition: spin.h:60
PGPROC * PreparedXactProcs
Definition: proc.c:82
PGPROC * bgworkerFreeProcs
Definition: proc.h:242
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define MemSet(start, val, len)
Definition: c.h:857
void * ShmemAlloc(Size size)
Definition: shmem.c:157
PGSemaphore PGSemaphoreCreate(void)
Definition: posix_sema.c:245
PGPROC * autovacFreeProcs
Definition: proc.h:240
Latch * walwriterLatch
Definition: proc.h:246
int spins_per_delay
Definition: proc.h:250
int max_prepared_xacts
Definition: twophase.c:117
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:372
int MaxBackends
Definition: globals.c:126
unsigned int uint32
Definition: c.h:268
PGPROC ** procgloballist
Definition: proc.h:98
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
#define INVALID_PGPROCNO
Definition: proc.h:76
Definition: proc.h:229
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:667
int startupProcPid
Definition: proc.h:253
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
int MaxConnections
Definition: globals.c:123
int autovacuum_max_workers
Definition: autovacuum.c:113
static void dlist_init(dlist_head *head)
Definition: ilist.h:278
Latch * checkpointerLatch
Definition: proc.h:248
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
PGPROC * freeProcs
Definition: proc.h:238
uint32 allProcCount
Definition: proc.h:236
int pgprocno
Definition: proc.h:109
pg_atomic_uint32 procArrayGroupFirst
Definition: proc.h:244
void SHMQueueInit(SHM_QUEUE *queue)
Definition: shmqueue.c:36
int startupBufferPinWaitBufId
Definition: proc.h:255
int i
PGPROC * allProcs
Definition: proc.h:232
PGPROC * startupProc
Definition: proc.h:252
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:234
PGSemaphore sem
Definition: proc.h:100
void InitSharedLatch(volatile Latch *latch)
Definition: latch.c:252
Definition: proc.h:94
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
#define DEFAULT_SPINS_PER_DELAY
Definition: s_lock.h:966
bool IsWaitingForLock ( void  )

Definition at line 660 of file proc.c.

References NULL.

Referenced by RecoveryConflictInterrupt().

661 {
662  if (lockAwaited == NULL)
663  return false;
664 
665  return true;
666 }
#define NULL
Definition: c.h:229
static LOCALLOCK * lockAwaited
Definition: proc.c:85
void LockErrorCleanup ( void  )

Definition at line 677 of file proc.c.

References AbortStrongLockAcquire(), DEADLOCK_TIMEOUT, disable_timeouts(), GrantAwaitedLock(), LOCALLOCK::hashcode, HOLD_INTERRUPTS, DisableTimeoutParams::id, DisableTimeoutParams::keep_indicator, PGPROC::links, LOCK_TIMEOUT, LockHashPartitionLock, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SHM_QUEUE::next, NULL, RemoveFromWaitQueue(), RESUME_INTERRUPTS, STATUS_OK, and PGPROC::waitStatus.

Referenced by AbortSubTransaction(), AbortTransaction(), ProcessInterrupts(), and ProcReleaseLocks().

678 {
679  LWLock *partitionLock;
680  DisableTimeoutParams timeouts[2];
681 
682  HOLD_INTERRUPTS();
683 
685 
686  /* Nothing to do if we weren't waiting for a lock */
687  if (lockAwaited == NULL)
688  {
690  return;
691  }
692 
693  /*
694  * Turn off the deadlock and lock timeout timers, if they are still
695  * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
696  * indicator flag, since this function is executed before
697  * ProcessInterrupts when responding to SIGINT; else we'd lose the
698  * knowledge that the SIGINT came from a lock timeout and not an external
699  * source.
700  */
701  timeouts[0].id = DEADLOCK_TIMEOUT;
702  timeouts[0].keep_indicator = false;
703  timeouts[1].id = LOCK_TIMEOUT;
704  timeouts[1].keep_indicator = true;
705  disable_timeouts(timeouts, 2);
706 
707  /* Unlink myself from the wait queue, if on it (might not be anymore!) */
708  partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
709  LWLockAcquire(partitionLock, LW_EXCLUSIVE);
710 
711  if (MyProc->links.next != NULL)
712  {
713  /* We could not have been granted the lock yet */
715  }
716  else
717  {
718  /*
719  * Somebody kicked us off the lock queue already. Perhaps they
720  * granted us the lock, or perhaps they detected a deadlock. If they
721  * did grant us the lock, we'd better remember it in our local lock
722  * table.
723  */
724  if (MyProc->waitStatus == STATUS_OK)
726  }
727 
728  lockAwaited = NULL;
729 
730  LWLockRelease(partitionLock);
731 
733 }
uint32 hashcode
Definition: lock.h:410
Definition: lwlock.h:32
void GrantAwaitedLock(void)
Definition: lock.c:1643
PGPROC * MyProc
Definition: proc.c:67
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
#define LockHashPartitionLock(hashcode)
Definition: lock.h:498
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:561
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:116
TimeoutId id
Definition: timeout.h:65
void AbortStrongLockAcquire(void)
Definition: lock.c:1614
#define STATUS_OK
Definition: c.h:975
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1761
int waitStatus
Definition: proc.h:101
#define NULL
Definition: c.h:229
static LOCALLOCK * lockAwaited
Definition: proc.c:85
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:114
int ProcGlobalSemas ( void  )

Definition at line 128 of file proc.c.

References MaxBackends, and NUM_AUXILIARY_PROCS.

Referenced by CreateSharedMemoryAndSemaphores().

129 {
130  /*
131  * We need a sema per backend (including autovacuum), plus one for each
132  * auxiliary process.
133  */
135 }
int MaxBackends
Definition: globals.c:126
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
Size ProcGlobalShmemSize ( void  )

Definition at line 102 of file proc.c.

References add_size(), max_prepared_xacts, MaxBackends, mul_size(), and NUM_AUXILIARY_PROCS.

Referenced by CreateSharedMemoryAndSemaphores().

103 {
104  Size size = 0;
105 
106  /* ProcGlobal */
107  size = add_size(size, sizeof(PROC_HDR));
108  /* MyProcs, including autovacuum workers and launcher */
109  size = add_size(size, mul_size(MaxBackends, sizeof(PGPROC)));
110  /* AuxiliaryProcs */
111  size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGPROC)));
112  /* Prepared xacts */
113  size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGPROC)));
114  /* ProcStructLock */
115  size = add_size(size, sizeof(slock_t));
116 
117  size = add_size(size, mul_size(MaxBackends, sizeof(PGXACT)));
118  size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGXACT)));
119  size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGXACT)));
120 
121  return size;
122 }
int slock_t
Definition: s_lock.h:888
Definition: proc.h:207
int max_prepared_xacts
Definition: twophase.c:117
int MaxBackends
Definition: globals.c:126
#define NUM_AUXILIARY_PROCS
Definition: proc.h:273
Definition: proc.h:229
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
size_t Size
Definition: c.h:356
Definition: proc.h:94
static void ProcKill ( int  code,
Datum  arg 
)
static

Definition at line 781 of file proc.c.

References Assert, AutovacuumLauncherPid, ConditionVariableCancelSleep(), DisownLatch(), dlist_delete(), dlist_is_empty(), i, IsAutoVacuumLauncherProcess(), IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), LWLockReleaseAll(), MarkPostmasterChildInactive(), MyProc, PGPROC::myProcLocks, MyReplicationSlot, SHM_QUEUE::next, NULL, NUM_LOCK_PARTITIONS, PGPROC::procgloballist, PGPROC::procLatch, ProcStructLock, ReplicationSlotCleanup(), ReplicationSlotRelease(), SHMQueueEmpty(), SIGUSR2, SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, SwitchBackToLocalLatch(), SyncRepCleanupAtProcExit(), and update_spins_per_delay().

Referenced by InitProcess().

782 {
783  PGPROC *proc;
784  PGPROC *volatile * procgloballist;
785 
786  Assert(MyProc != NULL);
787 
788  /* Make sure we're out of the sync rep lists */
790 
791 #ifdef USE_ASSERT_CHECKING
792  {
793  int i;
794 
795  /* Last process should have released all locks. */
796  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
798  }
799 #endif
800 
801  /*
802  * Release any LW locks I am holding. There really shouldn't be any, but
803  * it's cheap to check again before we cut the knees off the LWLock
804  * facility by releasing our PGPROC ...
805  */
807 
808  /* Cancel any pending condition variable sleep, too */
810 
811  /* Make sure active replication slots are released */
812  if (MyReplicationSlot != NULL)
814 
815  /* Also cleanup all the temporary slots. */
817 
818  /*
819  * Detach from any lock group of which we are a member. If the leader
820  * exist before all other group members, it's PGPROC will remain allocated
821  * until the last group process exits; that process must return the
822  * leader's PGPROC to the appropriate list.
823  */
824  if (MyProc->lockGroupLeader != NULL)
825  {
826  PGPROC *leader = MyProc->lockGroupLeader;
827  LWLock *leader_lwlock = LockHashPartitionLockByProc(leader);
828 
829  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
832  if (dlist_is_empty(&leader->lockGroupMembers))
833  {
834  leader->lockGroupLeader = NULL;
835  if (leader != MyProc)
836  {
837  procgloballist = leader->procgloballist;
838 
839  /* Leader exited first; return its PGPROC. */
841  leader->links.next = (SHM_QUEUE *) *procgloballist;
842  *procgloballist = leader;
844  }
845  }
846  else if (leader != MyProc)
848  LWLockRelease(leader_lwlock);
849  }
850 
851  /*
852  * Reset MyLatch to the process local one. This is so that signal
853  * handlers et al can continue using the latch after the shared latch
854  * isn't ours anymore. After that clear MyProc and disown the shared
855  * latch.
856  */
858  proc = MyProc;
859  MyProc = NULL;
860  DisownLatch(&proc->procLatch);
861 
862  procgloballist = proc->procgloballist;
864 
865  /*
866  * If we're still a member of a locking group, that means we're a leader
867  * which has somehow exited before its children. The last remaining child
868  * will release our PGPROC. Otherwise, release it now.
869  */
870  if (proc->lockGroupLeader == NULL)
871  {
872  /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
874 
875  /* Return PGPROC structure (and semaphore) to appropriate freelist */
876  proc->links.next = (SHM_QUEUE *) *procgloballist;
877  *procgloballist = proc;
878  }
879 
880  /* Update shared estimate of spins_per_delay */
882 
884 
885  /*
886  * This process is no longer present in shared memory in any meaningful
887  * way, so tell the postmaster we've cleaned up acceptably well. (XXX
888  * autovac launcher should be included here someday)
889  */
892 
893  /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
894  if (AutovacuumLauncherPid != 0)
896 }
Definition: lwlock.h:32
dlist_head lockGroupMembers
Definition: proc.h:189
PGPROC * MyProc
Definition: proc.c:67
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:80
void MarkPostmasterChildInactive(void)
Definition: pmsignal.c:256
Latch procLatch
Definition: proc.h:103
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:264
dlist_node lockGroupLink
Definition: proc.h:190
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:250
int AutovacuumLauncherPid
Definition: autovacuum.c:313
bool IsUnderPostmaster
Definition: globals.c:100
void ReplicationSlotRelease(void)
Definition: slot.c:375
PGPROC ** procgloballist
Definition: proc.h:98
static void dlist_delete(dlist_node *node)
Definition: ilist.h:358
int update_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:207
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:513
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3354
ReplicationSlot * MyReplicationSlot
Definition: slot.c:96
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
void SyncRepCleanupAtProcExit(void)
Definition: syncrep.c:360
void DisownLatch(volatile Latch *latch)
Definition: latch.c:308
int i
void ReplicationSlotCleanup(void)
Definition: slot.c:429
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:156
void LWLockReleaseAll(void)
Definition: lwlock.c:1814
Definition: proc.h:94
#define SIGUSR2
Definition: win32.h:203
PGPROC * lockGroupLeader
Definition: proc.h:188
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1595 of file proc.c.

References Assert, LockMethodData::conflictTab, GrantLock(), PROC_QUEUE::links, PGPROC::links, LOCKBIT_ON, LockCheckConflicts(), SHM_QUEUE::next, ProcWakeup(), PROC_QUEUE::size, STATUS_OK, PGPROC::waitLockMode, PGPROC::waitProcLock, and LOCK::waitProcs.

Referenced by CleanUpLock(), and DeadLockCheck().

1596 {
1597  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1598  int queue_size = waitQueue->size;
1599  PGPROC *proc;
1600  LOCKMASK aheadRequests = 0;
1601 
1602  Assert(queue_size >= 0);
1603 
1604  if (queue_size == 0)
1605  return;
1606 
1607  proc = (PGPROC *) waitQueue->links.next;
1608 
1609  while (queue_size-- > 0)
1610  {
1611  LOCKMODE lockmode = proc->waitLockMode;
1612 
1613  /*
1614  * Waken if (a) doesn't conflict with requests of earlier waiters, and
1615  * (b) doesn't conflict with already-held locks.
1616  */
1617  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1618  LockCheckConflicts(lockMethodTable,
1619  lockmode,
1620  lock,
1621  proc->waitProcLock) == STATUS_OK)
1622  {
1623  /* OK to waken */
1624  GrantLock(lock, proc->waitProcLock, lockmode);
1625  proc = ProcWakeup(proc, STATUS_OK);
1626 
1627  /*
1628  * ProcWakeup removes proc from the lock's waiting process queue
1629  * and returns the next proc in chain; don't use proc's next-link,
1630  * because it's been cleared.
1631  */
1632  }
1633  else
1634  {
1635  /*
1636  * Cannot wake this guy. Remember his request for later checks.
1637  */
1638  aheadRequests |= LOCKBIT_ON(lockmode);
1639  proc = (PGPROC *) proc->links.next;
1640  }
1641  }
1642 
1643  Assert(waitQueue->size >= 0);
1644 }
int LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1292
int LOCKMODE
Definition: lockdefs.h:26
SHM_QUEUE links
Definition: lock.h:32
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1415
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:137
const LOCKMASK * conflictTab
Definition: lock.h:115
PROC_QUEUE waitProcs
Definition: lock.h:294
PROCLOCK * waitProcLock
Definition: proc.h:136
#define STATUS_OK
Definition: c.h:975
#define Assert(condition)
Definition: c.h:675
int LOCKMASK
Definition: lockdefs.h:25
#define LOCKBIT_ON(lockmode)
Definition: lock.h:88
int size
Definition: lock.h:33
PGPROC * ProcWakeup(PGPROC *proc, int waitStatus)
Definition: proc.c:1559
Definition: proc.h:94
void ProcQueueInit ( PROC_QUEUE queue)

Definition at line 1004 of file proc.c.

References PROC_QUEUE::links, SHMQueueInit(), and PROC_QUEUE::size.

Referenced by DeadLockCheck(), lock_twophase_recover(), and SetupLockInTable().

1005 {
1006  SHMQueueInit(&(queue->links));
1007  queue->size = 0;
1008 }
SHM_QUEUE links
Definition: lock.h:32
void SHMQueueInit(SHM_QUEUE *queue)
Definition: shmqueue.c:36
int size
Definition: lock.h:33
void ProcReleaseLocks ( bool  isCommit)

Definition at line 753 of file proc.c.

References DEFAULT_LOCKMETHOD, LockErrorCleanup(), LockReleaseAll(), and USER_LOCKMETHOD.

Referenced by ResourceOwnerReleaseInternal().

754 {
755  if (!MyProc)
756  return;
757  /* If waiting, get off wait queue (should only be needed after error) */
759  /* Release standard locks, including session-level if aborting */
761  /* Release transaction-level advisory locks */
763 }
PGPROC * MyProc
Definition: proc.c:67
#define DEFAULT_LOCKMETHOD
Definition: lock.h:129
#define USER_LOCKMETHOD
Definition: lock.h:130
void LockErrorCleanup(void)
Definition: proc.c:677
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2014
void ProcSendSignal ( int  pid)

Definition at line 1777 of file proc.c.

References BackendPidGetProc(), NULL, PGPROC::procLatch, ProcStructLock, RecoveryInProgress(), SetLatch(), SpinLockAcquire, SpinLockRelease, PROC_HDR::startupProc, and PROC_HDR::startupProcPid.

Referenced by ReleasePredicateLocks(), and UnpinBuffer().

1778 {
1779  PGPROC *proc = NULL;
1780 
1781  if (RecoveryInProgress())
1782  {
1784 
1785  /*
1786  * Check to see whether it is the Startup process we wish to signal.
1787  * This call is made by the buffer manager when it wishes to wake up a
1788  * process that has been waiting for a pin in so it can obtain a
1789  * cleanup lock using LockBufferForCleanup(). Startup is not a normal
1790  * backend, so BackendPidGetProc() will not return any pid at all. So
1791  * we remember the information for this special case.
1792  */
1793  if (pid == ProcGlobal->startupProcPid)
1794  proc = ProcGlobal->startupProc;
1795 
1797  }
1798 
1799  if (proc == NULL)
1800  proc = BackendPidGetProc(pid);
1801 
1802  if (proc != NULL)
1803  {
1804  SetLatch(&proc->procLatch);
1805  }
1806 }
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:2342
PROC_HDR * ProcGlobal
Definition: proc.c:80
bool RecoveryInProgress(void)
Definition: xlog.c:7873
Latch procLatch
Definition: proc.h:103
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:253
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
void SetLatch(volatile Latch *latch)
Definition: latch.c:415
#define NULL
Definition: c.h:229
PGPROC * startupProc
Definition: proc.h:252
Definition: proc.h:94
int ProcSleep ( LOCALLOCK locallock,
LockMethod  lockMethodTable 
)

Definition at line 1028 of file proc.c.

References _, PROC_HDR::allPgXact, appendStringInfo(), Assert, buf, CHECK_FOR_INTERRUPTS, CheckDeadLock(), CheckRecoveryConflictDeadlock(), LockMethodData::conflictTab, StringInfoData::data, deadlock_state, DEADLOCK_TIMEOUT, DeadlockTimeout, DEBUG1, EnableTimeoutParams::delay_ms, DescribeLockTag(), disable_timeout(), disable_timeouts(), DS_BLOCKED_BY_AUTOVACUUM, DS_HARD_DEADLOCK, DS_NO_DEADLOCK, DS_NOT_YET_CHECKED, DS_SOFT_DEADLOCK, enable_timeout_after(), enable_timeouts(), ereport, errdetail_log(), errdetail_log_plural(), errmsg(), get_timeout_start_time(), GetBlockingAutoVacuumPgproc(), GetCurrentTimestamp(), GetLockmodeName(), got_deadlock_timeout, GrantAwaitedLock(), GrantLock(), PROCLOCK::groupLeader, LOCALLOCK::hashcode, PGPROC::heldLocks, PROCLOCK::holdMask, i, EnableTimeoutParams::id, DisableTimeoutParams::id, InHotStandby, initStringInfo(), InRecovery, DisableTimeoutParams::keep_indicator, PROC_QUEUE::links, PGPROC::links, LOCALLOCKTAG::lock, LOCALLOCK::lock, LOCK_TIMEOUT, LOCKBIT_ON, LockCheckConflicts(), PGPROC::lockGroupLeader, LockHashPartitionLock, PROCLOCK::lockLink, LOCKTAG::locktag_lockmethodid, LOCKTAG::locktag_type, LockTimeout, LOG, log_lock_waits, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), LOCALLOCKTAG::mode, MyLatch, PROCLOCKTAG::myProc, MyProcPid, SHM_QUEUE::next, NULL, offsetof, pfree(), PG_WAIT_LOCK, PGPROC::pgprocno, PGPROC::pid, PROC_IS_AUTOVACUUM, PROC_VACUUM_FOR_WRAPAROUND, LOCALLOCK::proclock, LOCK::procLocks, RecoveryInProgress(), RememberSimpleDeadLock(), RemoveFromWaitQueue(), ResetLatch(), ResolveRecoveryConflictWithLock(), SHMQueueInsertBefore(), SHMQueueNext(), PROC_QUEUE::size, STATUS_ERROR, STATUS_OK, STATUS_WAITING, LOCK::tag, PROCLOCK::tag, LOCALLOCK::tag, TimestampDifference(), TMPARAM_AFTER, EnableTimeoutParams::type, PGXACT::vacuumFlags, WaitLatch(), PGPROC::waitLock, PGPROC::waitLockMode, LOCK::waitMask, PGPROC::waitProcLock, LOCK::waitProcs, PGPROC::waitStatus, WARNING, and WL_LATCH_SET.

Referenced by WaitOnLock().

1029 {
1030  LOCKMODE lockmode = locallock->tag.mode;
1031  LOCK *lock = locallock->lock;
1032  PROCLOCK *proclock = locallock->proclock;
1033  uint32 hashcode = locallock->hashcode;
1034  LWLock *partitionLock = LockHashPartitionLock(hashcode);
1035  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1036  LOCKMASK myHeldLocks = MyProc->heldLocks;
1037  bool early_deadlock = false;
1038  bool allow_autovacuum_cancel = true;
1039  int myWaitStatus;
1040  PGPROC *proc;
1041  PGPROC *leader = MyProc->lockGroupLeader;
1042  int i;
1043 
1044  /*
1045  * If group locking is in use, locks held by members of my locking group
1046  * need to be included in myHeldLocks.
1047  */
1048  if (leader != NULL)
1049  {
1050  SHM_QUEUE *procLocks = &(lock->procLocks);
1051  PROCLOCK *otherproclock;
1052 
1053  otherproclock = (PROCLOCK *)
1054  SHMQueueNext(procLocks, procLocks, offsetof(PROCLOCK, lockLink));
1055  while (otherproclock != NULL)
1056  {
1057  if (otherproclock->groupLeader == leader)
1058  myHeldLocks |= otherproclock->holdMask;
1059  otherproclock = (PROCLOCK *)
1060  SHMQueueNext(procLocks, &otherproclock->lockLink,
1061  offsetof(PROCLOCK, lockLink));
1062  }
1063  }
1064 
1065  /*
1066  * Determine where to add myself in the wait queue.
1067  *
1068  * Normally I should go at the end of the queue. However, if I already
1069  * hold locks that conflict with the request of any previous waiter, put
1070  * myself in the queue just in front of the first such waiter. This is not
1071  * a necessary step, since deadlock detection would move me to before that
1072  * waiter anyway; but it's relatively cheap to detect such a conflict
1073  * immediately, and avoid delaying till deadlock timeout.
1074  *
1075  * Special case: if I find I should go in front of some waiter, check to
1076  * see if I conflict with already-held locks or the requests before that
1077  * waiter. If not, then just grant myself the requested lock immediately.
1078  * This is the same as the test for immediate grant in LockAcquire, except
1079  * we are only considering the part of the wait queue before my insertion
1080  * point.
1081  */
1082  if (myHeldLocks != 0)
1083  {
1084  LOCKMASK aheadRequests = 0;
1085 
1086  proc = (PGPROC *) waitQueue->links.next;
1087  for (i = 0; i < waitQueue->size; i++)
1088  {
1089  /*
1090  * If we're part of the same locking group as this waiter, its
1091  * locks neither conflict with ours nor contribute to
1092  * aheadRequests.
1093  */
1094  if (leader != NULL && leader == proc->lockGroupLeader)
1095  {
1096  proc = (PGPROC *) proc->links.next;
1097  continue;
1098  }
1099  /* Must he wait for me? */
1100  if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
1101  {
1102  /* Must I wait for him ? */
1103  if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
1104  {
1105  /*
1106  * Yes, so we have a deadlock. Easiest way to clean up
1107  * correctly is to call RemoveFromWaitQueue(), but we
1108  * can't do that until we are *on* the wait queue. So, set
1109  * a flag to check below, and break out of loop. Also,
1110  * record deadlock info for later message.
1111  */
1112  RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
1113  early_deadlock = true;
1114  break;
1115  }
1116  /* I must go before this waiter. Check special case. */
1117  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1118  LockCheckConflicts(lockMethodTable,
1119  lockmode,
1120  lock,
1121  proclock) == STATUS_OK)
1122  {
1123  /* Skip the wait and just grant myself the lock. */
1124  GrantLock(lock, proclock, lockmode);
1125  GrantAwaitedLock();
1126  return STATUS_OK;
1127  }
1128  /* Break out of loop to put myself before him */
1129  break;
1130  }
1131  /* Nope, so advance to next waiter */
1132  aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
1133  proc = (PGPROC *) proc->links.next;
1134  }
1135 
1136  /*
1137  * If we fall out of loop normally, proc points to waitQueue head, so
1138  * we will insert at tail of queue as desired.
1139  */
1140  }
1141  else
1142  {
1143  /* I hold no locks, so I can't push in front of anyone. */
1144  proc = (PGPROC *) &(waitQueue->links);
1145  }
1146 
1147  /*
1148  * Insert self into queue, ahead of the given proc (or at tail of queue).
1149  */
1150  SHMQueueInsertBefore(&(proc->links), &(MyProc->links));
1151  waitQueue->size++;
1152 
1153  lock->waitMask |= LOCKBIT_ON(lockmode);
1154 
1155  /* Set up wait information in PGPROC object, too */
1156  MyProc->waitLock = lock;
1157  MyProc->waitProcLock = proclock;
1158  MyProc->waitLockMode = lockmode;
1159 
1161 
1162  /*
1163  * If we detected deadlock, give up without waiting. This must agree with
1164  * CheckDeadLock's recovery code, except that we shouldn't release the
1165  * semaphore since we haven't tried to lock it yet.
1166  */
1167  if (early_deadlock)
1168  {
1169  RemoveFromWaitQueue(MyProc, hashcode);
1170  return STATUS_ERROR;
1171  }
1172 
1173  /* mark that we are waiting for a lock */
1174  lockAwaited = locallock;
1175 
1176  /*
1177  * Release the lock table's partition lock.
1178  *
1179  * NOTE: this may also cause us to exit critical-section state, possibly
1180  * allowing a cancel/die interrupt to be accepted. This is OK because we
1181  * have recorded the fact that we are waiting for a lock, and so
1182  * LockErrorCleanup will clean up if cancel/die happens.
1183  */
1184  LWLockRelease(partitionLock);
1185 
1186  /*
1187  * Also, now that we will successfully clean up after an ereport, it's
1188  * safe to check to see if there's a buffer pin deadlock against the
1189  * Startup process. Of course, that's only necessary if we're doing Hot
1190  * Standby and are not the Startup process ourselves.
1191  */
1192  if (RecoveryInProgress() && !InRecovery)
1194 
1195  /* Reset deadlock_state before enabling the timeout handler */
1197  got_deadlock_timeout = false;
1198 
1199  /*
1200  * Set timer so we can wake up after awhile and check for a deadlock. If a
1201  * deadlock is detected, the handler releases the process's semaphore and
1202  * sets MyProc->waitStatus = STATUS_ERROR, allowing us to know that we
1203  * must report failure rather than success.
1204  *
1205  * By delaying the check until we've waited for a bit, we can avoid
1206  * running the rather expensive deadlock-check code in most cases.
1207  *
1208  * If LockTimeout is set, also enable the timeout for that. We can save a
1209  * few cycles by enabling both timeout sources in one call.
1210  *
1211  * If InHotStandby we set lock waits slightly later for clarity with other
1212  * code.
1213  */
1214  if (!InHotStandby)
1215  {
1216  if (LockTimeout > 0)
1217  {
1218  EnableTimeoutParams timeouts[2];
1219 
1220  timeouts[0].id = DEADLOCK_TIMEOUT;
1221  timeouts[0].type = TMPARAM_AFTER;
1222  timeouts[0].delay_ms = DeadlockTimeout;
1223  timeouts[1].id = LOCK_TIMEOUT;
1224  timeouts[1].type = TMPARAM_AFTER;
1225  timeouts[1].delay_ms = LockTimeout;
1226  enable_timeouts(timeouts, 2);
1227  }
1228  else
1230  }
1231 
1232  /*
1233  * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1234  * will not wait. But a set latch does not necessarily mean that the lock
1235  * is free now, as there are many other sources for latch sets than
1236  * somebody releasing the lock.
1237  *
1238  * We process interrupts whenever the latch has been set, so cancel/die
1239  * interrupts are processed quickly. This means we must not mind losing
1240  * control to a cancel/die interrupt here. We don't, because we have no
1241  * shared-state-change work to do after being granted the lock (the
1242  * grantor did it all). We do have to worry about canceling the deadlock
1243  * timeout and updating the locallock table, but if we lose control to an
1244  * error, LockErrorCleanup will fix that up.
1245  */
1246  do
1247  {
1248  if (InHotStandby)
1249  {
1250  /* Set a timer and wait for that or for the Lock to be granted */
1252  }
1253  else
1254  {
1256  PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1258  /* check for deadlocks first, as that's probably log-worthy */
1260  {
1261  CheckDeadLock();
1262  got_deadlock_timeout = false;
1263  }
1265  }
1266 
1267  /*
1268  * waitStatus could change from STATUS_WAITING to something else
1269  * asynchronously. Read it just once per loop to prevent surprising
1270  * behavior (such as missing log messages).
1271  */
1272  myWaitStatus = *((volatile int *) &MyProc->waitStatus);
1273 
1274  /*
1275  * If we are not deadlocked, but are waiting on an autovacuum-induced
1276  * task, send a signal to interrupt it.
1277  */
1278  if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
1279  {
1280  PGPROC *autovac = GetBlockingAutoVacuumPgproc();
1281  PGXACT *autovac_pgxact = &ProcGlobal->allPgXact[autovac->pgprocno];
1282 
1283  LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1284 
1285  /*
1286  * Only do it if the worker is not working to protect against Xid
1287  * wraparound.
1288  */
1289  if ((autovac_pgxact->vacuumFlags & PROC_IS_AUTOVACUUM) &&
1290  !(autovac_pgxact->vacuumFlags & PROC_VACUUM_FOR_WRAPAROUND))
1291  {
1292  int pid = autovac->pid;
1293  StringInfoData locktagbuf;
1294  StringInfoData logbuf; /* errdetail for server log */
1295 
1296  initStringInfo(&locktagbuf);
1297  initStringInfo(&logbuf);
1298  DescribeLockTag(&locktagbuf, &lock->tag);
1299  appendStringInfo(&logbuf,
1300  _("Process %d waits for %s on %s."),
1301  MyProcPid,
1303  lockmode),
1304  locktagbuf.data);
1305 
1306  /* release lock as quickly as possible */
1307  LWLockRelease(ProcArrayLock);
1308 
1309  /* send the autovacuum worker Back to Old Kent Road */
1310  ereport(DEBUG1,
1311  (errmsg("sending cancel to blocking autovacuum PID %d",
1312  pid),
1313  errdetail_log("%s", logbuf.data)));
1314 
1315  if (kill(pid, SIGINT) < 0)
1316  {
1317  /*
1318  * There's a race condition here: once we release the
1319  * ProcArrayLock, it's possible for the autovac worker to
1320  * close up shop and exit before we can do the kill().
1321  * Therefore, we do not whinge about no-such-process.
1322  * Other errors such as EPERM could conceivably happen if
1323  * the kernel recycles the PID fast enough, but such cases
1324  * seem improbable enough that it's probably best to issue
1325  * a warning if we see some other errno.
1326  */
1327  if (errno != ESRCH)
1328  ereport(WARNING,
1329  (errmsg("could not send signal to process %d: %m",
1330  pid)));
1331  }
1332 
1333  pfree(logbuf.data);
1334  pfree(locktagbuf.data);
1335  }
1336  else
1337  LWLockRelease(ProcArrayLock);
1338 
1339  /* prevent signal from being resent more than once */
1340  allow_autovacuum_cancel = false;
1341  }
1342 
1343  /*
1344  * If awoken after the deadlock check interrupt has run, and
1345  * log_lock_waits is on, then report about the wait.
1346  */
1348  {
1350  lock_waiters_sbuf,
1351  lock_holders_sbuf;
1352  const char *modename;
1353  long secs;
1354  int usecs;
1355  long msecs;
1356  SHM_QUEUE *procLocks;
1357  PROCLOCK *proclock;
1358  bool first_holder = true,
1359  first_waiter = true;
1360  int lockHoldersNum = 0;
1361 
1362  initStringInfo(&buf);
1363  initStringInfo(&lock_waiters_sbuf);
1364  initStringInfo(&lock_holders_sbuf);
1365 
1366  DescribeLockTag(&buf, &locallock->tag.lock);
1367  modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1368  lockmode);
1371  &secs, &usecs);
1372  msecs = secs * 1000 + usecs / 1000;
1373  usecs = usecs % 1000;
1374 
1375  /*
1376  * we loop over the lock's procLocks to gather a list of all
1377  * holders and waiters. Thus we will be able to provide more
1378  * detailed information for lock debugging purposes.
1379  *
1380  * lock->procLocks contains all processes which hold or wait for
1381  * this lock.
1382  */
1383 
1384  LWLockAcquire(partitionLock, LW_SHARED);
1385 
1386  procLocks = &(lock->procLocks);
1387  proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
1388  offsetof(PROCLOCK, lockLink));
1389 
1390  while (proclock)
1391  {
1392  /*
1393  * we are a waiter if myProc->waitProcLock == proclock; we are
1394  * a holder if it is NULL or something different
1395  */
1396  if (proclock->tag.myProc->waitProcLock == proclock)
1397  {
1398  if (first_waiter)
1399  {
1400  appendStringInfo(&lock_waiters_sbuf, "%d",
1401  proclock->tag.myProc->pid);
1402  first_waiter = false;
1403  }
1404  else
1405  appendStringInfo(&lock_waiters_sbuf, ", %d",
1406  proclock->tag.myProc->pid);
1407  }
1408  else
1409  {
1410  if (first_holder)
1411  {
1412  appendStringInfo(&lock_holders_sbuf, "%d",
1413  proclock->tag.myProc->pid);
1414  first_holder = false;
1415  }
1416  else
1417  appendStringInfo(&lock_holders_sbuf, ", %d",
1418  proclock->tag.myProc->pid);
1419 
1420  lockHoldersNum++;
1421  }
1422 
1423  proclock = (PROCLOCK *) SHMQueueNext(procLocks, &proclock->lockLink,
1424  offsetof(PROCLOCK, lockLink));
1425  }
1426 
1427  LWLockRelease(partitionLock);
1428 
1430  ereport(LOG,
1431  (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1432  MyProcPid, modename, buf.data, msecs, usecs),
1433  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1434  "Processes holding the lock: %s. Wait queue: %s.",
1435  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1436  else if (deadlock_state == DS_HARD_DEADLOCK)
1437  {
1438  /*
1439  * This message is a bit redundant with the error that will be
1440  * reported subsequently, but in some cases the error report
1441  * might not make it to the log (eg, if it's caught by an
1442  * exception handler), and we want to ensure all long-wait
1443  * events get logged.
1444  */
1445  ereport(LOG,
1446  (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1447  MyProcPid, modename, buf.data, msecs, usecs),
1448  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1449  "Processes holding the lock: %s. Wait queue: %s.",
1450  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1451  }
1452 
1453  if (myWaitStatus == STATUS_WAITING)
1454  ereport(LOG,
1455  (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1456  MyProcPid, modename, buf.data, msecs, usecs),
1457  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1458  "Processes holding the lock: %s. Wait queue: %s.",
1459  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1460  else if (myWaitStatus == STATUS_OK)
1461  ereport(LOG,
1462  (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1463  MyProcPid, modename, buf.data, msecs, usecs)));
1464  else
1465  {
1466  Assert(myWaitStatus == STATUS_ERROR);
1467 
1468  /*
1469  * Currently, the deadlock checker always kicks its own
1470  * process, which means that we'll only see STATUS_ERROR when
1471  * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
1472  * print redundant messages. But for completeness and
1473  * future-proofing, print a message if it looks like someone
1474  * else kicked us off the lock.
1475  */
1477  ereport(LOG,
1478  (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1479  MyProcPid, modename, buf.data, msecs, usecs),
1480  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1481  "Processes holding the lock: %s. Wait queue: %s.",
1482  lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1483  }
1484 
1485  /*
1486  * At this point we might still need to wait for the lock. Reset
1487  * state so we don't print the above messages again.
1488  */
1490 
1491  pfree(buf.data);
1492  pfree(lock_holders_sbuf.data);
1493  pfree(lock_waiters_sbuf.data);
1494  }
1495  } while (myWaitStatus == STATUS_WAITING);
1496 
1497  /*
1498  * Disable the timers, if they are still running. As in LockErrorCleanup,
1499  * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1500  * already caused QueryCancelPending to become set, we want the cancel to
1501  * be reported as a lock timeout, not a user cancel.
1502  */
1503  if (!InHotStandby)
1504  {
1505  if (LockTimeout > 0)
1506  {
1507  DisableTimeoutParams timeouts[2];
1508 
1509  timeouts[0].id = DEADLOCK_TIMEOUT;
1510  timeouts[0].keep_indicator = false;
1511  timeouts[1].id = LOCK_TIMEOUT;
1512  timeouts[1].keep_indicator = true;
1513  disable_timeouts(timeouts, 2);
1514  }
1515  else
1517  }
1518 
1519  /*
1520  * Re-acquire the lock table's partition lock. We have to do this to hold
1521  * off cancel/die interrupts before we can mess with lockAwaited (else we
1522  * might have a missed or duplicated locallock update).
1523  */
1524  LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1525 
1526  /*
1527  * We no longer want LockErrorCleanup to do anything.
1528  */
1529  lockAwaited = NULL;
1530 
1531  /*
1532  * If we got the lock, be sure to remember it in the locallock table.
1533  */
1534  if (MyProc->waitStatus == STATUS_OK)
1535  GrantAwaitedLock();
1536 
1537  /*
1538  * We don't have to do anything else, because the awaker did all the
1539  * necessary update of the lock table and MyProc.
1540  */
1541  return MyProc->waitStatus;
1542 }
TimestampTz get_timeout_start_time(TimeoutId id)
Definition: timeout.c:653
PROCLOCKTAG tag
Definition: lock.h:348
void ResolveRecoveryConflictWithLock(LOCKTAG locktag)
Definition: standby.c:362
uint32 hashcode
Definition: lock.h:410
#define PG_WAIT_LOCK
Definition: pgstat.h:738
Definition: lwlock.h:32
TimeoutId id
Definition: timeout.h:54
int LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1292
LOCALLOCKTAG tag
Definition: lock.h:405
#define DEBUG1
Definition: elog.h:25
int MyProcPid
Definition: globals.c:38
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:3845
LOCKTAG lock
Definition: lock.h:386
void GrantAwaitedLock(void)
Definition: lock.c:1643
Definition: proc.h:207
int LOCKMODE
Definition: lockdefs.h:26
LOCKMODE mode
Definition: lock.h:387
PROCLOCK * proclock
Definition: lock.h:409
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
SHM_QUEUE links
Definition: lock.h:32
PGXACT * allPgXact
Definition: proc.h:234
PGPROC * MyProc
Definition: proc.c:67
LOCKMASK holdMask
Definition: lock.h:352
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1415
SHM_QUEUE links
Definition: proc.h:97
TimeoutType type
Definition: timeout.h:55
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:137
bool InRecovery
Definition: xlog.c:192
LOCKTAG tag
Definition: lock.h:288
#define PROC_VACUUM_FOR_WRAPAROUND
Definition: proc.h:55
const LOCKMASK * conflictTab
Definition: lock.h:115
#define LockHashPartitionLock(hashcode)
Definition: lock.h:498
SHM_QUEUE lockLink
Definition: lock.h:354
#define InHotStandby
Definition: xlog.h:74
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define STATUS_ERROR
Definition: c.h:976
void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
Definition: shmqueue.c:89
void ResetLatch(volatile Latch *latch)
Definition: latch.c:498
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7873
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:561
PROC_QUEUE waitProcs
Definition: lock.h:294
uint8 vacuumFlags
Definition: proc.h:218
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
Definition: deadlock.c:1149
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:336
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:476
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
static DeadLockState deadlock_state
Definition: proc.c:87
TimeoutId id
Definition: timeout.h:65
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:954
PROCLOCK * waitProcLock
Definition: proc.h:136
static char * buf
Definition: pg_test_fsync.c:66
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:90
unsigned int uint32
Definition: c.h:268
int errdetail_log(const char *fmt,...)
Definition: elog.c:921
void CheckRecoveryConflictDeadlock(void)
Definition: standby.c:515
Definition: lock.h:285
LOCK * waitLock
Definition: proc.h:135
#define ereport(elevel, rest)
Definition: elog.h:122
#define STATUS_OK
Definition: c.h:975
LOCKMASK waitMask
Definition: lock.h:292
SHM_QUEUE procLocks
Definition: lock.h:293
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define WARNING
Definition: elog.h:40
Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, Size linkOffset)
Definition: shmqueue.c:145
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1761
int waitStatus
Definition: proc.h:101
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:942
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:428
uint8 locktag_type
Definition: lock.h:185
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool log_lock_waits
Definition: proc.c:64
static LOCALLOCK * lockAwaited
Definition: proc.c:85
int LockTimeout
Definition: proc.c:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
LOCK * lock
Definition: lock.h:408
int LOCKMASK
Definition: lockdefs.h:25
static void CheckDeadLock(void)
Definition: proc.c:1656
uint8 locktag_lockmethodid
Definition: lock.h:186
PGPROC * myProc
Definition: lock.h:342
#define LOCKBIT_ON(lockmode)
Definition: lock.h:88
Definition: lock.h:345
int pgprocno
Definition: proc.h:109
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
int size
Definition: lock.h:33
struct Latch * MyLatch
Definition: globals.c:51
int DeadlockTimeout
Definition: proc.c:60
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define STATUS_WAITING
Definition: c.h:979
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition: deadlock.c:293
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:525
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1624
Definition: proc.h:94
int pid
Definition: proc.h:108
#define WL_LATCH_SET
Definition: latch.h:124
#define _(x)
Definition: elog.c:84
PGPROC * lockGroupLeader
Definition: proc.h:188
#define PROC_IS_AUTOVACUUM
Definition: proc.h:52
#define offsetof(type, field)
Definition: c.h:555
LOCKMASK heldLocks
Definition: proc.h:138
PGPROC * groupLeader
Definition: lock.h:351
void ProcWaitForSignal ( uint32  wait_event_info)

Definition at line 1766 of file proc.c.

References CHECK_FOR_INTERRUPTS, MyLatch, ResetLatch(), WaitLatch(), and WL_LATCH_SET.

Referenced by GetSafeSnapshot(), LockBufferForCleanup(), ResolveRecoveryConflictWithBufferPin(), and ResolveRecoveryConflictWithLock().

1767 {
1768  WaitLatch(MyLatch, WL_LATCH_SET, 0, wait_event_info);
1771 }
void ResetLatch(volatile Latch *latch)
Definition: latch.c:498
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:336
struct Latch * MyLatch
Definition: globals.c:51
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define WL_LATCH_SET
Definition: latch.h:124
PGPROC* ProcWakeup ( PGPROC proc,
int  waitStatus 
)

Definition at line 1559 of file proc.c.

References Assert, PGPROC::links, SHM_QUEUE::next, NULL, SHM_QUEUE::prev, PGPROC::procLatch, SetLatch(), SHMQueueDelete(), PROC_QUEUE::size, STATUS_WAITING, PGPROC::waitLock, PGPROC::waitProcLock, LOCK::waitProcs, and PGPROC::waitStatus.

Referenced by ProcLockWakeup().

1560 {
1561  PGPROC *retProc;
1562 
1563  /* Proc should be sleeping ... */
1564  if (proc->links.prev == NULL ||
1565  proc->links.next == NULL)
1566  return NULL;
1567  Assert(proc->waitStatus == STATUS_WAITING);
1568 
1569  /* Save next process before we zap the list link */
1570  retProc = (PGPROC *) proc->links.next;
1571 
1572  /* Remove process from wait queue */
1573  SHMQueueDelete(&(proc->links));
1574  (proc->waitLock->waitProcs.size)--;
1575 
1576  /* Clean up process' state and pass it the ok/fail signal */
1577  proc->waitLock = NULL;
1578  proc->waitProcLock = NULL;
1579  proc->waitStatus = waitStatus;
1580 
1581  /* And awaken it */
1582  SetLatch(&proc->procLatch);
1583 
1584  return retProc;
1585 }
SHM_QUEUE links
Definition: proc.h:97
struct SHM_QUEUE * next
Definition: shmem.h:31
Latch procLatch
Definition: proc.h:103
PROC_QUEUE waitProcs
Definition: lock.h:294
PROCLOCK * waitProcLock
Definition: proc.h:136
LOCK * waitLock
Definition: proc.h:135
int waitStatus
Definition: proc.h:101
void SetLatch(volatile Latch *latch)
Definition: latch.c:415
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
int size
Definition: lock.h:33
void SHMQueueDelete(SHM_QUEUE *queue)
Definition: shmqueue.c:68
#define STATUS_WAITING
Definition: c.h:979
Definition: proc.h:94
void PublishStartupProcessInformation ( void  )

Definition at line 593 of file proc.c.

References MyProc, MyProcPid, ProcStructLock, SpinLockAcquire, SpinLockRelease, PROC_HDR::startupProc, and PROC_HDR::startupProcPid.

Referenced by StartupXLOG().

594 {
596 
599 
601 }
int MyProcPid
Definition: globals.c:38
PGPROC * MyProc
Definition: proc.c:67
PROC_HDR * ProcGlobal
Definition: proc.c:80
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:253
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
PGPROC * startupProc
Definition: proc.h:252
static void RemoveProcFromArray ( int  code,
Datum  arg 
)
static

Definition at line 770 of file proc.c.

References Assert, InvalidTransactionId, NULL, and ProcArrayRemove().

Referenced by InitProcessPhase2().

771 {
772  Assert(MyProc != NULL);
774 }
PGPROC * MyProc
Definition: proc.c:67
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:332
#define InvalidTransactionId
Definition: transam.h:31
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void SetStartupBufferPinWaitBufId ( int  bufid)

Definition at line 611 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

612 {
613  /* use volatile pointer to prevent code rearrangement */
614  volatile PROC_HDR *procglobal = ProcGlobal;
615 
616  procglobal->startupBufferPinWaitBufId = bufid;
617 }
PROC_HDR * ProcGlobal
Definition: proc.c:80
Definition: proc.h:229
int startupBufferPinWaitBufId
Definition: proc.h:255

Variable Documentation

NON_EXEC_STATIC PGPROC* AuxiliaryProcs = NULL
DeadLockState deadlock_state = DS_NOT_YET_CHECKED
static

Definition at line 87 of file proc.c.

Referenced by CheckDeadLock(), and ProcSleep().

int DeadlockTimeout = 1000

Definition at line 60 of file proc.c.

Referenced by ProcSleep(), and ResolveRecoveryConflictWithBufferPin().

volatile sig_atomic_t got_deadlock_timeout
static

Definition at line 90 of file proc.c.

Referenced by CheckDeadLockAlert(), and ProcSleep().

int IdleInTransactionSessionTimeout = 0

Definition at line 63 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

LOCALLOCK* lockAwaited = NULL
static

Definition at line 85 of file proc.c.

int LockTimeout = 0

Definition at line 62 of file proc.c.

Referenced by ProcSleep().

bool log_lock_waits = false

Definition at line 64 of file proc.c.

Referenced by ProcSleep().

PGPROC* MyProc = NULL

Definition at line 67 of file proc.c.

Referenced by AbortTransaction(), ApplyLauncherMain(), attach_to_queues(), AutoVacWorkerMain(), AuxiliaryProcKill(), BackgroundWriterMain(), BecomeLockGroupLeader(), CheckpointerMain(), CommitTransaction(), ConditionVariableCancelSleep(), ConditionVariablePrepareToSleep(), ConditionVariableSleep(), copy_read_data(), CountOtherDBBackends(), CreateReplicationSlot(), errdetail_abort(), exec_eval_simple_expr(), ExecParallelGetReceiver(), ExecParallelSetupTupleQueues(), FastPathGetRelationLockEntry(), FastPathGrantRelationLock(), FastPathUnGrantRelationLock(), FindLockCycleRecurseMember(), fmgr_sql(), get_cast_hashentry(), GetCurrentVirtualXIDs(), GetLockConflicts(), GetNewTransactionId(), GetSerializableTransactionSnapshotInt(), GetStableLatestTransactionId(), init_sql_fcache(), InitializeParallelDSM(), InitializeSessionUserId(), InitPostgres(), InitWalSenderSlot(), libpqrcv_connect(), libpqrcv_PQexec(), lock_and_open_sequence(), LockAcquireExtended(), LockCheckConflicts(), LockRelease(), LockReleaseAll(), log_line_prefix(), logicalrep_worker_attach(), logicalrep_worker_stop(), LogicalRepApplyLoop(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockAttemptLock(), LWLockDequeueSelf(), LWLockQueueSelf(), LWLockWaitForVar(), MinimumActiveBackends(), mq_putmessage(), ParallelWorkerMain(), pgstat_report_activity(), pgstat_report_wait_end(), pgstat_report_wait_start(), PostPrepare_Locks(), PrepareTransaction(), ProcArrayGroupClearXid(), ProcKill(), PublishStartupProcessInformation(), RecoveryConflictInterrupt(), ReinitializeParallelDSM(), setup_dynamic_shared_memory(), SharedInvalBackendInit(), shm_mq_attach(), shm_mq_detach(), shm_mq_receive(), shm_mq_sendv(), shm_mq_wait_for_attach(), StartTransaction(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepCancelWait(), SyncRepCleanupAtProcExit(), SyncRepQueueInsert(), SyncRepWaitForLSN(), TransactionIdIsInProgress(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), wait_for_sync_status_change(), WaitForBackgroundWorkerShutdown(), WaitForParallelWorkersToFinish(), WaitXLogInsertionsToFinish(), WALInsertLockAcquire(), WalReceiverMain(), WalWriterMain(), write_csvlog(), and XidCacheRemoveRunningXids().

PGPROC* PreparedXactProcs = NULL

Definition at line 82 of file proc.c.

Referenced by TwoPhaseShmemInit().

int StatementTimeout = 0

Definition at line 61 of file proc.c.

Referenced by start_xact_command().