PostgreSQL Source Code  git master
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 "replication/walsender.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

◆ AuxiliaryPidGetProc()

PGPROC* AuxiliaryPidGetProc ( int  pid)

Definition at line 986 of file proc.c.

References AuxiliaryProcs, name, NUM_AUXILIARY_PROCS, PGPROC::pid, ProcQueueInit(), and ShmemInitStruct().

Referenced by pg_stat_get_activity().

987 {
988  PGPROC *result = NULL;
989  int index;
990 
991  if (pid == 0) /* never match dummy PGPROCs */
992  return NULL;
993 
994  for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
995  {
996  PGPROC *proc = &AuxiliaryProcs[index];
997 
998  if (proc->pid == pid)
999  {
1000  result = proc;
1001  break;
1002  }
1003  }
1004  return result;
1005 }
Definition: type.h:89
#define NUM_AUXILIARY_PROCS
Definition: proc.h:292
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:82
Definition: proc.h:95
int pid
Definition: proc.h:109

◆ AuxiliaryProcKill()

static void AuxiliaryProcKill ( int  code,
Datum  arg 
)
static

Definition at line 939 of file proc.c.

References Assert, AuxiliaryProcs, ConditionVariableCancelSleep(), DatumGetInt32, DisownLatch(), LWLockReleaseAll(), MyProc, 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().

940 {
941  int proctype = DatumGetInt32(arg);
943  PGPROC *proc;
944 
945  Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
946 
947  auxproc = &AuxiliaryProcs[proctype];
948 
949  Assert(MyProc == auxproc);
950 
951  /* Release any LW locks I am holding (see notes above) */
953 
954  /* Cancel any pending condition variable sleep, too */
956 
957  /*
958  * Reset MyLatch to the process local one. This is so that signal
959  * handlers et al can continue using the latch after the shared latch
960  * isn't ours anymore. After that clear MyProc and disown the shared
961  * latch.
962  */
964  proc = MyProc;
965  MyProc = NULL;
966  DisownLatch(&proc->procLatch);
967 
969 
970  /* Mark auxiliary proc no longer in use */
971  proc->pid = 0;
972 
973  /* Update shared estimate of spins_per_delay */
975 
977 }
#define DatumGetInt32(X)
Definition: postgres.h:472
PGPROC * MyProc
Definition: proc.c:68
PROC_HDR * ProcGlobal
Definition: proc.c:81
Latch procLatch
Definition: proc.h:104
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:361
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:269
#define NUM_AUXILIARY_PROCS
Definition: proc.h:292
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:78
#define Assert(condition)
Definition: c.h:732
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:82
void DisownLatch(volatile Latch *latch)
Definition: latch.c:316
void * arg
void LWLockReleaseAll(void)
Definition: lwlock.c:1824
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
Definition: proc.h:95
int pid
Definition: proc.h:109

◆ BecomeLockGroupLeader()

void BecomeLockGroupLeader ( void  )

Definition at line 1851 of file proc.c.

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

Referenced by LaunchParallelWorkers().

1852 {
1853  LWLock *leader_lwlock;
1854 
1855  /* If we already did it, we don't need to do it again. */
1856  if (MyProc->lockGroupLeader == MyProc)
1857  return;
1858 
1859  /* We had better not be a follower. */
1860  Assert(MyProc->lockGroupLeader == NULL);
1861 
1862  /* Create single-member group, containing only ourselves. */
1863  leader_lwlock = LockHashPartitionLockByProc(MyProc);
1864  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1867  LWLockRelease(leader_lwlock);
1868 }
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:204
PGPROC * MyProc
Definition: proc.c:68
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
dlist_node lockGroupLink
Definition: proc.h:205
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:514
#define Assert(condition)
Definition: c.h:732
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
PGPROC * lockGroupLeader
Definition: proc.h:203

◆ BecomeLockGroupMember()

bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)

Definition at line 1881 of file proc.c.

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

Referenced by ParallelWorkerMain().

1882 {
1883  LWLock *leader_lwlock;
1884  bool ok = false;
1885 
1886  /* Group leader can't become member of group */
1887  Assert(MyProc != leader);
1888 
1889  /* Can't already be a member of a group */
1890  Assert(MyProc->lockGroupLeader == NULL);
1891 
1892  /* PID must be valid. */
1893  Assert(pid != 0);
1894 
1895  /*
1896  * Get lock protecting the group fields. Note LockHashPartitionLockByProc
1897  * accesses leader->pgprocno in a PGPROC that might be free. This is safe
1898  * because all PGPROCs' pgprocno fields are set during shared memory
1899  * initialization and never change thereafter; so we will acquire the
1900  * correct lock even if the leader PGPROC is in process of being recycled.
1901  */
1902  leader_lwlock = LockHashPartitionLockByProc(leader);
1903  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1904 
1905  /* Is this the leader we're looking for? */
1906  if (leader->pid == pid && leader->lockGroupLeader == leader)
1907  {
1908  /* OK, join the group */
1909  ok = true;
1910  MyProc->lockGroupLeader = leader;
1912  }
1913  LWLockRelease(leader_lwlock);
1914 
1915  return ok;
1916 }
Definition: lwlock.h:32
dlist_head lockGroupMembers
Definition: proc.h:204
PGPROC * MyProc
Definition: proc.c:68
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:317
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
dlist_node lockGroupLink
Definition: proc.h:205
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:514
#define Assert(condition)
Definition: c.h:732
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int pid
Definition: proc.h:109
PGPROC * lockGroupLeader
Definition: proc.h:203

◆ CheckDeadLock()

static void CheckDeadLock ( void  )
static

Definition at line 1691 of file proc.c.

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

Referenced by ProcSleep().

