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/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 "storage/standby.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)
 
ProcWaitStatus ProcSleep (LOCALLOCK *locallock, LockMethod lockMethodTable)
 
PGPROCProcWakeup (PGPROC *proc, ProcWaitStatus 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 985 of file proc.c.

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

Referenced by pg_stat_get_activity().

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

◆ AuxiliaryProcKill()

static void AuxiliaryProcKill ( int  code,
Datum  arg 
)
static

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

939 {
940  int proctype = DatumGetInt32(arg);
942  PGPROC *proc;
943 
944  Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
945 
946  auxproc = &AuxiliaryProcs[proctype];
947 
948  Assert(MyProc == auxproc);
949 
950  /* Release any LW locks I am holding (see notes above) */
952 
953  /* Cancel any pending condition variable sleep, too */
955 
956  /*
957  * Reset MyLatch to the process local one. This is so that signal
958  * handlers et al can continue using the latch after the shared latch
959  * isn't ours anymore. After that clear MyProc and disown the shared
960  * latch.
961  */
963  proc = MyProc;
964  MyProc = NULL;
965  DisownLatch(&proc->procLatch);
966 
968 
969  /* Mark auxiliary proc no longer in use */
970  proc->pid = 0;
971 
972  /* Update shared estimate of spins_per_delay */
974 
976 }
#define DatumGetInt32(X)
Definition: postgres.h:472
PGPROC * MyProc
Definition: proc.c:67
PROC_HDR * ProcGlobal
Definition: proc.c:80
void DisownLatch(Latch *latch)
Definition: latch.c:337
Latch procLatch
Definition: proc.h:111
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:188
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:274
#define NUM_AUXILIARY_PROCS
Definition: proc.h:297
int update_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:206
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
#define Assert(condition)
Definition: c.h:738
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition: proc.c:81
void * arg
void LWLockReleaseAll(void)
Definition: lwlock.c:1911
Definition: proc.h:102
int pid
Definition: proc.h:116
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:121

◆ BecomeLockGroupLeader()

void BecomeLockGroupLeader ( void  )

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

1851 {
1852  LWLock *leader_lwlock;
1853 
1854  /* If we already did it, we don't need to do it again. */
1855  if (MyProc->lockGroupLeader == MyProc)
1856  return;
1857 
1858  /* We had better not be a follower. */
1859  Assert(MyProc->lockGroupLeader == NULL);
1860 
1861  /* Create single-member group, containing only ourselves. */
1862  leader_lwlock = LockHashPartitionLockByProc(MyProc);
1863  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1866  LWLockRelease(leader_lwlock);
1867 }
Definition: lwlock.h:31
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:300
dlist_head lockGroupMembers
Definition: proc.h:211
PGPROC * MyProc
Definition: proc.c:67
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
dlist_node lockGroupLink
Definition: proc.h:212
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:519
#define Assert(condition)
Definition: c.h:738
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
PGPROC * lockGroupLeader
Definition: proc.h:210

◆ BecomeLockGroupMember()

bool BecomeLockGroupMember ( PGPROC leader,
int  pid 
)

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

1881 {
1882  LWLock *leader_lwlock;
1883  bool ok = false;
1884 
1885  /* Group leader can't become member of group */
1886  Assert(MyProc != leader);
1887 
1888  /* Can't already be a member of a group */
1889  Assert(MyProc->lockGroupLeader == NULL);
1890 
1891  /* PID must be valid. */
1892  Assert(pid != 0);
1893 
1894  /*
1895  * Get lock protecting the group fields. Note LockHashPartitionLockByProc
1896  * accesses leader->pgprocno in a PGPROC that might be free. This is safe
1897  * because all PGPROCs' pgprocno fields are set during shared memory
1898  * initialization and never change thereafter; so we will acquire the
1899  * correct lock even if the leader PGPROC is in process of being recycled.
1900  */
1901  leader_lwlock = LockHashPartitionLockByProc(leader);
1902  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
1903 
1904  /* Is this the leader we're looking for? */
1905  if (leader->pid == pid && leader->lockGroupLeader == leader)
1906  {
1907  /* OK, join the group */
1908  ok = true;
1909  MyProc->lockGroupLeader = leader;
1911  }
1912  LWLockRelease(leader_lwlock);
1913 
1914  return ok;
1915 }
Definition: lwlock.h:31
dlist_head lockGroupMembers
Definition: proc.h:211
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:1812
dlist_node lockGroupLink
Definition: proc.h:212
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:519
#define Assert(condition)
Definition: c.h:738
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
int pid
Definition: proc.h:116
PGPROC * lockGroupLeader
Definition: proc.h:210

◆ 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 safe because we hold the lock partition lock.
1717  */
1718  if (MyProc->links.prev == NULL ||
1719  MyProc->links.next == NULL)
1720  goto check_done;
1721 
1722 #ifdef LOCK_DEBUG
1723  if (Debug_deadlocks)
1724  DumpAllLocks();
1725 #endif
1726 
1727  /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
1729 
1731  {
1732  /*
1733  * Oops. We have a deadlock.
1734  *
1735  * Get this process out of wait state. (Note: we could do this more
1736  * efficiently by relying on lockAwaited, but use this coding to
1737  * preserve the flexibility to kill some other transaction than the
1738  * one detecting the deadlock.)
1739  *
1740  * RemoveFromWaitQueue sets MyProc->waitStatus to PROC_WAIT_STATUS_ERROR, so
1741  * ProcSleep will report an error after we return from the signal
1742  * handler.
1743  */
1744  Assert(MyProc->waitLock != NULL);
1746 
1747  /*
1748  * We're done here. Transaction abort caused by the error that
1749  * ProcSleep will raise will cause any other locks we hold to be
1750  * released, thus allowing other processes to wake up; we don't need
1751  * to do that here. NOTE: an exception is that releasing locks we
1752  * hold doesn't consider the possibility of waiters that were blocked
1753  * behind us on the lock we just failed to get, and might now be
1754  * wakable because we're not in front of them anymore. However,
1755  * RemoveFromWaitQueue took care of waking up any such processes.
1756  */
1757  }
1758 
1759  /*
1760  * And release locks. We do this in reverse order for two reasons: (1)
1761  * Anyone else who needs more than one of the locks will be trying to lock
1762  * them in increasing order; we don't want to release the other process
1763  * until it can get all the locks it needs. (2) This avoids O(N^2)
1764  * behavior inside LWLockRelease.
1765  */
1766 check_done:
1767  for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1769 }
PGPROC * MyProc
Definition: proc.c:67
SHM_QUEUE links
Definition: proc.h:105
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKTAG tag
Definition: lock.h:290
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define LockHashPartitionLockByIndex(i)
Definition: lock.h:507
static DeadLockState deadlock_state
Definition: proc.c:87
DeadLockState DeadLockCheck(PGPROC *proc)
Definition: deadlock.c:217
LOCK * waitLock
Definition: proc.h:146
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition: lock.c:517
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition: lock.c:1918
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define Assert(condition)
Definition: c.h:738
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
int i
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115

