1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
/*-------------------------------------------------------------------------
*
* proc.h
* per-process shared memory data structures
*
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: proc.h,v 1.53 2001/11/05 17:46:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef _PROC_H_
#define _PROC_H_
#include "access/xlog.h"
#include "storage/backendid.h"
#include "storage/ipc.h"
#include "storage/lock.h"
typedef struct
{
IpcSemaphoreId semId; /* SysV semaphore set ID */
int semNum; /* semaphore number within set */
} SEMA;
/*
* Each backend has a PROC struct in shared memory. There is also a list of
* currently-unused PROC structs that will be reallocated to new backends.
*
* links: list link for any list the PROC is in. When waiting for a lock,
* the PROC is linked into that lock's waitProcs queue. A recycled PROC
* is linked into ProcGlobal's freeProcs list.
*/
struct PROC
{
/* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */
SHM_QUEUE links; /* list link if process is in a list */
SEMA sem; /* ONE semaphore to sleep on */
int errType; /* STATUS_OK or STATUS_ERROR after wakeup */
TransactionId xid; /* transaction currently being executed by
* this proc */
TransactionId xmin; /* minimal running XID as it was when we
* were starting our xact: vacuum must not
* remove tuples deleted by xid >= xmin ! */
int pid; /* This backend's process id */
Oid databaseId; /* OID of database this backend is using */
/*
* XLOG location of first XLOG record written by this backend's
* current transaction. If backend is not in a transaction or hasn't
* yet modified anything, logRec.xrecoff is zero.
*/
XLogRecPtr logRec;
/* Info about LWLock the process is currently waiting for, if any. */
bool lwWaiting; /* true if waiting for an LW lock */
bool lwExclusive; /* true if waiting for exclusive access */
struct PROC *lwWaitLink; /* next waiter for same LW lock */
/* Info about lock the process is currently waiting for, if any. */
/* waitLock and waitHolder are NULL if not currently waiting. */
LOCK *waitLock; /* Lock object we're sleeping on ... */
HOLDER *waitHolder; /* Per-holder info for awaited lock */
LOCKMODE waitLockMode; /* type of lock we're waiting for */
LOCKMASK heldLocks; /* bitmask for lock types already held on
* this lock object by this backend */
SHM_QUEUE procHolders; /* list of HOLDER objects for locks held
* or awaited by this backend */
};
/* NOTE: "typedef struct PROC PROC" appears in storage/lock.h. */
extern PROC *MyProc;
/*
* There is one ProcGlobal struct for the whole installation.
*
* PROC_NSEMS_PER_SET is the number of semaphores in each sys-V semaphore set
* we allocate. It must be no more than 32 (or however many bits in an int
* on your machine), or our free-semaphores bitmap won't work. It also must
* be *less than* your kernel's SEMMSL (max semaphores per set) parameter,
* which is often around 25. (Less than, because we allocate one extra sema
* in each set for identification purposes.)
*
* PROC_SEM_MAP_ENTRIES is the number of semaphore sets we need to allocate
* to keep track of up to maxBackends backends.
*/
#define PROC_NSEMS_PER_SET 16
#define PROC_SEM_MAP_ENTRIES(maxBackends) (((maxBackends)-1)/PROC_NSEMS_PER_SET+1)
typedef struct
{
/* info about a single set of per-process semaphores */
IpcSemaphoreId procSemId;
int32 freeSemMap;
/*
* In freeSemMap, bit i is set if the i'th semaphore of this sema set
* is allocated to a process. (i counts from 0 at the LSB)
*/
} SEM_MAP_ENTRY;
typedef struct PROC_HDR
{
/* Head of list of free PROC structures */
SHMEM_OFFSET freeProcs;
/* Info about semaphore sets used for per-process semaphores */
int semMapEntries;
/*
* VARIABLE LENGTH ARRAY: actual length is semMapEntries. THIS MUST BE
* LAST IN THE STRUCT DECLARATION.
*/
SEM_MAP_ENTRY procSemMap[1];
} PROC_HDR;
/* configurable option */
extern int DeadlockTimeout;
/*
* Function Prototypes
*/
extern void InitProcGlobal(int maxBackends);
extern void InitProcess(void);
extern void InitDummyProcess(void);
extern void ProcReleaseLocks(bool isCommit);
extern void ProcQueueInit(PROC_QUEUE *queue);
extern int ProcSleep(LOCKMETHODTABLE *lockMethodTable, LOCKMODE lockmode,
LOCK *lock, HOLDER *holder);
extern PROC *ProcWakeup(PROC *proc, int errType);
extern void ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock);
extern bool LockWaitCancel(void);
extern void HandleDeadLock(SIGNAL_ARGS);
extern void ProcWaitForSignal(void);
extern void ProcCancelWaitForSignal(void);
extern void ProcSendSignal(BackendId procId);
extern bool enable_sigalrm_interrupt(int delayms);
extern bool disable_sigalrm_interrupt(void);
#endif /* PROC_H */
|