1692 {
1693  int i;
1694 
1695  /*
1696  * Acquire exclusive lock on the entire shared lock data structures. Must
1697  * grab LWLocks in partition-number order to avoid LWLock deadlock.
1698  *
1699  * Note that the deadlock check interrupt had better not be enabled
1700  * anywhere that this process itself holds lock partition locks, else this
1701  * will wait forever. Also note that LWLockAcquire creates a critical
1702  * section, so that this routine cannot be interrupted by cancel/die
1703  * interrupts.
1704  */
1705  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1707 
1708  /*
1709  * Check to see if we've been awoken by anyone in the interim.
1710  *
1711  * If we have, we can return and resume our transaction -- happy day.
1712  * Before we are awoken the process releasing the lock grants it to us so
1713  * we know that we don't have to wait anymore.
1714  *
1715  * We check by looking to see if we've been unlinked from the wait queue.
1716  * This is quicker than checking our semaphore's state, since no kernel
1717  * call is needed, and it is safe because we hold the lock partition lock.
1718  */
1719  if (MyProc->links.prev == NULL ||
1720  MyProc->links.next == NULL)
1721  goto check_done;
1722 
1723 #ifdef LOCK_DEBUG
1724  if (Debug_deadlocks)
1725  DumpAllLocks();
1726 #endif
1727 
1728  /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
1730 
1732  {
1733  /*
1734  * Oops. We have a deadlock.
1735  *
1736  * Get this process out of wait state. (Note: we could do this more
1737  * efficiently by relying on lockAwaited, but use this coding to
1738  * preserve the flexibility to kill some other transaction than the
1739  * one detecting the deadlock.)
1740  *
1741  * RemoveFromWaitQueue sets MyProc->waitStatus to STATUS_ERROR, so
1742  * ProcSleep will report an error after we return from the signal
1743  * handler.
1744  */
1745  Assert(MyProc->waitLock != NULL);
1747 
1748  /*
1749  * We're done here. Transaction abort caused by the error that
1750  * ProcSleep will raise will cause any other locks we hold to be
1751  * released, thus allowing other processes to wake up; we don't need
1752  * to do that here. NOTE: an exception is that releasing locks we
1753  * hold doesn't consider the possibility of waiters that were blocked
1754  * behind us on the lock we just failed to get, and might now be
1755  * wakable because we're not in front of them anymore. However,
1756  * RemoveFromWaitQueue took care of waking up any such processes.
1757  */
1758  }
1759 
1760  /*
1761  * And release locks. We do this in reverse order for two reasons: (1)
1762  * Anyone else who needs more than one of the locks will be trying to lock
1763  * them in increasing order; we don't want to release the other process
1764  * until it can get all the locks it needs. (2) This avoids O(N^2)
1765  * behavior inside LWLockRelease.
1766  */
1767 check_done:
1768  for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1770 }
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKTAG tag
Definition: lock.h:287
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define LockHashPartitionLockByIndex(i)
Definition: lock.h:502
static DeadLockState deadlock_state
Definition: proc.c:88
DeadLockState DeadLockCheck(PGPROC *proc)
Definition: deadlock.c:217
LOCK * waitLock
Definition: proc.h:139
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition: lock.c:490
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1827
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define Assert(condition)
Definition: c.h:732
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int i
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117

◆ CheckDeadLockAlert()

void CheckDeadLockAlert ( void  )

Definition at line 1778 of file proc.c.

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres().

1779 {
1780  int save_errno = errno;
1781 
1782  got_deadlock_timeout = true;
1783 
1784  /*
1785  * Have to set the latch again, even if handle_sig_alarm already did. Back
1786  * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1787  * ever would be a problem, but setting a set latch again is cheap.
1788  */
1789  SetLatch(MyLatch);
1790  errno = save_errno;
1791 }
static volatile sig_atomic_t got_deadlock_timeout
Definition: proc.c:91
void SetLatch(volatile Latch *latch)
Definition: latch.c:436
struct Latch * MyLatch
Definition: globals.c:54

◆ GetStartupBufferPinWaitBufId()

int GetStartupBufferPinWaitBufId ( void  )

Definition at line 658 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery().

659 {
660  /* use volatile pointer to prevent code rearrangement */
661  volatile PROC_HDR *procglobal = ProcGlobal;
662 
663  return procglobal->startupBufferPinWaitBufId;
664 }
PROC_HDR * ProcGlobal
Definition: proc.c:81
Definition: proc.h:244
int startupBufferPinWaitBufId
Definition: proc.h:274

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n)

Definition at line 672 of file proc.c.

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

Referenced by InitPostgres().

673 {
674  PGPROC *proc;
675 
677 
678  proc = ProcGlobal->freeProcs;
679 
680  while (n > 0 && proc != NULL)
681  {
682  proc = (PGPROC *) proc->links.next;
683  n--;
684  }
685 
687 
688  return (n <= 0);
689 }
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:81
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:78
PGPROC * freeProcs
Definition: proc.h:253
Definition: proc.h:95

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )

Definition at line 516 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, 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(), PGPROC::tempNamespaceId, PGXACT::vacuumFlags, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStatus, PGXACT::xid, and PGXACT::xmin.

Referenced by AuxiliaryProcessMain(), and BackendRun().