◆ CheckDeadLockAlert()

void CheckDeadLockAlert ( void  )

Definition at line 1777 of file proc.c.

References got_deadlock_timeout, MyLatch, and SetLatch().

Referenced by InitPostgres().

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

◆ GetStartupBufferPinWaitBufId()

int GetStartupBufferPinWaitBufId ( void  )

Definition at line 657 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by HoldingBufferPinThatDelaysRecovery().

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

◆ HaveNFreeProcs()

bool HaveNFreeProcs ( int  n)

Definition at line 671 of file proc.c.

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

Referenced by InitPostgres().

672 {
673  PGPROC *proc;
674 
676 
677  proc = ProcGlobal->freeProcs;
678 
679  while (n > 0 && proc != NULL)
680  {
681  proc = (PGPROC *) proc->links.next;
682  n--;
683  }
684 
686 
687  return (n <= 0);
688 }
SHM_QUEUE links
Definition: proc.h:105
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
PGPROC * freeProcs
Definition: proc.h:258
Definition: proc.h:102

◆ InitAuxiliaryProcess()

void InitAuxiliaryProcess ( void  )

Definition at line 515 of file proc.c.

References PROC_HDR::allPgXact, Assert, AuxiliaryProcKill(), AuxiliaryProcs, PGPROC::backendId, PGPROC::databaseId, PGPROC::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, PROC_WAIT_STATUS_OK, PGPROC::procLatch, ProcStructLock, PGPROC::roleId, PGPROC::sem, set_spins_per_delay(), SHMQueueElemInit(), SHMQueueEmpty(), SpinLockAcquire, SpinLockRelease, PROC_HDR::spins_per_delay, SwitchToSharedLatch(), PGPROC::tempNamespaceId, PGXACT::vacuumFlags, PGPROC::waitLock, PGPROC::waitProcLock, PGPROC::waitStatus, PGXACT::xid, and PGXACT::xmin.

Referenced by AuxiliaryProcessMain(), and BackendRun().

