1
/*-------------------------------------------------------------------------
4
* POSTGRES inter-process communication initialization code.
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/storage/ipc/ipci.c
13
*-------------------------------------------------------------------------
17
#include "access/clog.h"
18
#include "access/heapam.h"
19
#include "access/multixact.h"
20
#include "access/nbtree.h"
21
#include "access/subtrans.h"
22
#include "access/twophase.h"
23
#include "commands/async.h"
24
#include "miscadmin.h"
26
#include "postmaster/autovacuum.h"
27
#include "postmaster/bgwriter.h"
28
#include "postmaster/postmaster.h"
29
#include "replication/walreceiver.h"
30
#include "replication/walsender.h"
31
#include "storage/bufmgr.h"
32
#include "storage/ipc.h"
33
#include "storage/pg_shmem.h"
34
#include "storage/pmsignal.h"
35
#include "storage/predicate.h"
36
#include "storage/procarray.h"
37
#include "storage/procsignal.h"
38
#include "storage/sinvaladt.h"
39
#include "storage/spin.h"
42
shmem_startup_hook_type shmem_startup_hook = NULL;
44
static Size total_addin_request = 0;
45
static bool addin_request_allowed = true;
49
* RequestAddinShmemSpace
50
* Request that extra shmem space be allocated for use by
53
* This is only useful if called from the _PG_init hook of a library that
54
* is loaded into the postmaster via shared_preload_libraries. Once
55
* shared memory has been allocated, calls will be ignored. (We could
56
* raise an error, but it seems better to make it a no-op, so that
57
* libraries containing such calls can be reloaded if needed.)
60
RequestAddinShmemSpace(Size size)
62
if (IsUnderPostmaster || !addin_request_allowed)
63
return; /* too late */
64
total_addin_request = add_size(total_addin_request, size);
69
* CreateSharedMemoryAndSemaphores
70
* Creates and initializes shared memory and semaphores.
72
* This is called by the postmaster or by a standalone backend.
73
* It is also called by a backend forked from the postmaster in the
74
* EXEC_BACKEND case. In the latter case, the shared memory segment
75
* already exists and has been physically attached to, but we have to
76
* initialize pointers in local memory that reference the shared structures,
77
* because we didn't inherit the correct pointer values from the postmaster
78
* as we do in the fork() scenario. The easiest way to do that is to run
79
* through the same code as before. (Note that the called routines mostly
80
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
81
* This is a bit code-wasteful and could be cleaned up.)
83
* If "makePrivate" is true then we only need private memory, not shared
84
* memory. This is true for a standalone backend, false for a postmaster.
87
CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
89
if (!IsUnderPostmaster)
91
PGShmemHeader *seghdr;
96
* Size of the Postgres shared-memory block is estimated via
97
* moderately-accurate estimates for the big hogs, plus 100K for the
98
* stuff that's too small to bother with estimating.
100
* We take some care during this phase to ensure that the total size
101
* request doesn't overflow size_t. If this gets through, we don't
102
* need to be so careful during the actual allocation phase.
105
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
106
sizeof(ShmemIndexEnt)));
107
size = add_size(size, BufferShmemSize());
108
size = add_size(size, LockShmemSize());
109
size = add_size(size, PredicateLockShmemSize());
110
size = add_size(size, ProcGlobalShmemSize());
111
size = add_size(size, XLOGShmemSize());
112
size = add_size(size, CLOGShmemSize());
113
size = add_size(size, SUBTRANSShmemSize());
114
size = add_size(size, TwoPhaseShmemSize());
115
size = add_size(size, MultiXactShmemSize());
116
size = add_size(size, LWLockShmemSize());
117
size = add_size(size, ProcArrayShmemSize());
118
size = add_size(size, BackendStatusShmemSize());
119
size = add_size(size, SInvalShmemSize());
120
size = add_size(size, PMSignalShmemSize());
121
size = add_size(size, ProcSignalShmemSize());
122
size = add_size(size, BgWriterShmemSize());
123
size = add_size(size, AutoVacuumShmemSize());
124
size = add_size(size, WalSndShmemSize());
125
size = add_size(size, WalRcvShmemSize());
126
size = add_size(size, BTreeShmemSize());
127
size = add_size(size, SyncScanShmemSize());
128
size = add_size(size, AsyncShmemSize());
130
size = add_size(size, ShmemBackendArraySize());
133
/* freeze the addin request size and include it */
134
addin_request_allowed = false;
135
size = add_size(size, total_addin_request);
137
/* might as well round it off to a multiple of a typical page size */
138
size = add_size(size, 8192 - (size % 8192));
140
elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
141
(unsigned long) size);
144
* Create the shmem segment
146
seghdr = PGSharedMemoryCreate(size, makePrivate, port);
148
InitShmemAccess(seghdr);
153
numSemas = ProcGlobalSemas();
154
numSemas += SpinlockSemas();
155
PGReserveSemaphores(numSemas, port);
160
* We are reattaching to an existing shared memory segment. This
161
* should only be reached in the EXEC_BACKEND case, and even then only
162
* with makePrivate == false.
165
Assert(!makePrivate);
167
elog(PANIC, "should be attached to shared memory already");
172
* Set up shared memory allocation mechanism
174
if (!IsUnderPostmaster)
175
InitShmemAllocation();
178
* Now initialize LWLocks, which do shared memory allocation and are
179
* needed for InitShmemIndex.
181
if (!IsUnderPostmaster)
185
* Set up shmem.c index hashtable
190
* Set up xlog, clog, and buffers
196
MultiXactShmemInit();
200
* Set up lock manager
205
* Set up predicate lock manager
207
InitPredicateLocks();
210
* Set up process table
212
if (!IsUnderPostmaster)
214
CreateSharedProcArray();
215
CreateSharedBackendStatus();
218
* Set up shared-inval messaging
220
CreateSharedInvalidationState();
223
* Set up interprocess signaling mechanisms
226
ProcSignalShmemInit();
228
AutoVacuumShmemInit();
233
* Set up other modules that need some shared memory space
242
* Alloc the win32 shared backend array
244
if (!IsUnderPostmaster)
245
ShmemBackendArrayAllocation();
249
* Now give loadable modules a chance to set up their shmem allocations
251
if (shmem_startup_hook)
252
shmem_startup_hook();