517 {
518  PGPROC *auxproc;
519  int proctype;
520 
521  /*
522  * ProcGlobal should be set up already (if we are a backend, we inherit
523  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
524  */
525  if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
526  elog(PANIC, "proc header uninitialized");
527 
528  if (MyProc != NULL)
529  elog(ERROR, "you already exist");
530 
531  /*
532  * We use the ProcStructLock to protect assignment and releasing of
533  * AuxiliaryProcs entries.
534  *
535  * While we are holding the ProcStructLock, also copy the current shared
536  * estimate of spins_per_delay to local storage.
537  */
539 
541 
542  /*
543  * Find a free auxproc ... *big* trouble if there isn't one ...
544  */
545  for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
546  {
547  auxproc = &AuxiliaryProcs[proctype];
548  if (auxproc->pid == 0)
549  break;
550  }
551  if (proctype >= NUM_AUXILIARY_PROCS)
552  {
554  elog(FATAL, "all AuxiliaryProcs are in use");
555  }
556 
557  /* Mark auxiliary proc as in use by me */
558  /* use volatile pointer to prevent code rearrangement */
559  ((volatile PGPROC *) auxproc)->pid = MyProcPid;
560 
561  MyProc = auxproc;
562  MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno];
563 
565 
566  /*
567  * Initialize all fields of MyProc, except for those previously
568  * initialized by InitProcGlobal.
569  */
573  MyProc->fpVXIDLock = false;
582  MyPgXact->delayChkpt = false;
583  MyPgXact->vacuumFlags = 0;
584  MyProc->lwWaiting = false;
585  MyProc->lwWaitMode = 0;
586  MyProc->waitLock = NULL;
587  MyProc->waitProcLock = NULL;
588 #ifdef USE_ASSERT_CHECKING
589  {
590  int i;
591 
592  /* Last process should have released all locks. */
593  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
595  }
596 #endif
597 
598  /*
599  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
600  * on it. That allows us to repoint the process latch, which so far
601  * points to process local one, to the shared one.
602  */
605 
606  /* Check that group locking fields are in a proper initial state. */
607  Assert(MyProc->lockGroupLeader == NULL);
609 
610  /*
611  * We might be reusing a semaphore that belonged to a failed process. So
612  * be careful and reinitialize its value here. (This is not strictly
613  * necessary anymore, but seems like a good idea for cleanliness.)
614  */
616 
617  /*
618  * Arrange to clean up at process exit.
619  */
621 }
static void AuxiliaryProcKill(int code, Datum arg)
Definition: proc.c:939
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:196
int MyProcPid
Definition: globals.c:40
BackendId backendId
Definition: proc.h:113
dlist_head lockGroupMembers
Definition: proc.h:204
Oid tempNamespaceId
Definition: proc.h:117
TransactionId xmin
Definition: proc.h:228
PGXACT * allPgXact
Definition: proc.h:249
PGPROC * MyProc
Definition: proc.c:68
TransactionId xid
Definition: proc.h:224
SHM_QUEUE links
Definition: proc.h:98
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:284
bool lwWaiting
Definition: proc.h:130
Oid roleId
Definition: proc.h:115
PROC_HDR * ProcGlobal
Definition: proc.c:81
uint8 lwWaitMode
Definition: proc.h:131
bool fpVXIDLock
Definition: proc.h:195
#define PANIC
Definition: elog.h:53
Latch procLatch
Definition: proc.h:104
PGXACT * MyPgXact
Definition: proc.c:69
uint8 vacuumFlags
Definition: proc.h:233
bool IsBackgroundWorker
Definition: globals.c:111
bool isBackgroundWorker
Definition: proc.h:120
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:269
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:140
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
#define InvalidTransactionId
Definition: transam.h:31
Oid databaseId
Definition: proc.h:114
void OwnLatch(volatile Latch *latch)
Definition: latch.c:296
LOCK * waitLock
Definition: proc.h:139
#define NUM_AUXILIARY_PROCS
Definition: proc.h:292
#define STATUS_OK
Definition: c.h:1075
bool delayChkpt
Definition: proc.h:235
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:78
void SwitchToSharedLatch(void)
Definition: miscinit.c:342
int waitStatus
Definition: proc.h:102
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:732
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:82
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:479
int pgprocno
Definition: proc.h:110
#define elog(elevel,...)
Definition: elog.h:226
#define InvalidLocalTransactionId
Definition: lock.h:69
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:160
PGSemaphore sem
Definition: proc.h:101
Definition: proc.h:95
int pid
Definition: proc.h:109
PGPROC * lockGroupLeader
Definition: proc.h:203
LocalTransactionId fpLocalTransactionId
Definition: proc.h:196
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
LocalTransactionId lxid
Definition: proc.h:106

◆ InitProcess()

void InitProcess ( void  )

Definition at line 305 of file proc.c.

References PROC_HDR::allPgXact, am_walsender, Assert, PROC_HDR::autovacFreeProcs, PGPROC::backendId, PROC_HDR::bgworkerFreeProcs, PGPROC::clogGroupMember, PGPROC::clogGroupMemberLsn, PGPROC::clogGroupMemberPage, PGPROC::clogGroupMemberXid, PGPROC::clogGroupMemberXidStatus, PGPROC::clogGroupNext, 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, InvalidXLogRecPtr, IsAnyAutoVacuumProcess, IsAutoVacuumLauncherProcess(), IsAutoVacuumWorkerProcess(), IsBackgroundWorker, PGPROC::isBackgroundWorker, IsUnderPostmaster, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupMembers, PGPROC::lwWaiting, PGPROC::lwWaitMode, PGPROC::lxid, MarkPostmasterChildActive(), max_wal_senders, PGPROC::myProcLocks, MyProcPid, SHM_QUEUE::next, NUM_LOCK_PARTITIONS, on_shmem_exit(), OwnLatch(), PANIC, pg_atomic_read_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, PGPROC::tempNamespaceId, TRANSACTION_STATUS_IN_PROGRESS, PGXACT::vacuumFlags, PGPROC::wait_event_info, PGPROC::waitLock, PGPROC::waitLSN, PGPROC::waitProcLock, PGPROC::waitStatus, PROC_HDR::walsenderFreeProcs, PGXACT::xid, and PGXACT::xmin.

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