516 {
517  PGPROC *auxproc;
518  int proctype;
519 
520  /*
521  * ProcGlobal should be set up already (if we are a backend, we inherit
522  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
523  */
524  if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
525  elog(PANIC, "proc header uninitialized");
526 
527  if (MyProc != NULL)
528  elog(ERROR, "you already exist");
529 
530  /*
531  * We use the ProcStructLock to protect assignment and releasing of
532  * AuxiliaryProcs entries.
533  *
534  * While we are holding the ProcStructLock, also copy the current shared
535  * estimate of spins_per_delay to local storage.
536  */
538 
540 
541  /*
542  * Find a free auxproc ... *big* trouble if there isn't one ...
543  */
544  for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
545  {
546  auxproc = &AuxiliaryProcs[proctype];
547  if (auxproc->pid == 0)
548  break;
549  }
550  if (proctype >= NUM_AUXILIARY_PROCS)
551  {
553  elog(FATAL, "all AuxiliaryProcs are in use");
554  }
555 
556  /* Mark auxiliary proc as in use by me */
557  /* use volatile pointer to prevent code rearrangement */
558  ((volatile PGPROC *) auxproc)->pid = MyProcPid;
559 
560  MyProc = auxproc;
561  MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno];
562 
564 
565  /*
566  * Initialize all fields of MyProc, except for those previously
567  * initialized by InitProcGlobal.
568  */
572  MyProc->fpVXIDLock = false;
581  MyProc->delayChkpt = false;
582  MyPgXact->vacuumFlags = 0;
583  MyProc->lwWaiting = false;
584  MyProc->lwWaitMode = 0;
585  MyProc->waitLock = NULL;
586  MyProc->waitProcLock = NULL;
587 #ifdef USE_ASSERT_CHECKING
588  {
589  int i;
590 
591  /* Last process should have released all locks. */
592  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
594  }
595 #endif
596 
597  /*
598  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
599  * on it. That allows us to repoint the process latch, which so far
600  * points to process local one, to the shared one.
601  */
604 
605  /* Check that group locking fields are in a proper initial state. */
606  Assert(MyProc->lockGroupLeader == NULL);
608 
609  /*
610  * We might be reusing a semaphore that belonged to a failed process. So
611  * be careful and reinitialize its value here. (This is not strictly
612  * necessary anymore, but seems like a good idea for cleanliness.)
613  */
615 
616  /*
617  * Arrange to clean up at process exit.
618  */
620 }
static void AuxiliaryProcKill(int code, Datum arg)
Definition: proc.c:938
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:195
int MyProcPid
Definition: globals.c:40
BackendId backendId
Definition: proc.h:120
dlist_head lockGroupMembers
Definition: proc.h:211
Oid tempNamespaceId
Definition: proc.h:124
TransactionId xmin
Definition: proc.h:235
PGXACT * allPgXact
Definition: proc.h:254
PGPROC * MyProc
Definition: proc.c:67
TransactionId xid
Definition: proc.h:231
SHM_QUEUE links
Definition: proc.h:105
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:295
bool lwWaiting
Definition: proc.h:137
Oid roleId
Definition: proc.h:122
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 lwWaitMode
Definition: proc.h:138
ProcWaitStatus waitStatus
Definition: proc.h:109
bool fpVXIDLock
Definition: proc.h:202
#define PANIC
Definition: elog.h:53
Latch procLatch
Definition: proc.h:111
PGXACT * MyPgXact
Definition: proc.c:68
uint8 vacuumFlags
Definition: proc.h:240
bool IsBackgroundWorker
Definition: globals.c:111
bool isBackgroundWorker
Definition: proc.h:127
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:274
#define ERROR
Definition: elog.h:43
bool delayChkpt
Definition: proc.h:152
void OwnLatch(Latch *latch)
Definition: latch.c:317
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:147
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:121
LOCK * waitLock
Definition: proc.h:146
#define NUM_AUXILIARY_PROCS
Definition: proc.h:297
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:169
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:738
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:479
int pgprocno
Definition: proc.h:117
#define elog(elevel,...)
Definition: elog.h:214
#define InvalidLocalTransactionId
Definition: lock.h:68
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:169
PGSemaphore sem
Definition: proc.h:108
Definition: proc.h:102
int pid
Definition: proc.h:116
PGPROC * lockGroupLeader
Definition: proc.h:210
LocalTransactionId fpLocalTransactionId
Definition: proc.h:203
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115
LocalTransactionId lxid
Definition: proc.h:113

◆ InitProcess()

void InitProcess ( void  )

Definition at line 304 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, PGPROC::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, PROC_WAIT_STATUS_OK, 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, 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().

