summaryrefslogtreecommitdiff
path: root/src/include/storage/proc.h
blob: cba32ecec2178ecf0040253555de59971d7dca1c (plain)
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 */