306 {
307  PGPROC *volatile *procgloballist;
308 
309  /*
310  * ProcGlobal should be set up already (if we are a backend, we inherit
311  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
312  */
313  if (ProcGlobal == NULL)
314  elog(PANIC, "proc header uninitialized");
315 
316  if (MyProc != NULL)
317  elog(ERROR, "you already exist");
318 
319  /* Decide which list should supply our PGPROC. */
321  procgloballist = &ProcGlobal->autovacFreeProcs;
322  else if (IsBackgroundWorker)
323  procgloballist = &ProcGlobal->bgworkerFreeProcs;
324  else if (am_walsender)
325  procgloballist = &ProcGlobal->walsenderFreeProcs;
326  else
327  procgloballist = &ProcGlobal->freeProcs;
328 
329  /*
330  * Try to get a proc struct from the appropriate free list. If this
331  * fails, we must be out of PGPROC structures (not to mention semaphores).
332  *
333  * While we are holding the ProcStructLock, also copy the current shared
334  * estimate of spins_per_delay to local storage.
335  */
337 
339 
340  MyProc = *procgloballist;
341 
342  if (MyProc != NULL)
343  {
344  *procgloballist = (PGPROC *) MyProc->links.next;
346  }
347  else
348  {
349  /*
350  * If we reach here, all the PGPROCs are in use. This is one of the
351  * possible places to detect "too many backends", so give the standard
352  * error message. XXX do we need to give a different failure message
353  * in the autovacuum case?
354  */
356  if (am_walsender)
357  ereport(FATAL,
358  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
359  errmsg("number of requested standby connections exceeds max_wal_senders (currently %d)",
360  max_wal_senders)));
361  ereport(FATAL,
362  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
363  errmsg("sorry, too many clients already")));
364  }
366 
367  /*
368  * Cross-check that the PGPROC is of the type we expect; if this were not
369  * the case, it would get returned to the wrong list.
370  */
371  Assert(MyProc->procgloballist == procgloballist);
372 
373  /*
374  * Now that we have a PGPROC, mark ourselves as an active postmaster
375  * child; this is so that the postmaster can detect it if we exit without
376  * cleaning up. (XXX autovac launcher currently doesn't participate in
377  * this; it probably should.)
378  */
381 
382  /*
383  * Initialize all fields of MyProc, except for those previously
384  * initialized by InitProcGlobal.
385  */
389  MyProc->fpVXIDLock = false;
393  MyProc->pid = MyProcPid;
394  /* backendId, databaseId and roleId will be filled in later */
400  MyPgXact->delayChkpt = false;
401  MyPgXact->vacuumFlags = 0;
402  /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
405  MyProc->lwWaiting = false;
406  MyProc->lwWaitMode = 0;
407  MyProc->waitLock = NULL;
408  MyProc->waitProcLock = NULL;
409 #ifdef USE_ASSERT_CHECKING
410  {
411  int i;
412 
413  /* Last process should have released all locks. */
414  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
416  }
417 #endif
419 
420  /* Initialize fields for sync rep */
421  MyProc->waitLSN = 0;
424 
425  /* Initialize fields for group XID clearing. */
426  MyProc->procArrayGroupMember = false;
429 
430  /* Check that group locking fields are in a proper initial state. */
431  Assert(MyProc->lockGroupLeader == NULL);
433 
434  /* Initialize wait event information. */
435  MyProc->wait_event_info = 0;
436 
437  /* Initialize fields for group transaction status update. */
438  MyProc->clogGroupMember = false;
444 
445  /*
446  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
447  * on it. That allows us to repoint the process latch, which so far
448  * points to process local one, to the shared one.
449  */
452 
453  /*
454  * We might be reusing a semaphore that belonged to a failed process. So
455  * be careful and reinitialize its value here. (This is not strictly
456  * necessary anymore, but seems like a good idea for cleanliness.)
457  */
459 
460  /*
461  * Arrange to clean up at backend exit.
462  */
464 
465  /*
466  * Now that we have a PGPROC, we could try to acquire locks, so initialize
467  * local state needed for LWLocks, and the deadlock checker.
468  */
471 }
bool procArrayGroupMember
Definition: proc.h:166
static void ProcKill(int code, Datum arg)
Definition: proc.c:816
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XidStatus clogGroupMemberXidStatus
Definition: proc.h:182
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:196
int MyProcPid
Definition: globals.c:40
BackendId backendId
Definition: proc.h:113
uint32 wait_event_info
Definition: proc.h:176
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:186
dlist_head lockGroupMembers
Definition: proc.h:204
Oid tempNamespaceId
Definition: proc.h:117
TransactionId xmin
Definition: proc.h:228
PGXACT * allPgXact
Definition: proc.h:249
PGPROC * MyProc
Definition: proc.c:68
TransactionId xid
Definition: proc.h:224
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:284
bool lwWaiting
Definition: proc.h:130
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:31
PGPROC * bgworkerFreeProcs
Definition: proc.h:257
Oid roleId
Definition: proc.h:115
int errcode(int sqlerrcode)
Definition: elog.c:570
PROC_HDR * ProcGlobal
Definition: proc.c:81
uint8 lwWaitMode
Definition: proc.h:131
pg_atomic_uint32 clogGroupNext
Definition: proc.h:180
bool fpVXIDLock
Definition: proc.h:195
#define PANIC
Definition: elog.h:53
PGPROC * autovacFreeProcs
Definition: proc.h:255
PGPROC * walsenderFreeProcs
Definition: proc.h:259
Latch procLatch
Definition: proc.h:104
PGXACT * MyPgXact
Definition: proc.c:69
uint8 vacuumFlags
Definition: proc.h:233
bool IsBackgroundWorker
Definition: globals.c:111
bool isBackgroundWorker
Definition: proc.h:120
bool am_walsender
Definition: walsender.c:114
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:269
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:140
void InitDeadLockChecking(void)
Definition: deadlock.c:143
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
int clogGroupMemberPage
Definition: proc.h:184
bool recoveryConflictPending
Definition: proc.h:127
bool IsUnderPostmaster
Definition: globals.c:109
#define InvalidTransactionId
Definition: transam.h:31
TransactionId clogGroupMemberXid
Definition: proc.h:181
Oid databaseId
Definition: proc.h:114
PGPROC ** procgloballist
Definition: proc.h:99
void OwnLatch(volatile Latch *latch)
Definition: latch.c:296
LOCK * waitLock
Definition: proc.h:139
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3276
#define ereport(elevel, rest)
Definition: elog.h:141
#define STATUS_OK
Definition: c.h:1075
bool delayChkpt
Definition: proc.h:235
#define INVALID_PGPROCNO
Definition: proc.h:77
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:168
int max_wal_senders
Definition: walsender.c:120
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:78
void SwitchToSharedLatch(void)
Definition: miscinit.c:342
int waitStatus
Definition: proc.h:102
#define InvalidOid
Definition: postgres_ext.h:36
#define IsAnyAutoVacuumProcess()
Definition: autovacuum.h:53
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3270
#define Assert(condition)
Definition: c.h:732
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
PGPROC * freeProcs
Definition: proc.h:253
SHM_QUEUE syncRepLinks
Definition: proc.h:153
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
int pgprocno
Definition: proc.h:110
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool clogGroupMember
Definition: proc.h:179
#define elog(elevel,...)
Definition: elog.h:226
#define InvalidLocalTransactionId
Definition: lock.h:69
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:160
PGSemaphore sem
Definition: proc.h:101
int syncRepState
Definition: proc.h:152
Definition: proc.h:95
int pid
Definition: proc.h:109
XLogRecPtr waitLSN
Definition: proc.h:151
PGPROC * lockGroupLeader
Definition: proc.h:203
LocalTransactionId fpLocalTransactionId
Definition: proc.h:196
#define PROC_IS_AUTOVACUUM
Definition: proc.h:53
TransactionId procArrayGroupMemberXid
Definition: proc.h:174
void InitLWLockAccess(void)
Definition: lwlock.c:535
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:26
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:244
void MarkPostmasterChildActive(void)
Definition: pmsignal.c:256
LocalTransactionId lxid
Definition: proc.h:106