305 {
306  PGPROC *volatile *procgloballist;
307 
308  /*
309  * ProcGlobal should be set up already (if we are a backend, we inherit
310  * this by fork() or EXEC_BACKEND mechanism from the postmaster).
311  */
312  if (ProcGlobal == NULL)
313  elog(PANIC, "proc header uninitialized");
314 
315  if (MyProc != NULL)
316  elog(ERROR, "you already exist");
317 
318  /* Decide which list should supply our PGPROC. */
320  procgloballist = &ProcGlobal->autovacFreeProcs;
321  else if (IsBackgroundWorker)
322  procgloballist = &ProcGlobal->bgworkerFreeProcs;
323  else if (am_walsender)
324  procgloballist = &ProcGlobal->walsenderFreeProcs;
325  else
326  procgloballist = &ProcGlobal->freeProcs;
327 
328  /*
329  * Try to get a proc struct from the appropriate free list. If this
330  * fails, we must be out of PGPROC structures (not to mention semaphores).
331  *
332  * While we are holding the ProcStructLock, also copy the current shared
333  * estimate of spins_per_delay to local storage.
334  */
336 
338 
339  MyProc = *procgloballist;
340 
341  if (MyProc != NULL)
342  {
343  *procgloballist = (PGPROC *) MyProc->links.next;
345  }
346  else
347  {
348  /*
349  * If we reach here, all the PGPROCs are in use. This is one of the
350  * possible places to detect "too many backends", so give the standard
351  * error message. XXX do we need to give a different failure message
352  * in the autovacuum case?
353  */
355  if (am_walsender)
356  ereport(FATAL,
357  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
358  errmsg("number of requested standby connections exceeds max_wal_senders (currently %d)",
359  max_wal_senders)));
360  ereport(FATAL,
361  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
362  errmsg("sorry, too many clients already")));
363  }
365 
366  /*
367  * Cross-check that the PGPROC is of the type we expect; if this were not
368  * the case, it would get returned to the wrong list.
369  */
370  Assert(MyProc->procgloballist == procgloballist);
371 
372  /*
373  * Now that we have a PGPROC, mark ourselves as an active postmaster
374  * child; this is so that the postmaster can detect it if we exit without
375  * cleaning up. (XXX autovac launcher currently doesn't participate in
376  * this; it probably should.)
377  */
380 
381  /*
382  * Initialize all fields of MyProc, except for those previously
383  * initialized by InitProcGlobal.
384  */
388  MyProc->fpVXIDLock = false;
392  MyProc->pid = MyProcPid;
393  /* backendId, databaseId and roleId will be filled in later */
399  MyProc->delayChkpt = false;
400  MyPgXact->vacuumFlags = 0;
401  /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
404  MyProc->lwWaiting = false;
405  MyProc->lwWaitMode = 0;
406  MyProc->waitLock = NULL;
407  MyProc->waitProcLock = NULL;
408 #ifdef USE_ASSERT_CHECKING
409  {
410  int i;
411 
412  /* Last process should have released all locks. */
413  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
415  }
416 #endif
418 
419  /* Initialize fields for sync rep */
420  MyProc->waitLSN = 0;
423 
424  /* Initialize fields for group XID clearing. */
425  MyProc->procArrayGroupMember = false;
428 
429  /* Check that group locking fields are in a proper initial state. */
430  Assert(MyProc->lockGroupLeader == NULL);
432 
433  /* Initialize wait event information. */
434  MyProc->wait_event_info = 0;
435 
436  /* Initialize fields for group transaction status update. */
437  MyProc->clogGroupMember = false;
443 
444  /*
445  * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
446  * on it. That allows us to repoint the process latch, which so far
447  * points to process local one, to the shared one.
448  */
451 
452  /*
453  * We might be reusing a semaphore that belonged to a failed process. So
454  * be careful and reinitialize its value here. (This is not strictly
455  * necessary anymore, but seems like a good idea for cleanliness.)
456  */
458 
459  /*
460  * Arrange to clean up at backend exit.
461  */
463 
464  /*
465  * Now that we have a PGPROC, we could try to acquire locks, so initialize
466  * local state needed for LWLocks, and the deadlock checker.
467  */
470 }
bool procArrayGroupMember
Definition: proc.h:175
static void ProcKill(int code, Datum arg)
Definition: proc.c:815
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XidStatus clogGroupMemberXidStatus
Definition: proc.h:191
void set_spins_per_delay(int shared_spins_per_delay)
Definition: s_lock.c:195
int MyProcPid
Definition: globals.c:40
BackendId backendId
Definition: proc.h:120
uint32 wait_event_info
Definition: proc.h:185
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:195
dlist_head lockGroupMembers
Definition: proc.h:211
Oid tempNamespaceId
Definition: proc.h:124
TransactionId xmin
Definition: proc.h:235
PGXACT * allPgXact
Definition: proc.h:254
PGPROC * MyProc
Definition: proc.c:67
TransactionId xid
Definition: proc.h:231
SHM_QUEUE links
Definition: proc.h:105
struct SHM_QUEUE * next
Definition: shmem.h:31
void PGSemaphoreReset(PGSemaphore sema)
Definition: posix_sema.c:295
bool lwWaiting
Definition: proc.h:137
#define SYNC_REP_NOT_WAITING
Definition: syncrep.h:31
PGPROC * bgworkerFreeProcs
Definition: proc.h:262
Oid roleId
Definition: proc.h:122
int errcode(int sqlerrcode)
Definition: elog.c:610
PROC_HDR * ProcGlobal
Definition: proc.c:80
uint8 lwWaitMode
Definition: proc.h:138
pg_atomic_uint32 clogGroupNext
Definition: proc.h:189
ProcWaitStatus waitStatus
Definition: proc.h:109
bool fpVXIDLock
Definition: proc.h:202
#define PANIC
Definition: elog.h:53
PGPROC * autovacFreeProcs
Definition: proc.h:260
PGPROC * walsenderFreeProcs
Definition: proc.h:264
Latch procLatch
Definition: proc.h:111
PGXACT * MyPgXact
Definition: proc.c:68
uint8 vacuumFlags
Definition: proc.h:240
bool IsBackgroundWorker
Definition: globals.c:111
bool isBackgroundWorker
Definition: proc.h:127
bool am_walsender
Definition: walsender.c:115
#define SpinLockAcquire(lock)
Definition: spin.h:62
int spins_per_delay
Definition: proc.h:274
#define ERROR
Definition: elog.h:43
bool delayChkpt
Definition: proc.h:152
void OwnLatch(Latch *latch)
Definition: latch.c:317
#define FATAL
Definition: elog.h:52
PROCLOCK * waitProcLock
Definition: proc.h:147
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:193
bool recoveryConflictPending
Definition: proc.h:134
bool IsUnderPostmaster
Definition: globals.c:109
#define InvalidTransactionId
Definition: transam.h:31
TransactionId clogGroupMemberXid
Definition: proc.h:190
Oid databaseId
Definition: proc.h:121
PGPROC ** procgloballist
Definition: proc.h:106
LOCK * waitLock
Definition: proc.h:146
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3301
#define INVALID_PGPROCNO
Definition: proc.h:77
pg_atomic_uint32 procArrayGroupNext
Definition: proc.h:177
int max_wal_senders
Definition: walsender.c:121
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:169
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define IsAnyAutoVacuumProcess()
Definition: autovacuum.h:55
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3295
#define Assert(condition)
Definition: c.h:738
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
PGPROC * freeProcs
Definition: proc.h:258
SHM_QUEUE syncRepLinks
Definition: proc.h:162
void SHMQueueElemInit(SHM_QUEUE *queue)
Definition: shmqueue.c:57
int pgprocno
Definition: proc.h:117
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool clogGroupMember
Definition: proc.h:188
#define elog(elevel,...)
Definition: elog.h:214
#define InvalidLocalTransactionId
Definition: lock.h:68
int i
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:169
PGSemaphore sem
Definition: proc.h:108
int syncRepState
Definition: proc.h:161
Definition: proc.h:102
int pid
Definition: proc.h:116
XLogRecPtr waitLSN
Definition: proc.h:160
PGPROC * lockGroupLeader
Definition: proc.h:210
LocalTransactionId fpLocalTransactionId
Definition: proc.h:203
#define PROC_IS_AUTOVACUUM
Definition: proc.h:53
TransactionId procArrayGroupMemberXid
Definition: proc.h:183
void InitLWLockAccess(void)
Definition: lwlock.c:583
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:26
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:241
void MarkPostmasterChildActive(void)
Definition: pmsignal.c:256
LocalTransactionId lxid
Definition: proc.h:113

