]> granicus.if.org Git - postgresql/blob - src/backend/storage/ipc/ipci.c
Update copyright for 2009.
[postgresql] / src / backend / storage / ipc / ipci.c
1 /*-------------------------------------------------------------------------
2  *
3  * ipci.c
4  *        POSTGRES inter-process communication initialization code.
5  *
6  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.98 2009/01/01 17:23:47 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
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 "miscadmin.h"
24 #include "pgstat.h"
25 #include "postmaster/autovacuum.h"
26 #include "postmaster/bgwriter.h"
27 #include "postmaster/postmaster.h"
28 #include "storage/bufmgr.h"
29 #include "storage/ipc.h"
30 #include "storage/pg_shmem.h"
31 #include "storage/pmsignal.h"
32 #include "storage/procarray.h"
33 #include "storage/sinvaladt.h"
34 #include "storage/spin.h"
35
36
37 static Size total_addin_request = 0;
38 static bool addin_request_allowed = true;
39
40
41 /*
42  * RequestAddinShmemSpace
43  *              Request that extra shmem space be allocated for use by
44  *              a loadable module.
45  *
46  * This is only useful if called from the _PG_init hook of a library that
47  * is loaded into the postmaster via shared_preload_libraries.  Once
48  * shared memory has been allocated, calls will be ignored.  (We could
49  * raise an error, but it seems better to make it a no-op, so that
50  * libraries containing such calls can be reloaded if needed.)
51  */
52 void
53 RequestAddinShmemSpace(Size size)
54 {
55         if (IsUnderPostmaster || !addin_request_allowed)
56                 return;                                 /* too late */
57         total_addin_request = add_size(total_addin_request, size);
58 }
59
60
61 /*
62  * CreateSharedMemoryAndSemaphores
63  *              Creates and initializes shared memory and semaphores.
64  *
65  * This is called by the postmaster or by a standalone backend.
66  * It is also called by a backend forked from the postmaster in the
67  * EXEC_BACKEND case.  In the latter case, the shared memory segment
68  * already exists and has been physically attached to, but we have to
69  * initialize pointers in local memory that reference the shared structures,
70  * because we didn't inherit the correct pointer values from the postmaster
71  * as we do in the fork() scenario.  The easiest way to do that is to run
72  * through the same code as before.  (Note that the called routines mostly
73  * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
74  * This is a bit code-wasteful and could be cleaned up.)
75  *
76  * If "makePrivate" is true then we only need private memory, not shared
77  * memory.      This is true for a standalone backend, false for a postmaster.
78  */
79 void
80 CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
81 {
82         if (!IsUnderPostmaster)
83         {
84                 PGShmemHeader *seghdr;
85                 Size            size;
86                 int                     numSemas;
87
88                 /*
89                  * Size of the Postgres shared-memory block is estimated via
90                  * moderately-accurate estimates for the big hogs, plus 100K for the
91                  * stuff that's too small to bother with estimating.
92                  *
93                  * We take some care during this phase to ensure that the total size
94                  * request doesn't overflow size_t.  If this gets through, we don't
95                  * need to be so careful during the actual allocation phase.
96                  */
97                 size = 100000;
98                 size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
99                                                                                                  sizeof(ShmemIndexEnt)));
100                 size = add_size(size, BufferShmemSize());
101                 size = add_size(size, LockShmemSize());
102                 size = add_size(size, ProcGlobalShmemSize());
103                 size = add_size(size, XLOGShmemSize());
104                 size = add_size(size, CLOGShmemSize());
105                 size = add_size(size, SUBTRANSShmemSize());
106                 size = add_size(size, TwoPhaseShmemSize());
107                 size = add_size(size, MultiXactShmemSize());
108                 size = add_size(size, LWLockShmemSize());
109                 size = add_size(size, ProcArrayShmemSize());
110                 size = add_size(size, BackendStatusShmemSize());
111                 size = add_size(size, SInvalShmemSize());
112                 size = add_size(size, BgWriterShmemSize());
113                 size = add_size(size, AutoVacuumShmemSize());
114                 size = add_size(size, BTreeShmemSize());
115                 size = add_size(size, SyncScanShmemSize());
116 #ifdef EXEC_BACKEND
117                 size = add_size(size, ShmemBackendArraySize());
118 #endif
119
120                 /* freeze the addin request size and include it */
121                 addin_request_allowed = false;
122                 size = add_size(size, total_addin_request);
123
124                 /* might as well round it off to a multiple of a typical page size */
125                 size = add_size(size, 8192 - (size % 8192));
126
127                 elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
128                          (unsigned long) size);
129
130                 /*
131                  * Create the shmem segment
132                  */
133                 seghdr = PGSharedMemoryCreate(size, makePrivate, port);
134
135                 InitShmemAccess(seghdr);
136
137                 /*
138                  * Create semaphores
139                  */
140                 numSemas = ProcGlobalSemas();
141                 numSemas += SpinlockSemas();
142                 PGReserveSemaphores(numSemas, port);
143         }
144         else
145         {
146                 /*
147                  * We are reattaching to an existing shared memory segment. This
148                  * should only be reached in the EXEC_BACKEND case, and even then only
149                  * with makePrivate == false.
150                  */
151 #ifdef EXEC_BACKEND
152                 Assert(!makePrivate);
153 #else
154                 elog(PANIC, "should be attached to shared memory already");
155 #endif
156         }
157
158         /*
159          * Set up shared memory allocation mechanism
160          */
161         if (!IsUnderPostmaster)
162                 InitShmemAllocation();
163
164         /*
165          * Now initialize LWLocks, which do shared memory allocation and are
166          * needed for InitShmemIndex.
167          */
168         if (!IsUnderPostmaster)
169                 CreateLWLocks();
170
171         /*
172          * Set up shmem.c index hashtable
173          */
174         InitShmemIndex();
175
176         /*
177          * Set up xlog, clog, and buffers
178          */
179         XLOGShmemInit();
180         CLOGShmemInit();
181         SUBTRANSShmemInit();
182         TwoPhaseShmemInit();
183         MultiXactShmemInit();
184         InitBufferPool();
185
186         /*
187          * Set up lock manager
188          */
189         InitLocks();
190
191         /*
192          * Set up process table
193          */
194         if (!IsUnderPostmaster)
195                 InitProcGlobal();
196         CreateSharedProcArray();
197         CreateSharedBackendStatus();
198
199         /*
200          * Set up shared-inval messaging
201          */
202         CreateSharedInvalidationState();
203
204         /*
205          * Set up interprocess signaling mechanisms
206          */
207         PMSignalInit();
208         BgWriterShmemInit();
209         AutoVacuumShmemInit();
210
211         /*
212          * Set up other modules that need some shared memory space
213          */
214         BTreeShmemInit();
215         SyncScanShmemInit();
216
217 #ifdef EXEC_BACKEND
218
219         /*
220          * Alloc the win32 shared backend array
221          */
222         if (!IsUnderPostmaster)
223                 ShmemBackendArrayAllocation();
224 #endif
225 }