◆ InitProcessPhase2()

void InitProcessPhase2 ( void  )

Definition at line 481 of file proc.c.

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

Referenced by InitPostgres().

482 {
483  Assert(MyProc != NULL);
484 
485  /*
486  * Add our PGPROC to the PGPROC array in shared memory.
487  */
489 
490  /*
491  * Arrange to clean that up at backend exit.
492  */
494 }
static void RemoveProcFromArray(int code, Datum arg)
Definition: proc.c:805
PGPROC * MyProc
Definition: proc.c:68
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
#define Assert(condition)
Definition: c.h:732
void ProcArrayAdd(PGPROC *proc)
Definition: procarray.c:276

◆ InitProcGlobal()

void InitProcGlobal ( void  )

Definition at line 164 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, PROC_HDR::clogGroupFirst, DEFAULT_SPINS_PER_DELAY, dlist_init(), PROC_HDR::freeProcs, i, InitSharedLatch(), INVALID_PGPROCNO, PGPROC::links, LWLockInitialize(), LWTRANCHE_PROC, max_prepared_xacts, max_worker_processes, MaxBackends, MaxConnections, MemSet, SHM_QUEUE::next, 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, PROC_HDR::walsenderFreeProcs, and PROC_HDR::walwriterLatch.

Referenced by CreateSharedMemoryAndSemaphores().

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

◆ IsWaitingForLock()

bool IsWaitingForLock ( void  )

Definition at line 695 of file proc.c.

Referenced by RecoveryConflictInterrupt().

696 {
697  if (lockAwaited == NULL)
698  return false;
699 
700  return true;
701 }
static LOCALLOCK * lockAwaited
Definition: proc.c:86

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )

Definition at line 712 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, RemoveFromWaitQueue(), RESUME_INTERRUPTS, STATUS_OK, and PGPROC::waitStatus.

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

713 {
714  LWLock *partitionLock;
715  DisableTimeoutParams timeouts[2];
716 
717  HOLD_INTERRUPTS();
718 
720 
721  /* Nothing to do if we weren't waiting for a lock */
722  if (lockAwaited == NULL)
723  {
725  return;
726  }
727 
728  /*
729  * Turn off the deadlock and lock timeout timers, if they are still
730  * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
731  * indicator flag, since this function is executed before
732  * ProcessInterrupts when responding to SIGINT; else we'd lose the
733  * knowledge that the SIGINT came from a lock timeout and not an external
734  * source.
735  */
736  timeouts[0].id = DEADLOCK_TIMEOUT;
737  timeouts[0].keep_indicator = false;
738  timeouts[1].id = LOCK_TIMEOUT;
739  timeouts[1].keep_indicator = true;
740  disable_timeouts(timeouts, 2);
741 
742  /* Unlink myself from the wait queue, if on it (might not be anymore!) */
743  partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
744  LWLockAcquire(partitionLock, LW_EXCLUSIVE);
745 
746  if (MyProc->links.next != NULL)
747  {
748  /* We could not have been granted the lock yet */
750  }
751  else
752  {
753  /*
754  * Somebody kicked us off the lock queue already. Perhaps they
755  * granted us the lock, or perhaps they detected a deadlock. If they
756  * did grant us the lock, we'd better remember it in our local lock
757  * table.
758  */
759  if (MyProc->waitStatus == STATUS_OK)
761  }
762 
763  lockAwaited = NULL;
764 
765  LWLockRelease(partitionLock);
766 
768 }
uint32 hashcode
Definition: lock.h:409
Definition: lwlock.h:32
void GrantAwaitedLock(void)
Definition: lock.c:1695
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
#define LockHashPartitionLock(hashcode)
Definition: lock.h:499
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition: timeout.c:561
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:118
TimeoutId id
Definition: timeout.h:65
void AbortStrongLockAcquire(void)
Definition: lock.c:1666
#define STATUS_OK
Definition: c.h:1075
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1827
int waitStatus
Definition: proc.h:102
static LOCALLOCK * lockAwaited
Definition: proc.c:86
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:116

◆ ProcGlobalSemas()

int ProcGlobalSemas ( void  )

Definition at line 129 of file proc.c.

References MaxBackends, and NUM_AUXILIARY_PROCS.

Referenced by CreateSharedMemoryAndSemaphores().

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

◆ ProcGlobalShmemSize()

Size ProcGlobalShmemSize ( void  )

Definition at line 103 of file proc.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