◆ InitProcessPhase2()

void InitProcessPhase2 ( void  )

Definition at line 480 of file proc.c.

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

Referenced by InitPostgres().

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

◆ InitProcGlobal()

void InitProcGlobal ( void  )

Definition at line 163 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_LOCK_FASTPATH, 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().

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

◆ IsWaitingForLock()

bool IsWaitingForLock ( void  )

Definition at line 694 of file proc.c.

Referenced by RecoveryConflictInterrupt().

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

◆ LockErrorCleanup()

void LockErrorCleanup ( void  )

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

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

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

◆ ProcGlobalSemas()

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:135
#define NUM_AUXILIARY_PROCS
Definition: proc.h:297

◆ ProcGlobalShmemSize()

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:934
Definition: proc.h:229
int max_prepared_xacts
Definition: twophase.c:117
int MaxBackends
Definition: globals.c:135
#define NUM_AUXILIARY_PROCS
Definition: proc.h:297
Definition: proc.h:249
Size mul_size(Size s1, Size s2)
Definition: shmem.c:515
Size add_size(Size s1, Size s2)
Definition: shmem.c:498
size_t Size
Definition: c.h:466
Definition: proc.h:102

◆ ProcKill()

static void ProcKill ( int  code,
Datum  arg 
)
static

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

