1 /*-------------------------------------------------------------------------
4 * POSTGRES inter-process communication initialization code.
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.106 2010/09/15 10:06:21 heikki Exp $
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/procarray.h"
36 #include "storage/procsignal.h"
37 #include "storage/sinvaladt.h"
38 #include "storage/spin.h"
41 shmem_startup_hook_type shmem_startup_hook = NULL;
43 static Size total_addin_request = 0;
44 static bool addin_request_allowed = true;
48 * RequestAddinShmemSpace
49 * Request that extra shmem space be allocated for use by
52 * This is only useful if called from the _PG_init hook of a library that
53 * is loaded into the postmaster via shared_preload_libraries. Once
54 * shared memory has been allocated, calls will be ignored. (We could
55 * raise an error, but it seems better to make it a no-op, so that
56 * libraries containing such calls can be reloaded if needed.)
59 RequestAddinShmemSpace(Size size)
61 if (IsUnderPostmaster || !addin_request_allowed)
62 return; /* too late */
63 total_addin_request = add_size(total_addin_request, size);
68 * CreateSharedMemoryAndSemaphores
69 * Creates and initializes shared memory and semaphores.
71 * This is called by the postmaster or by a standalone backend.
72 * It is also called by a backend forked from the postmaster in the
73 * EXEC_BACKEND case. In the latter case, the shared memory segment
74 * already exists and has been physically attached to, but we have to
75 * initialize pointers in local memory that reference the shared structures,
76 * because we didn't inherit the correct pointer values from the postmaster
77 * as we do in the fork() scenario. The easiest way to do that is to run
78 * through the same code as before. (Note that the called routines mostly
79 * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
80 * This is a bit code-wasteful and could be cleaned up.)
82 * If "makePrivate" is true then we only need private memory, not shared
83 * memory. This is true for a standalone backend, false for a postmaster.
86 CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
88 if (!IsUnderPostmaster)
90 PGShmemHeader *seghdr;
95 * Size of the Postgres shared-memory block is estimated via
96 * moderately-accurate estimates for the big hogs, plus 100K for the
97 * stuff that's too small to bother with estimating.
99 * We take some care during this phase to ensure that the total size
100 * request doesn't overflow size_t. If this gets through, we don't
101 * need to be so careful during the actual allocation phase.
104 size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
105 sizeof(ShmemIndexEnt)));
106 size = add_size(size, BufferShmemSize());
107 size = add_size(size, LockShmemSize());
108 size = add_size(size, ProcGlobalShmemSize());
109 size = add_size(size, XLOGShmemSize());
110 size = add_size(size, CLOGShmemSize());
111 size = add_size(size, SUBTRANSShmemSize());
112 size = add_size(size, TwoPhaseShmemSize());
113 size = add_size(size, MultiXactShmemSize());
114 size = add_size(size, LWLockShmemSize());
115 size = add_size(size, ProcArrayShmemSize());
116 size = add_size(size, BackendStatusShmemSize());
117 size = add_size(size, SInvalShmemSize());
118 size = add_size(size, PMSignalShmemSize());
119 size = add_size(size, ProcSignalShmemSize());
120 size = add_size(size, BgWriterShmemSize());
121 size = add_size(size, AutoVacuumShmemSize());
122 size = add_size(size, WalSndShmemSize());
123 size = add_size(size, WalRcvShmemSize());
124 size = add_size(size, BTreeShmemSize());
125 size = add_size(size, SyncScanShmemSize());
126 size = add_size(size, AsyncShmemSize());
128 size = add_size(size, ShmemBackendArraySize());
131 /* freeze the addin request size and include it */
132 addin_request_allowed = false;
133 size = add_size(size, total_addin_request);
135 /* might as well round it off to a multiple of a typical page size */
136 size = add_size(size, 8192 - (size % 8192));
138 elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
139 (unsigned long) size);
142 * Create the shmem segment
144 seghdr = PGSharedMemoryCreate(size, makePrivate, port);
146 InitShmemAccess(seghdr);
151 numSemas = ProcGlobalSemas();
152 numSemas += SpinlockSemas();
153 PGReserveSemaphores(numSemas, port);
158 * We are reattaching to an existing shared memory segment. This
159 * should only be reached in the EXEC_BACKEND case, and even then only
160 * with makePrivate == false.
163 Assert(!makePrivate);
165 elog(PANIC, "should be attached to shared memory already");
170 * Set up shared memory allocation mechanism
172 if (!IsUnderPostmaster)
173 InitShmemAllocation();
176 * Now initialize LWLocks, which do shared memory allocation and are
177 * needed for InitShmemIndex.
179 if (!IsUnderPostmaster)
183 * Set up shmem.c index hashtable
188 * Set up xlog, clog, and buffers
194 MultiXactShmemInit();
198 * Set up lock manager
203 * Set up process table
205 if (!IsUnderPostmaster)
207 CreateSharedProcArray();
208 CreateSharedBackendStatus();
211 * Set up shared-inval messaging
213 CreateSharedInvalidationState();
216 * Set up interprocess signaling mechanisms
219 ProcSignalShmemInit();
221 AutoVacuumShmemInit();
226 * Set up other modules that need some shared memory space
235 * Alloc the win32 shared backend array
237 if (!IsUnderPostmaster)
238 ShmemBackendArrayAllocation();
242 * Now give loadable modules a chance to set up their shmem allocations
244 if (shmem_startup_hook)
245 shmem_startup_hook();