104 {
105  Size size = 0;
106 
107  /* ProcGlobal */
108  size = add_size(size, sizeof(PROC_HDR));
109  /* MyProcs, including autovacuum workers and launcher */
110  size = add_size(size, mul_size(MaxBackends, sizeof(PGPROC)));
111  /* AuxiliaryProcs */
112  size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGPROC)));
113  /* Prepared xacts */
114  size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGPROC)));
115  /* ProcStructLock */
116  size = add_size(size, sizeof(slock_t));
117 
118  size = add_size(size, mul_size(MaxBackends, sizeof(PGXACT)));
119  size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGXACT)));
120  size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGXACT)));
121 
122  return size;
123 }
int slock_t
Definition: s_lock.h:912
Definition: proc.h:222
int max_prepared_xacts
Definition: twophase.c:117
int MaxBackends
Definition: globals.c:135
#define NUM_AUXILIARY_PROCS
Definition: proc.h:292
Definition: proc.h:244
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:466
Definition: proc.h:95

◆ ProcKill()

static void ProcKill ( int  code,
Datum  arg 
)
static

Definition at line 816 of file proc.c.

References Assert, AutovacuumLauncherPid, ConditionVariableCancelSleep(), DisownLatch(), dlist_delete(), dlist_is_empty(), i, IsAutoVacuumLauncherProcess(), IsUnderPostmaster, kill, PGPROC::links, PGPROC::lockGroupLeader, PGPROC::lockGroupLink, PGPROC::lockGroupMembers, LockHashPartitionLockByProc, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), LWLockReleaseAll(), MarkPostmasterChildInactive(), MyProc, PGPROC::myProcLocks, MyReplicationSlot, SHM_QUEUE::next, 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().

817 {
818  PGPROC *proc;
819  PGPROC *volatile *procgloballist;
820 
821  Assert(MyProc != NULL);
822 
823  /* Make sure we're out of the sync rep lists */
825 
826 #ifdef USE_ASSERT_CHECKING
827  {
828  int i;
829 
830  /* Last process should have released all locks. */
831  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
833  }
834 #endif
835 
836  /*
837  * Release any LW locks I am holding. There really shouldn't be any, but
838  * it's cheap to check again before we cut the knees off the LWLock
839  * facility by releasing our PGPROC ...
840  */
842 
843  /* Cancel any pending condition variable sleep, too */
845 
846  /* Make sure active replication slots are released */
847  if (MyReplicationSlot != NULL)
849 
850  /* Also cleanup all the temporary slots. */
852 
853  /*
854  * Detach from any lock group of which we are a member. If the leader
855  * exist before all other group members, it's PGPROC will remain allocated
856  * until the last group process exits; that process must return the
857  * leader's PGPROC to the appropriate list.
858  */
859  if (MyProc->lockGroupLeader != NULL)
860  {
861  PGPROC *leader = MyProc->lockGroupLeader;
862  LWLock *leader_lwlock = LockHashPartitionLockByProc(leader);
863 
864  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
867  if (dlist_is_empty(&leader->lockGroupMembers))
868  {
869  leader->lockGroupLeader = NULL;
870  if (leader != MyProc)
871  {
872  procgloballist = leader->procgloballist;
873 
874  /* Leader exited first; return its PGPROC. */
876  leader->links.next = (SHM_QUEUE *) *procgloballist;
877  *procgloballist = leader;
879  }
880  }
881  else if (leader != MyProc)
882  MyProc->lockGroupLeader = NULL;
883  LWLockRelease(leader_lwlock);
884  }
885 
886  /*
887  * Reset MyLatch to the process local one. This is so that signal
888  * handlers et al can continue using the latch after the shared latch
889  * isn't ours anymore. After that clear MyProc and disown the shared
890  * latch.
891  */
893  proc = MyProc;
894  MyProc = NULL;
895  DisownLatch(&proc->procLatch);
896 
897  procgloballist = proc->procgloballist;
899 
900  /*
901  * If we're still a member of a locking group, that means we're a leader
902  * which has somehow exited before its children. The last remaining child
903  * will release our PGPROC. Otherwise, release it now.
904  */
905  if (proc->lockGroupLeader == NULL)
906  {
907  /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
909 
910  /* Return PGPROC structure (and semaphore) to appropriate freelist */
911  proc->links.next = (SHM_QUEUE *) *procgloballist;
912  *procgloballist = proc;
913  }
914 
915  /* Update shared estimate of spins_per_delay */
917 
919 
920  /*
921  * This process is no longer present in shared memory in any meaningful
922  * way, so tell the postmaster we've cleaned up acceptably well. (XXX
923  * autovac launcher should be included here someday)
924  */
927 
928  /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
929  if (AutovacuumLauncherPid != 0)
931 }
Definition: lwlock.h:32
dlist_head lockGroupMembers
Definition: proc.h:204
PGPROC * MyProc
Definition: proc.c:68
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:81
void MarkPostmasterChildInactive(void)
Definition: pmsignal.c:289
#define kill(pid, sig)
Definition: win32_port.h:435
#define SIGUSR2
Definition: win32_port.h:176
Latch procLatch
Definition: proc.h:104
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:361
dlist_node lockGroupLink
Definition: proc.h:205
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:269
int AutovacuumLauncherPid
Definition: autovacuum.c:304
bool IsUnderPostmaster
Definition: globals.c:109
void ReplicationSlotRelease(void)
Definition: slot.c:424
PGPROC ** procgloballist
Definition: proc.h:99
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:514
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:78
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3270
ReplicationSlot * MyReplicationSlot
Definition: slot.c:96
#define Assert(condition)
Definition: c.h:732
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
void SyncRepCleanupAtProcExit(void)
Definition: syncrep.c:363
void DisownLatch(volatile Latch *latch)
Definition: latch.c:316
int i
void ReplicationSlotCleanup(void)
Definition: slot.c:479
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:160
void LWLockReleaseAll(void)
Definition: lwlock.c:1824
Definition: proc.h:95
PGPROC * lockGroupLeader
Definition: proc.h:203
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:117

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1630 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().