816 {
817  PGPROC *proc;
818  PGPROC *volatile *procgloballist;
819 
820  Assert(MyProc != NULL);
821 
822  /* Make sure we're out of the sync rep lists */
824 
825 #ifdef USE_ASSERT_CHECKING
826  {
827  int i;
828 
829  /* Last process should have released all locks. */
830  for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
832  }
833 #endif
834 
835  /*
836  * Release any LW locks I am holding. There really shouldn't be any, but
837  * it's cheap to check again before we cut the knees off the LWLock
838  * facility by releasing our PGPROC ...
839  */
841 
842  /* Cancel any pending condition variable sleep, too */
844 
845  /* Make sure active replication slots are released */
846  if (MyReplicationSlot != NULL)
848 
849  /* Also cleanup all the temporary slots. */
851 
852  /*
853  * Detach from any lock group of which we are a member. If the leader
854  * exist before all other group members, its PGPROC will remain allocated
855  * until the last group process exits; that process must return the
856  * leader's PGPROC to the appropriate list.
857  */
858  if (MyProc->lockGroupLeader != NULL)
859  {
860  PGPROC *leader = MyProc->lockGroupLeader;
861  LWLock *leader_lwlock = LockHashPartitionLockByProc(leader);
862 
863  LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
866  if (dlist_is_empty(&leader->lockGroupMembers))
867  {
868  leader->lockGroupLeader = NULL;
869  if (leader != MyProc)
870  {
871  procgloballist = leader->procgloballist;
872 
873  /* Leader exited first; return its PGPROC. */
875  leader->links.next = (SHM_QUEUE *) *procgloballist;
876  *procgloballist = leader;
878  }
879  }
880  else if (leader != MyProc)
881  MyProc->lockGroupLeader = NULL;
882  LWLockRelease(leader_lwlock);
883  }
884 
885  /*
886  * Reset MyLatch to the process local one. This is so that signal
887  * handlers et al can continue using the latch after the shared latch
888  * isn't ours anymore. After that clear MyProc and disown the shared
889  * latch.
890  */
892  proc = MyProc;
893  MyProc = NULL;
894  DisownLatch(&proc->procLatch);
895 
896  procgloballist = proc->procgloballist;
898 
899  /*
900  * If we're still a member of a locking group, that means we're a leader
901  * which has somehow exited before its children. The last remaining child
902  * will release our PGPROC. Otherwise, release it now.
903  */
904  if (proc->lockGroupLeader == NULL)
905  {
906  /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
908 
909  /* Return PGPROC structure (and semaphore) to appropriate freelist */
910  proc->links.next = (SHM_QUEUE *) *procgloballist;
911  *procgloballist = proc;
912  }
913 
914  /* Update shared estimate of spins_per_delay */
916 
918 
919  /*
920  * This process is no longer present in shared memory in any meaningful
921  * way, so tell the postmaster we've cleaned up acceptably well. (XXX
922  * autovac launcher should be included here someday)
923  */
926 
927  /* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
928  if (AutovacuumLauncherPid != 0)
930 }
Definition: lwlock.h:31
dlist_head lockGroupMembers
Definition: proc.h:211
PGPROC * MyProc
Definition: proc.c:67
SHM_QUEUE links
Definition: proc.h:105
struct SHM_QUEUE * next
Definition: shmem.h:31
PROC_HDR * ProcGlobal
Definition: proc.c:80
void MarkPostmasterChildInactive(void)
Definition: pmsignal.c:289
#define kill(pid, sig)
Definition: win32_port.h:426
void DisownLatch(Latch *latch)
Definition: latch.c:337
#define SIGUSR2
Definition: win32_port.h:166
Latch procLatch
Definition: proc.h:111
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define SpinLockAcquire(lock)
Definition: spin.h:62
void SwitchBackToLocalLatch(void)
Definition: miscinit.c:188
dlist_node lockGroupLink
Definition: proc.h:212
void ConditionVariableCancelSleep(void)
int spins_per_delay
Definition: proc.h:274
int AutovacuumLauncherPid
Definition: autovacuum.c:305
bool IsUnderPostmaster
Definition: globals.c:109
void ReplicationSlotRelease(void)
Definition: slot.c:476
PGPROC ** procgloballist
Definition: proc.h:106
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:206
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Definition: shmqueue.c:180
#define LockHashPartitionLockByProc(leader_pgproc)
Definition: lock.h:519
#define SpinLockRelease(lock)
Definition: spin.h:64
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3295
ReplicationSlot * MyReplicationSlot
Definition: slot.c:96
#define Assert(condition)
Definition: c.h:738
static bool dlist_is_empty(dlist_head *head)
Definition: ilist.h:289
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
void SyncRepCleanupAtProcExit(void)
Definition: syncrep.c:371
int i
void ReplicationSlotCleanup(void)
Definition: slot.c:531
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
Definition: proc.h:169
void LWLockReleaseAll(void)
Definition: lwlock.c:1911
Definition: proc.h:102
PGPROC * lockGroupLeader
Definition: proc.h:210
#define NUM_LOCK_PARTITIONS
Definition: lwlock.h:115

◆ ProcLockWakeup()

void ProcLockWakeup ( LockMethod  lockMethodTable,
LOCK lock 
)

Definition at line 1632 of file proc.c.

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

Referenced by CleanUpLock(), and DeadLockCheck().

1633 {
1634  PROC_QUEUE *waitQueue = &(lock->waitProcs);
1635  int queue_size = waitQueue->size;
1636  PGPROC *proc;
1637  LOCKMASK aheadRequests = 0;
1638 
1639  Assert(queue_size >= 0);
1640 
1641  if (queue_size == 0)
1642  return;
1643 
1644  proc = (PGPROC *) waitQueue->links.next;
1645 
1646  while (queue_size-- > 0)
1647  {
1648  LOCKMODE lockmode = proc->waitLockMode;
1649 
1650  /*
1651  * Waken if (a) doesn't conflict with requests of earlier waiters, and
1652  * (b) doesn't conflict with already-held locks.
1653  */
1654  if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1655  !LockCheckConflicts(lockMethodTable, lockmode, lock,
1656  proc->waitProcLock))
1657  {
1658  /* OK to waken */
1659  GrantLock(lock, proc->waitProcLock, lockmode);
1660  proc = ProcWakeup(proc, PROC_WAIT_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 LOCKMODE
Definition: lockdefs.h:26
SHM_QUEUE links
Definition: lock.h:31
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition: lock.c:1555
SHM_QUEUE links
Definition: proc.h:105
struct SHM_QUEUE * next
Definition: shmem.h:31
LOCKMODE waitLockMode
Definition: proc.h:148
const LOCKMASK * conflictTab
Definition: lock.h:113
PROC_QUEUE waitProcs
Definition: lock.h:296
PGPROC * ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition: proc.c:1596
PROCLOCK * waitProcLock
Definition: proc.h:147
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition: lock.c:1420
#define Assert(condition)
Definition: c.h:738
int LOCKMASK
Definition: lockdefs.h:25
#define LOCKBIT_ON(lockmode)
Definition: lock.h:86
int size
Definition: lock.h:32
Definition: proc.h:102

◆ ProcQueueInit()

void ProcQueueInit ( PROC_QUEUE queue)

Definition at line 1038 of file proc.c.

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

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

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

◆ ProcReleaseLocks()

void ProcReleaseLocks ( bool  isCommit)

Definition at line 787 of file proc.c.

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

Referenced by ResourceOwnerReleaseInternal().

788 {
789  if (!MyProc)
790  return;
791  /* If waiting, get off wait queue (should only be needed after error) */
793  /* Release standard locks, including session-level if aborting */
795  /* Release transaction-level advisory locks */
797 }
PGPROC * MyProc
Definition: proc.c:67
#define DEFAULT_LOCKMETHOD
Definition: lock.h:127
#define USER_LOCKMETHOD
Definition: lock.h:128
void LockErrorCleanup(void)
Definition: proc.c:711
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2180

◆ ProcSendSignal()

void ProcSendSignal ( int  pid)

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

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

◆ ProcSleep()

ProcWaitStatus ProcSleep ( LOCALLOCK locallock,
LockMethod  lockMethodTable 
)

Definition at line 1062 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, PROC_WAIT_STATUS_ERROR, PROC_WAIT_STATUS_OK, PROC_WAIT_STATUS_WAITING, LOCALLOCK::proclock, LOCK::procLocks, RecoveryInProgress(), RememberSimpleDeadLock(), RemoveFromWaitQueue(), ResetLatch(), ResolveRecoveryConflictWithLock(), SHMQueueInsertBefore(), SHMQueueNext(), PROC_QUEUE::size, 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().

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

◆ ProcWaitForSignal()

void ProcWaitForSignal ( uint32  wait_event_info)

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

1801 {
1803  wait_event_info);
1806 }
void ResetLatch(Latch *latch)
Definition: latch.c:540
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:365
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,
ProcWaitStatus  waitStatus 
)

