1
/*-------------------------------------------------------------------------
4
* POSTGRES inter-process communication initialization code.
6
* Portions Copyright (c) 1996-2005, 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.74 2004-12-31 22:00:56 pgsql Exp $
13
*-------------------------------------------------------------------------
17
#include "access/clog.h"
18
#include "access/subtrans.h"
19
#include "access/xlog.h"
20
#include "miscadmin.h"
21
#include "postmaster/bgwriter.h"
22
#include "postmaster/postmaster.h"
23
#include "storage/bufmgr.h"
24
#include "storage/freespace.h"
25
#include "storage/ipc.h"
26
#include "storage/lmgr.h"
27
#include "storage/lwlock.h"
28
#include "storage/pg_sema.h"
29
#include "storage/pg_shmem.h"
30
#include "storage/pmsignal.h"
31
#include "storage/proc.h"
32
#include "storage/sinval.h"
33
#include "storage/spin.h"
37
* CreateSharedMemoryAndSemaphores
38
* Creates and initializes shared memory and semaphores.
40
* This is called by the postmaster or by a standalone backend.
41
* It is also called by a backend forked from the postmaster in the
42
* EXEC_BACKEND case. In the latter case, the shared memory segment
43
* already exists and has been physically attached to, but we have to
44
* initialize pointers in local memory that reference the shared structures,
45
* because we didn't inherit the correct pointer values from the postmaster
46
* as we do in the fork() scenario. The easiest way to do that is to run
47
* through the same code as before. (Note that the called routines mostly
48
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
49
* This is a bit code-wasteful and could be cleaned up.)
51
* If "makePrivate" is true then we only need private memory, not shared
52
* memory. This is true for a standalone backend, false for a postmaster.
55
CreateSharedMemoryAndSemaphores(bool makePrivate,
59
PGShmemHeader *seghdr = NULL;
61
if (!IsUnderPostmaster)
67
* Size of the Postgres shared-memory block is estimated via
68
* moderately-accurate estimates for the big hogs, plus 100K for
69
* the stuff that's too small to bother with estimating.
71
size = hash_estimate_size(SHMEM_INDEX_SIZE, sizeof(ShmemIndexEnt));
72
size += BufferShmemSize();
73
size += LockShmemSize(maxBackends);
74
size += ProcGlobalShmemSize(maxBackends);
75
size += XLOGShmemSize();
76
size += CLOGShmemSize();
77
size += SUBTRANSShmemSize();
78
size += LWLockShmemSize();
79
size += SInvalShmemSize(maxBackends);
80
size += FreeSpaceShmemSize();
81
size += BgWriterShmemSize();
83
size += ShmemBackendArraySize();
86
/* might as well round it off to a multiple of a typical page size */
87
size += 8192 - (size % 8192);
89
elog(DEBUG3, "invoking IpcMemoryCreate(size=%d)", size);
92
* Create the shmem segment
94
seghdr = PGSharedMemoryCreate(size, makePrivate, port);
99
numSemas = ProcGlobalSemas(maxBackends);
100
numSemas += SpinlockSemas();
101
PGReserveSemaphores(numSemas, port);
106
* We are reattaching to an existing shared memory segment.
107
* This should only be reached in the EXEC_BACKEND case, and
108
* even then only with makePrivate == false.
111
Assert(!makePrivate);
112
Assert(UsedShmemSegAddr != NULL);
113
seghdr = UsedShmemSegAddr;
115
elog(PANIC, "should be attached to shared memory already");
121
* Set up shared memory allocation mechanism
123
InitShmemAllocation(seghdr, !IsUnderPostmaster);
126
* Now initialize LWLocks, which do shared memory allocation and are
127
* needed for InitShmemIndex.
129
if (!IsUnderPostmaster)
133
* Set up shmem.c index hashtable
138
* Set up xlog, clog, and buffers
146
* Set up lock manager
149
InitLockTable(maxBackends);
152
* Set up process table
154
InitProcGlobal(maxBackends);
157
* Set up shared-inval messaging
159
CreateSharedInvalidationState(maxBackends);
162
* Set up free-space map
167
* Set up interprocess signaling mechanisms
175
* Alloc the win32 shared backend array
177
if (!IsUnderPostmaster)
178
ShmemBackendArrayAllocation();