1631 {
1632  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1633  int queue_size = waitQueue->size;
1634  PGPROC *proc;
1635  LOCKMASK aheadRequests = 0;
1636 
1637  Assert(queue_size >= 0);
1638 
1639  if (queue_size == 0)
1640  return;
1641 
1642  proc = (PGPROC *) waitQueue->links.next;
1643 
1644  while (queue_size-- > 0)
1645  {
1646  LOCKMODE lockmode = proc->waitLockMode;
1647 
1648  /*
1649  * Waken if (a) doesn't conflict with requests of earlier waiters, and
1650  * (b) doesn't conflict with already-held locks.
1651  */
1652  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1653  LockCheckConflicts(lockMethodTable,
1654  lockmode,
1655  lock,
1656  proc->waitProcLock) == STATUS_OK)
1657  {
1658  /* OK to waken */
1659  GrantLock(lock, proc->waitProcLock, lockmode);
1660  proc = ProcWakeup(proc, STATUS_OK);
1661 
1662  /*
1663  * ProcWakeup removes proc from the lock's waiting process queue
1664  * and returns the next proc in chain; don't use proc's next-link,
1665  * because it's been cleared.
1666  */
1667  }
1668  else
1669  {
1670  /*
1671  * Cannot wake this guy. Remember his request for later checks.
1672  */
1673  aheadRequests |= LOCKBIT_ON(lockmode);
1674  proc = (PGPROC *) proc->links.next;
1675  }
1676  }
1677 
1678  Assert(waitQueue->size >= 0);
1679 }
int LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1344
int LOCKMODE
Definition: lockdefs.h:26
SHM_QUEUE links
Definition: lock.h:32
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1467
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:141
const LOCKMASK * conflictTab
Definition: lock.h:114
PROC_QUEUE waitProcs
Definition: lock.h:293
PROCLOCK * waitProcLock
Definition: proc.h:140
#define STATUS_OK
Definition: c.h:1075
#define Assert(condition)
Definition: c.h:732
int LOCKMASK
Definition: lockdefs.h:25
#define LOCKBIT_ON(lockmode)
Definition: lock.h:87
int size
Definition: lock.h:33
PGPROC * ProcWakeup(PGPROC *proc, int waitStatus)
Definition: proc.c:1594
Definition: proc.h:95

◆ ProcQueueInit()

void ProcQueueInit ( PROC_QUEUE queue)

Definition at line 1039 of file proc.c.

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

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

1040 {
1041  SHMQueueInit(&(queue->links));
1042  queue->size = 0;
1043 }
SHM_QUEUE links
Definition: lock.h:32
void SHMQueueInit(SHM_QUEUE *queue)
Definition: shmqueue.c:36
int size
Definition: lock.h:33

◆ ProcReleaseLocks()

void ProcReleaseLocks ( bool  isCommit)

Definition at line 788 of file proc.c.

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

Referenced by ResourceOwnerReleaseInternal().

789 {
790  if (!MyProc)
791  return;
792  /* If waiting, get off wait queue (should only be needed after error) */
794  /* Release standard locks, including session-level if aborting */
796  /* Release transaction-level advisory locks */
798 }
PGPROC * MyProc
Definition: proc.c:68
#define DEFAULT_LOCKMETHOD
Definition: lock.h:128
#define USER_LOCKMETHOD
Definition: lock.h:129
void LockErrorCleanup(void)
Definition: proc.c:712
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2089

◆ ProcSendSignal()

void ProcSendSignal ( int  pid)

Definition at line 1813 of file proc.c.

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

Referenced by ReleasePredicateLocks(), and UnpinBuffer().

1814 {
1815  PGPROC *proc = NULL;
1816 
1817  if (RecoveryInProgress())
1818  {
1820 
1821  /*
1822  * Check to see whether it is the Startup process we wish to signal.
1823  * This call is made by the buffer manager when it wishes to wake up a
1824  * process that has been waiting for a pin in so it can obtain a
1825  * cleanup lock using LockBufferForCleanup(). Startup is not a normal
1826  * backend, so BackendPidGetProc() will not return any pid at all. So
1827  * we remember the information for this special case.
1828  */
1829  if (pid == ProcGlobal->startupProcPid)
1830  proc = ProcGlobal->startupProc;
1831 
1833  }
1834 
1835  if (proc == NULL)
1836  proc = BackendPidGetProc(pid);
1837 
1838  if (proc != NULL)
1839  {
1840  SetLatch(&proc->procLatch);
1841  }
1842 }
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:2379
PROC_HDR * ProcGlobal
Definition: proc.c:81
bool RecoveryInProgress(void)
Definition: xlog.c:7898
Latch procLatch
Definition: proc.h:104
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:272
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:78
void SetLatch(volatile Latch *latch)
Definition: latch.c:436
PGPROC * startupProc
Definition: proc.h:271
Definition: proc.h:95

◆ ProcSleep()

int ProcSleep ( LOCALLOCK locallock,
LockMethod  lockMethodTable 
)

Definition at line 1063 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, kill, 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, 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, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by WaitOnLock().

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

◆ ProcWaitForSignal()

void ProcWaitForSignal ( uint32  wait_event_info)

Definition at line 1801 of file proc.c.

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

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

1802 {
1804  wait_event_info);
1807 }
void ResetLatch(volatile Latch *latch)
Definition: latch.c:519
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:344
struct Latch * MyLatch
Definition: globals.c:54
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
#define WL_LATCH_SET
Definition: latch.h:124
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

◆ ProcWakeup()

PGPROC* ProcWakeup ( PGPROC proc,
int  waitStatus 
)

Definition at line 1594 of file proc.c.

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

Referenced by ProcLockWakeup().