Definition at line 1596 of file proc.c.

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

Referenced by ProcLockWakeup().

1597 {
1598  PGPROC *retProc;
1599 
1600  /* Proc should be sleeping ... */
1601  if (proc->links.prev == NULL ||
1602  proc->links.next == NULL)
1603  return NULL;
1605 
1606  /* Save next process before we zap the list link */
1607  retProc = (PGPROC *) proc->links.next;
1608 
1609  /* Remove process from wait queue */
1610  SHMQueueDelete(&(proc->links));
1611  (proc->waitLock->waitProcs.size)--;
1612 
1613  /* Clean up process' state and pass it the ok/fail signal */
1614  proc->waitLock = NULL;
1615  proc->waitProcLock = NULL;
1616  proc->waitStatus = waitStatus;
1617 
1618  /* And awaken it */
1619  SetLatch(&proc->procLatch);
1620 
1621  return retProc;
1622 }
SHM_QUEUE links
Definition: proc.h:105
struct SHM_QUEUE * next
Definition: shmem.h:31
ProcWaitStatus waitStatus
Definition: proc.h:109
void SetLatch(Latch *latch)
Definition: latch.c:457
Latch procLatch
Definition: proc.h:111
PROC_QUEUE waitProcs
Definition: lock.h:296
PROCLOCK * waitProcLock
Definition: proc.h:147
LOCK * waitLock
Definition: proc.h:146
struct SHM_QUEUE * prev
Definition: shmem.h:30
#define Assert(condition)
Definition: c.h:738
int size
Definition: lock.h:32
void SHMQueueDelete(SHM_QUEUE *queue)
Definition: shmqueue.c:68
Definition: proc.h:102