1595 {
1596  PGPROC *retProc;
1597 
1598  /* Proc should be sleeping ... */
1599  if (proc->links.prev == NULL ||
1600  proc->links.next == NULL)
1601  return NULL;
1602  Assert(proc->waitStatus == STATUS_WAITING);
1603 
1604  /* Save next process before we zap the list link */
1605  retProc = (PGPROC *) proc->links.next;
1606 
1607  /* Remove process from wait queue */
1608  SHMQueueDelete(&(proc->links));
1609  (proc->waitLock->waitProcs.size)--;
1610 
1611  /* Clean up process' state and pass it the ok/fail signal */
1612  proc->waitLock = NULL;
1613  proc->waitProcLock = NULL;
1614  proc->waitStatus = waitStatus;
1615 
1616  /* And awaken it */
1617  SetLatch(&proc->procLatch);
1618 
1619  return retProc;
1620 }
SHM_QUEUE links
Definition: proc.h:98
struct SHM_QUEUE * next
Definition: shmem.h:31
Latch procLatch
Definition: proc.h:104
PROC_QUEUE waitProcs
Definition: lock.h:293
PROCLOCK * waitProcLock
Definition: proc.h:140
LOCK * waitLock
Definition: proc.h:139
int waitStatus
Definition: proc.h:102
void SetLatch(volatile Latch *latch)
Definition: latch.c:436
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define Assert(condition)
Definition: c.h:732
int size
Definition: lock.h:33
void SHMQueueDelete(SHM_QUEUE *queue)
Definition: shmqueue.c:68
#define STATUS_WAITING
Definition: c.h:1079
Definition: proc.h:95

◆ PublishStartupProcessInformation()

void PublishStartupProcessInformation ( void  )

Definition at line 628 of file proc.c.

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

Referenced by StartupXLOG().

629 {
631 
634 
636 }
int MyProcPid
Definition: globals.c:40
PGPROC * MyProc
Definition: proc.c:68
PROC_HDR * ProcGlobal
Definition: proc.c:81
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
int startupProcPid
Definition: proc.h:272
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:78
PGPROC * startupProc
Definition: proc.h:271

◆ RemoveProcFromArray()

static void RemoveProcFromArray ( int  code,
Datum  arg 
)
static

Definition at line 805 of file proc.c.

References Assert, InvalidTransactionId, and ProcArrayRemove().

Referenced by InitProcessPhase2().

806 {
807  Assert(MyProc != NULL);
809 }
PGPROC * MyProc
Definition: proc.c:68
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:334
#define InvalidTransactionId
Definition: transam.h:31
#define Assert(condition)
Definition: c.h:732

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)

Definition at line 646 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

647 {
648  /* use volatile pointer to prevent code rearrangement */
649  volatile PROC_HDR *procglobal = ProcGlobal;
650 
651  procglobal->startupBufferPinWaitBufId = bufid;
652 }
PROC_HDR * ProcGlobal
Definition: proc.c:81
Definition: proc.h:244
int startupBufferPinWaitBufId
Definition: proc.h:274

Variable Documentation

◆ AuxiliaryProcs

◆ deadlock_state

DeadLockState deadlock_state = DS_NOT_YET_CHECKED
static

Definition at line 88 of file proc.c.

Referenced by CheckDeadLock(), and ProcSleep().

◆ DeadlockTimeout

int DeadlockTimeout = 1000

Definition at line 61 of file proc.c.

Referenced by ProcSleep(), and ResolveRecoveryConflictWithBufferPin().

◆ got_deadlock_timeout

volatile sig_atomic_t got_deadlock_timeout
static

Definition at line 91 of file proc.c.

Referenced by CheckDeadLockAlert(), and ProcSleep().

◆ IdleInTransactionSessionTimeout

int IdleInTransactionSessionTimeout = 0

Definition at line 64 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ lockAwaited

LOCALLOCK* lockAwaited = NULL
static

Definition at line 86 of file proc.c.

◆ LockTimeout

int LockTimeout = 0

Definition at line 63 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

bool log_lock_waits = false

Definition at line 65 of file proc.c.

Referenced by ProcSleep().

◆ MyPgXact

◆ MyProc

PGPROC* MyProc = NULL

Definition at line 68 of file proc.c.

Referenced by AbortTransaction(), apw_sighup_handler(), apw_sigterm_handler(), AtEOSubXact_Namespace(), AtEOXact_Namespace(), attach_to_queues(), autoprewarm_main(), AutoVacWorkerMain(), AuxiliaryProcKill(), BackgroundWriterMain(), BecomeLockGroupLeader(), CheckpointerMain(), CommitTransaction(), ConditionVariableBroadcast(), ConditionVariableCancelSleep(), ConditionVariablePrepareToSleep(), ConditionVariableSleep(), CountOtherDBBackends(), CreateReplicationSlot(), errdetail_abort(), exec_eval_simple_expr(), exec_stmt_call(), ExecParallelGetReceiver(), ExecParallelSetupTupleQueues(), ExportSnapshot(), FastPathGetRelationLockEntry(), FastPathGrantRelationLock(), FastPathUnGrantRelationLock(), FindLockCycleRecurseMember(), fmgr_sql(), get_cast_hashentry(), GetCurrentVirtualXIDs(), GetLockConflicts(), GetLockmodeName(), GetNewTransactionId(), GetSerializableTransactionSnapshotInt(), GetStableLatestTransactionId(), init_sql_fcache(), InitializeParallelDSM(), InitializeSessionUserId(), InitPostgres(), InitTempTableNamespace(), InitWalSenderSlot(), lock_and_open_sequence(), LockAcquireExtended(), LockCheckConflicts(), LockRelease(), LockReleaseAll(), log_line_prefix(), logicalrep_worker_attach(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockAttemptLock(), LWLockDequeueSelf(), LWLockQueueSelf(), LWLockWaitForVar(), MinimumActiveBackends(), 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_internal(), shm_mq_receive(), shm_mq_sendv(), shm_mq_wait_for_attach(), StartTransaction(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepCancelWait(), SyncRepCleanupAtProcExit(), SyncRepQueueInsert(), SyncRepWaitForLSN(), TransactionGroupUpdateXidStatus(), TransactionIdIsInProgress(), TransactionIdSetPageStatus(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), WaitXLogInsertionsToFinish(), WALInsertLockAcquire(), WalReceiverMain(), WalWriterMain(), write_csvlog(), and XidCacheRemoveRunningXids().

◆ PreparedXactProcs

PGPROC* PreparedXactProcs = NULL

Definition at line 83 of file proc.c.

Referenced by PostmasterMarkPIDForWorkerNotify(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ ProcStructLock

◆ StatementTimeout

int StatementTimeout = 0

Definition at line 62 of file proc.c.

Referenced by enable_statement_timeout().