◆ PublishStartupProcessInformation()

void PublishStartupProcessInformation ( void  )

Definition at line 627 of file proc.c.

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

Referenced by StartupXLOG().

628 {
630 
633 
635 }
int MyProcPid
Definition: globals.c:40
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:277
NON_EXEC_STATIC slock_t * ProcStructLock
Definition: proc.c:77
PGPROC * startupProc
Definition: proc.h:276

◆ RemoveProcFromArray()

static void RemoveProcFromArray ( int  code,
Datum  arg 
)
static

Definition at line 804 of file proc.c.

References Assert, InvalidTransactionId, and ProcArrayRemove().

Referenced by InitProcessPhase2().

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

◆ SetStartupBufferPinWaitBufId()

void SetStartupBufferPinWaitBufId ( int  bufid)

Definition at line 645 of file proc.c.

References ProcGlobal, and PROC_HDR::startupBufferPinWaitBufId.

Referenced by LockBufferForCleanup().

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

Variable Documentation

◆ AuxiliaryProcs

◆ deadlock_state

DeadLockState deadlock_state = DS_NOT_YET_CHECKED
static

Definition at line 87 of file proc.c.

Referenced by CheckDeadLock(), and ProcSleep().

◆ DeadlockTimeout

int DeadlockTimeout = 1000

Definition at line 60 of file proc.c.

Referenced by ProcSleep(), and ResolveRecoveryConflictWithBufferPin().

◆ got_deadlock_timeout

volatile sig_atomic_t got_deadlock_timeout
static

Definition at line 90 of file proc.c.

Referenced by CheckDeadLockAlert(), and ProcSleep().

◆ IdleInTransactionSessionTimeout

int IdleInTransactionSessionTimeout = 0

Definition at line 63 of file proc.c.

Referenced by PostgresMain(), and ProcessInterrupts().

◆ lockAwaited

LOCALLOCK* lockAwaited = NULL
static

Definition at line 85 of file proc.c.

◆ LockTimeout

int LockTimeout = 0

Definition at line 62 of file proc.c.

Referenced by ProcSleep().

◆ log_lock_waits

bool log_lock_waits = false

Definition at line 64 of file proc.c.

Referenced by ProcSleep().

◆ MyPgXact

◆ MyProc

PGPROC* MyProc = NULL

Definition at line 67 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(), ConditionVariableTimedSleep(), CountOtherDBBackends(), CreateReplicationSlot(), EndPrepare(), errdetail_abort(), exec_eval_simple_expr(), exec_simple_check_plan(), 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(), MarkBufferDirtyHint(), MinimumActiveBackends(), ParallelWorkerMain(), pgstat_report_activity(), pgstat_report_wait_end(), pgstat_report_wait_start(), PostPrepare_Locks(), PrepareTransaction(), ProcArrayGroupClearXid(), ProcKill(), PublishStartupProcessInformation(), RecordTransactionCommit(), RecordTransactionCommitPrepared(), 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(), TerminateOtherDBBackends(), TransactionGroupUpdateXidStatus(), TransactionIdIsInProgress(), TransactionIdSetPageStatus(), TruncateMultiXact(), VirtualXactLockTableCleanup(), VirtualXactLockTableInsert(), WaitXLogInsertionsToFinish(), WALInsertLockAcquire(), WalReceiverMain(), WalWriterMain(), write_csvlog(), XidCacheRemoveRunningXids(), and XLogSaveBufferForHint().

◆ PreparedXactProcs

PGPROC* PreparedXactProcs = NULL

Definition at line 82 of file proc.c.

Referenced by PostmasterMarkPIDForWorkerNotify(), and TwoPhaseShmemInit().

◆ ProcGlobal

◆ ProcStructLock

◆ StatementTimeout

int StatementTimeout = 0

Definition at line 61 of file proc.c.

Referenced by enable_statement_timeout().