Commit 349f40b2 authored by Tom Lane's avatar Tom Lane

Rearrange backend startup sequence so that ShmemIndexLock can become

an LWLock instead of a spinlock.  This hardly matters on Unix machines
but should improve startup performance on Windows (or any port using
EXEC_BACKEND).  Per previous discussion.
parent e0078ea2
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.209 2005/11/22 18:17:07 momjian Exp $ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.210 2006/01/04 21:06:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -381,22 +381,19 @@ BootstrapMain(int argc, char *argv[]) ...@@ -381,22 +381,19 @@ BootstrapMain(int argc, char *argv[])
BaseInit(); BaseInit();
/* /*
* We aren't going to do the full InitPostgres pushups, but there are a * When we are a dummy process, we aren't going to do the full
* couple of things that need to get lit up even in a dummy process. * InitPostgres pushups, but there are a couple of things that need
* to get lit up even in a dummy process.
*/ */
if (IsUnderPostmaster) if (IsUnderPostmaster)
{ {
/* set up proc.c to get use of LWLocks */ /*
switch (xlogop) * Create a PGPROC so we can use LWLocks. In the EXEC_BACKEND case,
{ * this was already done by SubPostmasterMain().
case BS_XLOG_BGWRITER: */
InitDummyProcess(DUMMY_PROC_BGWRITER); #ifndef EXEC_BACKEND
break; InitDummyProcess();
#endif
default:
InitDummyProcess(DUMMY_PROC_DEFAULT);
break;
}
/* finish setting up bufmgr.c */ /* finish setting up bufmgr.c */
InitBufferPoolBackend(); InitBufferPoolBackend();
...@@ -437,11 +434,17 @@ BootstrapMain(int argc, char *argv[]) ...@@ -437,11 +434,17 @@ BootstrapMain(int argc, char *argv[])
proc_exit(1); proc_exit(1);
} }
/*
* We must be getting invoked for bootstrap mode
*/
Assert(!IsUnderPostmaster);
SetProcessingMode(BootstrapProcessing); SetProcessingMode(BootstrapProcessing);
/* /*
* backend initialization * Do backend-like initialization for bootstrap mode
*/ */
InitProcess();
(void) InitPostgres(dbname, NULL); (void) InitPostgres(dbname, NULL);
/* /*
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.8 2005/11/28 17:23:11 alvherre Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.9 2006/01/04 21:06:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -167,6 +167,9 @@ autovac_start(void) ...@@ -167,6 +167,9 @@ autovac_start(void)
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(false); ClosePostmasterPorts(false);
/* Lose the postmaster's on-exit routines */
on_exit_reset();
AutoVacMain(0, NULL); AutoVacMain(0, NULL);
break; break;
#endif #endif
...@@ -230,9 +233,6 @@ AutoVacMain(int argc, char *argv[]) ...@@ -230,9 +233,6 @@ AutoVacMain(int argc, char *argv[])
/* reset MyProcPid */ /* reset MyProcPid */
MyProcPid = getpid(); MyProcPid = getpid();
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* Identify myself via ps */ /* Identify myself via ps */
init_ps_display("autovacuum process", "", ""); init_ps_display("autovacuum process", "", "");
set_ps_display(""); set_ps_display("");
...@@ -268,6 +268,16 @@ AutoVacMain(int argc, char *argv[]) ...@@ -268,6 +268,16 @@ AutoVacMain(int argc, char *argv[])
/* Early initialization */ /* Early initialization */
BaseInit(); BaseInit();
/*
* Create a per-backend PGPROC struct in shared memory, except in
* the EXEC_BACKEND case where this was done in SubPostmasterMain.
* We must do this before we can use LWLocks (and in the EXEC_BACKEND
* case we already had to do some stuff with LWLocks).
*/
#ifndef EXEC_BACKEND
InitProcess();
#endif
/* /*
* If an exception is encountered, processing resumes here. * If an exception is encountered, processing resumes here.
* *
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.18 2005/10/15 02:49:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.19 2006/01/04 21:06:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -158,6 +158,9 @@ pgarch_start(void) ...@@ -158,6 +158,9 @@ pgarch_start(void)
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(false); ClosePostmasterPorts(false);
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* Drop our connection to postmaster's shared memory, as well */ /* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach(); PGSharedMemoryDetach();
...@@ -219,9 +222,6 @@ PgArchiverMain(int argc, char *argv[]) ...@@ -219,9 +222,6 @@ PgArchiverMain(int argc, char *argv[])
MyProcPid = getpid(); /* reset MyProcPid */ MyProcPid = getpid(); /* reset MyProcPid */
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* /*
* Ignore all signals usually bound to some action in the postmaster, * Ignore all signals usually bound to some action in the postmaster,
* except for SIGHUP, SIGUSR1 and SIGQUIT. * except for SIGHUP, SIGUSR1 and SIGQUIT.
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * Copyright (c) 2001-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.118 2006/01/03 19:54:08 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.119 2006/01/04 21:06:31 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -147,6 +147,7 @@ static int pgStatNumBackends = 0; ...@@ -147,6 +147,7 @@ static int pgStatNumBackends = 0;
static volatile bool need_statwrite; static volatile bool need_statwrite;
/* ---------- /* ----------
* Local function forward declarations * Local function forward declarations
* ---------- * ----------
...@@ -608,6 +609,9 @@ pgstat_start(void) ...@@ -608,6 +609,9 @@ pgstat_start(void)
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(false); ClosePostmasterPorts(false);
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* Drop our connection to postmaster's shared memory, as well */ /* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach(); PGSharedMemoryDetach();
...@@ -1465,9 +1469,6 @@ PgstatBufferMain(int argc, char *argv[]) ...@@ -1465,9 +1469,6 @@ PgstatBufferMain(int argc, char *argv[])
MyProcPid = getpid(); /* reset MyProcPid */ MyProcPid = getpid(); /* reset MyProcPid */
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* /*
* Ignore all signals usually bound to some action in the postmaster, * Ignore all signals usually bound to some action in the postmaster,
* except for SIGCHLD and SIGQUIT --- see pgstat_recvbuffer. * except for SIGCHLD and SIGQUIT --- see pgstat_recvbuffer.
...@@ -1551,10 +1552,10 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1551,10 +1552,10 @@ PgstatCollectorMain(int argc, char *argv[])
fd_set rfds; fd_set rfds;
int readPipe; int readPipe;
int len = 0; int len = 0;
struct itimerval timeval; struct itimerval timeout;
HASHCTL hash_ctl; HASHCTL hash_ctl;
bool need_timer = false; bool need_timer = false;
MyProcPid = getpid(); /* reset MyProcPid */ MyProcPid = getpid(); /* reset MyProcPid */
/* /*
...@@ -1597,11 +1598,15 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1597,11 +1598,15 @@ PgstatCollectorMain(int argc, char *argv[])
init_ps_display("stats collector process", "", ""); init_ps_display("stats collector process", "", "");
set_ps_display(""); set_ps_display("");
/*
* Arrange to write the initial status file right away
*/
need_statwrite = true; need_statwrite = true;
MemSet(&timeval, 0, sizeof(struct itimerval)); /* Preset the delay between status file writes */
timeval.it_value.tv_sec = PGSTAT_STAT_INTERVAL / 1000; MemSet(&timeout, 0, sizeof(struct itimerval));
timeval.it_value.tv_usec = PGSTAT_STAT_INTERVAL % 1000; timeout.it_value.tv_sec = PGSTAT_STAT_INTERVAL / 1000;
timeout.it_value.tv_usec = PGSTAT_STAT_INTERVAL % 1000;
/* /*
* Read in an existing statistics stats file or initialize the stats to * Read in an existing statistics stats file or initialize the stats to
...@@ -1634,6 +1639,12 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1634,6 +1639,12 @@ PgstatCollectorMain(int argc, char *argv[])
*/ */
for (;;) for (;;)
{ {
/*
* If time to write the stats file, do so. Note that the alarm
* interrupt isn't re-enabled immediately, but only after we next
* receive a stats message; so no cycles are wasted when there is
* nothing going on.
*/
if (need_statwrite) if (need_statwrite)
{ {
pgstat_write_statsfile(); pgstat_write_statsfile();
...@@ -1776,11 +1787,16 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1776,11 +1787,16 @@ PgstatCollectorMain(int argc, char *argv[])
*/ */
pgStatNumMessages++; pgStatNumMessages++;
/*
* If this is the first message after we wrote the stats file the
* last time, enable the alarm interrupt to make it be written
* again later.
*/
if (need_timer) if (need_timer)
{ {
if (setitimer(ITIMER_REAL, &timeval, NULL)) if (setitimer(ITIMER_REAL, &timeout, NULL))
ereport(ERROR, ereport(ERROR,
(errmsg("unable to set statistics collector timer: %m"))); (errmsg("could not set statistics collector timer: %m")));
need_timer = false; need_timer = false;
} }
} }
...@@ -1806,6 +1822,7 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1806,6 +1822,7 @@ PgstatCollectorMain(int argc, char *argv[])
} }
/* SIGALRM signal handler for collector process */
static void static void
force_statwrite(SIGNAL_ARGS) force_statwrite(SIGNAL_ARGS)
{ {
...@@ -1913,8 +1930,10 @@ pgstat_recvbuffer(void) ...@@ -1913,8 +1930,10 @@ pgstat_recvbuffer(void)
/* /*
* Wait for some work to do; but not for more than 10 seconds. (This * Wait for some work to do; but not for more than 10 seconds. (This
* determines how quickly we will shut down after an ungraceful * determines how quickly we will shut down after an ungraceful
* postmaster termination; so it needn't be very fast.) struct timeout * postmaster termination; so it needn't be very fast.)
* is modified by some operating systems. *
* struct timeout is modified by select() on some operating systems,
* so re-fill it each time.
*/ */
timeout.tv_sec = 10; timeout.tv_sec = 10;
timeout.tv_usec = 0; timeout.tv_usec = 0;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.476 2005/11/22 18:17:18 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.477 2006/01/04 21:06:31 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -262,6 +262,7 @@ static void CleanupBackend(int pid, int exitstatus); ...@@ -262,6 +262,7 @@ static void CleanupBackend(int pid, int exitstatus);
static void HandleChildCrash(int pid, int exitstatus, const char *procname); static void HandleChildCrash(int pid, int exitstatus, const char *procname);
static void LogChildExit(int lev, const char *procname, static void LogChildExit(int lev, const char *procname,
int pid, int exitstatus); int pid, int exitstatus);
static void BackendInitialize(Port *port);
static int BackendRun(Port *port); static int BackendRun(Port *port);
static void ExitPostmaster(int status); static void ExitPostmaster(int status);
static void usage(const char *); static void usage(const char *);
...@@ -324,12 +325,12 @@ typedef struct ...@@ -324,12 +325,12 @@ typedef struct
unsigned long UsedShmemSegID; unsigned long UsedShmemSegID;
void *UsedShmemSegAddr; void *UsedShmemSegAddr;
slock_t *ShmemLock; slock_t *ShmemLock;
slock_t *ShmemIndexLock;
VariableCache ShmemVariableCache; VariableCache ShmemVariableCache;
void *ShmemIndexAlloc;
Backend *ShmemBackendArray; Backend *ShmemBackendArray;
LWLock *LWLockArray; LWLock *LWLockArray;
slock_t *ProcStructLock; slock_t *ProcStructLock;
PROC_HDR *ProcGlobal;
PGPROC *DummyProcs;
InheritableSocket pgStatSock; InheritableSocket pgStatSock;
InheritableSocket pgStatPipe0; InheritableSocket pgStatPipe0;
InheritableSocket pgStatPipe1; InheritableSocket pgStatPipe1;
...@@ -2496,6 +2497,26 @@ BackendStartup(Port *port) ...@@ -2496,6 +2497,26 @@ BackendStartup(Port *port)
if (pid == 0) /* child */ if (pid == 0) /* child */
{ {
free(bn); free(bn);
/*
* Let's clean up ourselves as the postmaster child, and close the
* postmaster's listen sockets. (In EXEC_BACKEND case this is all
* done in SubPostmasterMain.)
*/
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
MyProcPid = getpid(); /* reset MyProcPid */
/* We don't want the postmaster's proc_exit() handlers */
on_exit_reset();
/* Close the postmaster's sockets */
ClosePostmasterPorts(false);
/* Perform additional initialization and client authentication */
BackendInitialize(port);
/* And run the backend */
proc_exit(BackendRun(port)); proc_exit(BackendRun(port));
} }
#endif /* EXEC_BACKEND */ #endif /* EXEC_BACKEND */
...@@ -2589,47 +2610,26 @@ split_opts(char **argv, int *argcp, char *s) ...@@ -2589,47 +2610,26 @@ split_opts(char **argv, int *argcp, char *s)
/* /*
* BackendRun -- perform authentication, and if successful, * BackendInitialize -- initialize an interactive (postmaster-child)
* set up the backend's argument list and invoke PostgresMain() * backend process, and perform client authentication.
* *
* returns: * returns: nothing. Will not return at all if there's any failure.
* Shouldn't return at all. *
* If PostgresMain() fails, return status. * Note: this code does not depend on having any access to shared memory.
* In the EXEC_BACKEND case, we are physically attached to shared memory
* but have not yet set up most of our local pointers to shmem structures.
*/ */
static int static void
BackendRun(Port *port) BackendInitialize(Port *port)
{ {
int status; int status;
char remote_host[NI_MAXHOST]; char remote_host[NI_MAXHOST];
char remote_port[NI_MAXSERV]; char remote_port[NI_MAXSERV];
char remote_ps_data[NI_MAXHOST]; char remote_ps_data[NI_MAXHOST];
char **av;
int maxac;
int ac;
char protobuf[32];
int i;
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
/*
* Let's clean up ourselves as the postmaster child, and close the
* postmaster's listen sockets
*/
ClosePostmasterPorts(false);
/* We don't want the postmaster's proc_exit() handlers */
on_exit_reset();
/*
* Signal handlers setting is moved to tcop/postgres...
*/
/* Save port etc. for ps status */ /* Save port etc. for ps status */
MyProcPort = port; MyProcPort = port;
/* Reset MyProcPid to new backend's pid */
MyProcPid = getpid();
/* /*
* PreAuthDelay is a debugging aid for investigating problems in the * PreAuthDelay is a debugging aid for investigating problems in the
* authentication cycle: it can be set in postgresql.conf to allow time to * authentication cycle: it can be set in postgresql.conf to allow time to
...@@ -2698,7 +2698,7 @@ BackendRun(Port *port) ...@@ -2698,7 +2698,7 @@ BackendRun(Port *port)
remote_port))); remote_port)));
/* /*
* save remote_host and remote_port in port stucture * save remote_host and remote_port in port structure
*/ */
port->remote_host = strdup(remote_host); port->remote_host = strdup(remote_host);
port->remote_port = strdup(remote_port); port->remote_port = strdup(remote_port);
...@@ -2766,6 +2766,24 @@ BackendRun(Port *port) ...@@ -2766,6 +2766,24 @@ BackendRun(Port *port)
ereport(LOG, ereport(LOG,
(errmsg("connection authorized: user=%s database=%s", (errmsg("connection authorized: user=%s database=%s",
port->user_name, port->database_name))); port->user_name, port->database_name)));
}
/*
* BackendRun -- set up the backend's argument list and invoke PostgresMain()
*
* returns:
* Shouldn't return at all.
* If PostgresMain() fails, return status.
*/
static int
BackendRun(Port *port)
{
char **av;
int maxac;
int ac;
char protobuf[32];
int i;
/* /*
* Don't want backend to be able to see the postmaster random number * Don't want backend to be able to see the postmaster random number
...@@ -3184,6 +3202,9 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3184,6 +3202,9 @@ SubPostmasterMain(int argc, char *argv[])
MyProcPid = getpid(); /* reset MyProcPid */ MyProcPid = getpid(); /* reset MyProcPid */
/* Lose the postmaster's on-exit routines (really a no-op) */
on_exit_reset();
/* In EXEC_BACKEND case we will not have inherited these settings */ /* In EXEC_BACKEND case we will not have inherited these settings */
IsPostmasterEnvironment = true; IsPostmasterEnvironment = true;
whereToSendOutput = DestNone; whereToSendOutput = DestNone;
...@@ -3229,23 +3250,43 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3229,23 +3250,43 @@ SubPostmasterMain(int argc, char *argv[])
/* Run backend or appropriate child */ /* Run backend or appropriate child */
if (strcmp(argv[1], "-forkbackend") == 0) if (strcmp(argv[1], "-forkbackend") == 0)
{ {
/* BackendRun will close sockets */ Assert(argc == 3); /* shouldn't be any more args */
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
#ifdef USE_SSL /* Close the postmaster's sockets */
ClosePostmasterPorts(false);
/* /*
* Need to reinitialize the SSL library in the backend, since the * Need to reinitialize the SSL library in the backend, since the
* context structures contain function pointers and cannot be passed * context structures contain function pointers and cannot be passed
* through the parameter file. * through the parameter file.
*/ */
#ifdef USE_SSL
if (EnableSSL) if (EnableSSL)
secure_initialize(); secure_initialize();
#endif #endif
Assert(argc == 3); /* shouldn't be any more args */ /*
* Perform additional initialization and client authentication.
*
* We want to do this before InitProcess() for a couple of reasons:
* 1. so that we aren't eating up a PGPROC slot while waiting on the
* client.
* 2. so that if InitProcess() fails due to being out of PGPROC slots,
* we have already initialized libpq and are able to report the error
* to the client.
*/
BackendInitialize(&port);
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0);
/* And run the backend */
proc_exit(BackendRun(&port)); proc_exit(BackendRun(&port));
} }
if (strcmp(argv[1], "-forkboot") == 0) if (strcmp(argv[1], "-forkboot") == 0)
...@@ -3253,6 +3294,12 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3253,6 +3294,12 @@ SubPostmasterMain(int argc, char *argv[])
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(false); ClosePostmasterPorts(false);
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
InitDummyProcess();
/* Attach process to shared data structures */ /* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0); CreateSharedMemoryAndSemaphores(false, 0);
...@@ -3264,6 +3311,12 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -3264,6 +3311,12 @@ SubPostmasterMain(int argc, char *argv[])
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(false); ClosePostmasterPorts(false);
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
InitProcess();
/* Attach process to shared data structures */ /* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores(false, 0); CreateSharedMemoryAndSemaphores(false, 0);
...@@ -3630,10 +3683,10 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname) ...@@ -3630,10 +3683,10 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname)
* functions * functions
*/ */
extern slock_t *ShmemLock; extern slock_t *ShmemLock;
extern slock_t *ShmemIndexLock;
extern void *ShmemIndexAlloc;
extern LWLock *LWLockArray; extern LWLock *LWLockArray;
extern slock_t *ProcStructLock; extern slock_t *ProcStructLock;
extern PROC_HDR *ProcGlobal;
extern PGPROC *DummyProcs;
extern int pgStatSock; extern int pgStatSock;
extern int pgStatPipe[2]; extern int pgStatPipe[2];
...@@ -3671,13 +3724,13 @@ save_backend_variables(BackendParameters * param, Port *port, ...@@ -3671,13 +3724,13 @@ save_backend_variables(BackendParameters * param, Port *port,
param->UsedShmemSegAddr = UsedShmemSegAddr; param->UsedShmemSegAddr = UsedShmemSegAddr;
param->ShmemLock = ShmemLock; param->ShmemLock = ShmemLock;
param->ShmemIndexLock = ShmemIndexLock;
param->ShmemVariableCache = ShmemVariableCache; param->ShmemVariableCache = ShmemVariableCache;
param->ShmemIndexAlloc = ShmemIndexAlloc;
param->ShmemBackendArray = ShmemBackendArray; param->ShmemBackendArray = ShmemBackendArray;
param->LWLockArray = LWLockArray; param->LWLockArray = LWLockArray;
param->ProcStructLock = ProcStructLock; param->ProcStructLock = ProcStructLock;
param->ProcGlobal = ProcGlobal;
param->DummyProcs = DummyProcs;
write_inheritable_socket(&param->pgStatSock, pgStatSock, childPid); write_inheritable_socket(&param->pgStatSock, pgStatSock, childPid);
write_inheritable_socket(&param->pgStatPipe0, pgStatPipe[0], childPid); write_inheritable_socket(&param->pgStatPipe0, pgStatPipe[0], childPid);
write_inheritable_socket(&param->pgStatPipe1, pgStatPipe[1], childPid); write_inheritable_socket(&param->pgStatPipe1, pgStatPipe[1], childPid);
...@@ -3876,13 +3929,13 @@ restore_backend_variables(BackendParameters * param, Port *port) ...@@ -3876,13 +3929,13 @@ restore_backend_variables(BackendParameters * param, Port *port)
UsedShmemSegAddr = param->UsedShmemSegAddr; UsedShmemSegAddr = param->UsedShmemSegAddr;
ShmemLock = param->ShmemLock; ShmemLock = param->ShmemLock;
ShmemIndexLock = param->ShmemIndexLock;
ShmemVariableCache = param->ShmemVariableCache; ShmemVariableCache = param->ShmemVariableCache;
ShmemIndexAlloc = param->ShmemIndexAlloc;
ShmemBackendArray = param->ShmemBackendArray; ShmemBackendArray = param->ShmemBackendArray;
LWLockArray = param->LWLockArray; LWLockArray = param->LWLockArray;
ProcStructLock = param->ProcStructLock; ProcStructLock = param->ProcStructLock;
ProcGlobal = param->ProcGlobal;
DummyProcs = param->DummyProcs;
read_inheritable_socket(&pgStatSock, &param->pgStatSock); read_inheritable_socket(&pgStatSock, &param->pgStatSock);
read_inheritable_socket(&pgStatPipe[0], &param->pgStatPipe0); read_inheritable_socket(&pgStatPipe[0], &param->pgStatPipe0);
read_inheritable_socket(&pgStatPipe[1], &param->pgStatPipe1); read_inheritable_socket(&pgStatPipe[1], &param->pgStatPipe1);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.21 2005/11/22 18:17:18 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.22 2006/01/04 21:06:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -135,9 +135,6 @@ SysLoggerMain(int argc, char *argv[]) ...@@ -135,9 +135,6 @@ SysLoggerMain(int argc, char *argv[])
MyProcPid = getpid(); /* reset MyProcPid */ MyProcPid = getpid(); /* reset MyProcPid */
/* Lose the postmaster's on-exit routines */
on_exit_reset();
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
syslogger_parseArgs(argc, argv); syslogger_parseArgs(argc, argv);
#endif /* EXEC_BACKEND */ #endif /* EXEC_BACKEND */
...@@ -460,6 +457,9 @@ SysLogger_Start(void) ...@@ -460,6 +457,9 @@ SysLogger_Start(void)
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(true); ClosePostmasterPorts(true);
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* Drop our connection to postmaster's shared memory, as well */ /* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach(); PGSharedMemoryDetach();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.80 2005/12/09 01:22:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.81 2006/01/04 21:06:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -57,10 +57,9 @@ ...@@ -57,10 +57,9 @@
void void
CreateSharedMemoryAndSemaphores(bool makePrivate, int port) CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
{ {
PGShmemHeader *seghdr = NULL;
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
PGShmemHeader *seghdr;
Size size; Size size;
int numSemas; int numSemas;
...@@ -104,6 +103,8 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) ...@@ -104,6 +103,8 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
*/ */
seghdr = PGSharedMemoryCreate(size, makePrivate, port); seghdr = PGSharedMemoryCreate(size, makePrivate, port);
InitShmemAccess(seghdr);
/* /*
* Create semaphores * Create semaphores
*/ */
...@@ -120,18 +121,16 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) ...@@ -120,18 +121,16 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
*/ */
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
Assert(!makePrivate); Assert(!makePrivate);
Assert(UsedShmemSegAddr != NULL);
seghdr = UsedShmemSegAddr;
#else #else
elog(PANIC, "should be attached to shared memory already"); elog(PANIC, "should be attached to shared memory already");
#endif #endif
} }
/* /*
* Set up shared memory allocation mechanism * Set up shared memory allocation mechanism
*/ */
InitShmemAllocation(seghdr, !IsUnderPostmaster); if (!IsUnderPostmaster)
InitShmemAllocation();
/* /*
* Now initialize LWLocks, which do shared memory allocation and are * Now initialize LWLocks, which do shared memory allocation and are
...@@ -163,7 +162,8 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) ...@@ -163,7 +162,8 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
/* /*
* Set up process table * Set up process table
*/ */
InitProcGlobal(); if (!IsUnderPostmaster)
InitProcGlobal();
CreateSharedProcArray(); CreateSharedProcArray();
/* /*
......
...@@ -8,25 +8,26 @@ ...@@ -8,25 +8,26 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.89 2005/12/29 18:08:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.90 2006/01/04 21:06:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
/* /*
* POSTGRES processes share one or more regions of shared memory. * POSTGRES processes share one or more regions of shared memory.
* The shared memory is created by a postmaster and is inherited * The shared memory is created by a postmaster and is inherited
* by each backend via fork(). The routines in this file are used for * by each backend via fork() (or, in some ports, via other OS-specific
* allocating and binding to shared memory data structures. * methods). The routines in this file are used for allocating and
* binding to shared memory data structures.
* *
* NOTES: * NOTES:
* (a) There are three kinds of shared memory data structures * (a) There are three kinds of shared memory data structures
* available to POSTGRES: fixed-size structures, queues and hash * available to POSTGRES: fixed-size structures, queues and hash
* tables. Fixed-size structures contain things like global variables * tables. Fixed-size structures contain things like global variables
* for a module and should never be allocated after the process * for a module and should never be allocated after the shared memory
* initialization phase. Hash tables have a fixed maximum size, but * initialization phase. Hash tables have a fixed maximum size, but
* their actual size can vary dynamically. When entries are added * their actual size can vary dynamically. When entries are added
* to the table, more space is allocated. Queues link data structures * to the table, more space is allocated. Queues link data structures
* that have been allocated either as fixed size structures or as hash * that have been allocated either within fixed-size structures or as hash
* buckets. Each shared data structure has a string name to identify * buckets. Each shared data structure has a string name to identify
* it (assigned in the module that declares it). * it (assigned in the module that declares it).
* *
...@@ -46,7 +47,14 @@ ...@@ -46,7 +47,14 @@
* of shared memory in a lot of different places (and changing * of shared memory in a lot of different places (and changing
* things during development), this is important. * things during development), this is important.
* *
* (c) memory allocation model: shared memory can never be * (c) In standard Unix-ish environments, individual backends do not
* need to re-establish their local pointers into shared memory, because
* they inherit correct values of those variables via fork() from the
* postmaster. However, this does not work in the EXEC_BACKEND case.
* In ports using EXEC_BACKEND, new backends have to set up their local
* pointers using the method described in (b) above.
* (d) memory allocation model: shared memory can never be
* freed, once allocated. Each hash table has its own free list, * freed, once allocated. Each hash table has its own free list,
* so hash buckets can be reused when an item is deleted. However, * so hash buckets can be reused when an item is deleted. However,
* if one hash table grows very large and then shrinks, its space * if one hash table grows very large and then shrinks, its space
...@@ -75,58 +83,59 @@ static SHMEM_OFFSET ShmemEnd; /* end+1 address of shared memory */ ...@@ -75,58 +83,59 @@ static SHMEM_OFFSET ShmemEnd; /* end+1 address of shared memory */
slock_t *ShmemLock; /* spinlock for shared memory and LWLock slock_t *ShmemLock; /* spinlock for shared memory and LWLock
* allocation */ * allocation */
NON_EXEC_STATIC slock_t *ShmemIndexLock; /* spinlock for ShmemIndex */
NON_EXEC_STATIC void *ShmemIndexAlloc = NULL; /* Memory actually allocated
* for ShmemIndex */
static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */ static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */
/* /*
* InitShmemAllocation() --- set up shared-memory allocation. * InitShmemAccess() --- set up basic pointers to shared memory.
* *
* Note: the argument should be declared "PGShmemHeader *seghdr", * Note: the argument should be declared "PGShmemHeader *seghdr",
* but we use void to avoid having to include ipc.h in shmem.h. * but we use void to avoid having to include ipc.h in shmem.h.
*/ */
void void
InitShmemAllocation(void *seghdr, bool init) InitShmemAccess(void *seghdr)
{ {
PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr; PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr;
/* Set up basic pointers to shared memory */
ShmemSegHdr = shmhdr; ShmemSegHdr = shmhdr;
ShmemBase = (SHMEM_OFFSET) shmhdr; ShmemBase = (SHMEM_OFFSET) shmhdr;
ShmemEnd = ShmemBase + shmhdr->totalsize; ShmemEnd = ShmemBase + shmhdr->totalsize;
}
if (init) /*
{ * InitShmemAllocation() --- set up shared-memory space allocation.
/* *
* Initialize the spinlocks used by ShmemAlloc/ShmemInitStruct. We * This should be called only in the postmaster or a standalone backend.
* have to do the space allocation the hard way, since ShmemAlloc */
* can't be called yet. void
*/ InitShmemAllocation(void)
ShmemLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset); {
shmhdr->freeoffset += MAXALIGN(sizeof(slock_t)); PGShmemHeader *shmhdr = ShmemSegHdr;
Assert(shmhdr->freeoffset <= shmhdr->totalsize);
ShmemIndexLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset); Assert(shmhdr != NULL);
shmhdr->freeoffset += MAXALIGN(sizeof(slock_t));
Assert(shmhdr->freeoffset <= shmhdr->totalsize);
SpinLockInit(ShmemLock); /*
SpinLockInit(ShmemIndexLock); * Initialize the spinlock used by ShmemAlloc. We have to do the
* space allocation the hard way, since obviously ShmemAlloc can't
* be called yet.
*/
ShmemLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset);
shmhdr->freeoffset += MAXALIGN(sizeof(slock_t));
Assert(shmhdr->freeoffset <= shmhdr->totalsize);
/* ShmemIndex can't be set up yet (need LWLocks first) */ SpinLockInit(ShmemLock);
ShmemIndex = (HTAB *) NULL;
/* /* ShmemIndex can't be set up yet (need LWLocks first) */
* Initialize ShmemVariableCache for transaction manager. shmhdr->indexoffset = 0;
*/ ShmemIndex = (HTAB *) NULL;
ShmemVariableCache = (VariableCache)
ShmemAlloc(sizeof(*ShmemVariableCache)); /*
memset(ShmemVariableCache, 0, sizeof(*ShmemVariableCache)); * Initialize ShmemVariableCache for transaction manager.
} * (This doesn't really belong here, but not worth moving.)
*/
ShmemVariableCache = (VariableCache)
ShmemAlloc(sizeof(*ShmemVariableCache));
memset(ShmemVariableCache, 0, sizeof(*ShmemVariableCache));
} }
/* /*
...@@ -194,7 +203,7 @@ ShmemIsValid(unsigned long addr) ...@@ -194,7 +203,7 @@ ShmemIsValid(unsigned long addr)
} }
/* /*
* InitShmemIndex() --- set up shmem index table. * InitShmemIndex() --- set up or attach to shmem index table.
*/ */
void void
InitShmemIndex(void) InitShmemIndex(void)
...@@ -239,15 +248,14 @@ InitShmemIndex(void) ...@@ -239,15 +248,14 @@ InitShmemIndex(void)
result->location = MAKE_OFFSET(ShmemIndex->hctl); result->location = MAKE_OFFSET(ShmemIndex->hctl);
result->size = SHMEM_INDEX_SIZE; result->size = SHMEM_INDEX_SIZE;
} }
/* now release the lock acquired in ShmemInitStruct */ /* now release the lock acquired in ShmemInitStruct */
SpinLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
} }
/* /*
* ShmemInitHash -- Create/Attach to and initialize * ShmemInitHash -- Create and initialize, or attach to, a
* shared memory hash table. * shared memory hash table.
* *
* We assume caller is doing some kind of synchronization * We assume caller is doing some kind of synchronization
...@@ -290,8 +298,8 @@ ShmemInitHash(const char *name, /* table string name for shmem index */ ...@@ -290,8 +298,8 @@ ShmemInitHash(const char *name, /* table string name for shmem index */
&found); &found);
/* /*
* shmem index is corrupted. Let someone else give the error message * If fail, shmem index is corrupted. Let caller give the error message
* since they have more information * since it has more information
*/ */
if (location == NULL) if (location == NULL)
return NULL; return NULL;
...@@ -315,8 +323,8 @@ ShmemInitHash(const char *name, /* table string name for shmem index */ ...@@ -315,8 +323,8 @@ ShmemInitHash(const char *name, /* table string name for shmem index */
* memory. * memory.
* *
* This is called during initialization to find or allocate * This is called during initialization to find or allocate
* a data structure in shared memory. If no other processes * a data structure in shared memory. If no other process
* have created the structure, this routine allocates space * has created the structure, this routine allocates space
* for it. If it exists already, a pointer to the existing * for it. If it exists already, a pointer to the existing
* table is returned. * table is returned.
* *
...@@ -334,15 +342,18 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -334,15 +342,18 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
strncpy(item.key, name, SHMEM_INDEX_KEYSIZE); strncpy(item.key, name, SHMEM_INDEX_KEYSIZE);
item.location = BAD_LOCATION; item.location = BAD_LOCATION;
SpinLockAcquire(ShmemIndexLock); LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
if (!ShmemIndex) if (!ShmemIndex)
{ {
PGShmemHeader *shmemseghdr = ShmemSegHdr;
Assert(strcmp(name, "ShmemIndex") == 0); Assert(strcmp(name, "ShmemIndex") == 0);
if (IsUnderPostmaster) if (IsUnderPostmaster)
{ {
/* Must be initializing a (non-standalone) backend */ /* Must be initializing a (non-standalone) backend */
Assert(ShmemIndexAlloc); Assert(shmemseghdr->indexoffset != 0);
structPtr = (void *) MAKE_PTR(shmemseghdr->indexoffset);
*foundPtr = TRUE; *foundPtr = TRUE;
} }
else else
...@@ -354,10 +365,12 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -354,10 +365,12 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
* Notice that the ShmemIndexLock is held until the shmem index * Notice that the ShmemIndexLock is held until the shmem index
* has been completely initialized. * has been completely initialized.
*/ */
Assert(shmemseghdr->indexoffset == 0);
structPtr = ShmemAlloc(size);
shmemseghdr->indexoffset = MAKE_OFFSET(structPtr);
*foundPtr = FALSE; *foundPtr = FALSE;
ShmemIndexAlloc = ShmemAlloc(size);
} }
return ShmemIndexAlloc; return structPtr;
} }
/* look it up in the shmem index */ /* look it up in the shmem index */
...@@ -366,7 +379,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -366,7 +379,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
if (!result) if (!result)
{ {
SpinLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory"))); errmsg("out of shared memory")));
...@@ -381,7 +394,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -381,7 +394,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
*/ */
if (result->size != size) if (result->size != size)
{ {
SpinLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
elog(WARNING, "ShmemIndex entry size is wrong"); elog(WARNING, "ShmemIndex entry size is wrong");
/* let caller print its message too */ /* let caller print its message too */
...@@ -398,7 +411,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -398,7 +411,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
/* out of memory */ /* out of memory */
Assert(ShmemIndex); Assert(ShmemIndex);
hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, NULL); hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, NULL);
SpinLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
...@@ -411,7 +424,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) ...@@ -411,7 +424,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
} }
Assert(ShmemIsValid((unsigned long) structPtr)); Assert(ShmemIsValid((unsigned long) structPtr));
SpinLockRelease(ShmemIndexLock); LWLockRelease(ShmemIndexLock);
return structPtr; return structPtr;
} }
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.474 2005/12/31 16:50:44 momjian Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.475 2006/01/04 21:06:31 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2860,7 +2860,6 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2860,7 +2860,6 @@ PostgresMain(int argc, char *argv[], const char *username)
PG_SETMASK(&BlockSig); /* block everything except SIGQUIT */ PG_SETMASK(&BlockSig); /* block everything except SIGQUIT */
if (IsUnderPostmaster) if (IsUnderPostmaster)
{ {
/* noninteractive case: nothing should be left after switches */ /* noninteractive case: nothing should be left after switches */
...@@ -2933,6 +2932,19 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2933,6 +2932,19 @@ PostgresMain(int argc, char *argv[], const char *username)
BuildFlatFiles(true); BuildFlatFiles(true);
} }
/*
* Create a per-backend PGPROC struct in shared memory, except in
* the EXEC_BACKEND case where this was done in SubPostmasterMain.
* We must do this before we can use LWLocks (and in the EXEC_BACKEND
* case we already had to do some stuff with LWLocks).
*/
#ifdef EXEC_BACKEND
if (!IsUnderPostmaster)
InitProcess();
#else
InitProcess();
#endif
/* /*
* General initialization. * General initialization.
* *
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.159 2005/11/22 18:17:26 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.160 2006/01/04 21:06:32 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
...@@ -311,6 +311,9 @@ BaseInit(void) ...@@ -311,6 +311,9 @@ BaseInit(void)
* can only be tested inside a transaction, so we want to do it during * can only be tested inside a transaction, so we want to do it during
* the startup transaction rather than doing a separate one in postgres.c.) * the startup transaction rather than doing a separate one in postgres.c.)
* *
* As of PostgreSQL 8.2, we expect InitProcess() was already called, so we
* already have a PGPROC struct ... but it's not filled in yet.
*
* Note: * Note:
* Be very careful with the order of calls in the InitPostgres function. * Be very careful with the order of calls in the InitPostgres function.
* -------------------------------- * --------------------------------
...@@ -383,17 +386,17 @@ InitPostgres(const char *dbname, const char *username) ...@@ -383,17 +386,17 @@ InitPostgres(const char *dbname, const char *username)
*/ */
/* /*
* Set up my per-backend PGPROC struct in shared memory. (We need to * Finish filling in the PGPROC struct, and add it to the ProcArray.
* know MyDatabaseId before we can do this, since it's entered into the * (We need to know MyDatabaseId before we can do this, since it's entered
* PGPROC struct.) * into the PGPROC struct.)
*
* Once I have done this, I am visible to other backends!
*/ */
InitProcess(); InitProcessPhase2();
/* /*
* Initialize my entry in the shared-invalidation manager's array of * Initialize my entry in the shared-invalidation manager's array of
* per-backend data. (Formerly this came before InitProcess, but now it * per-backend data.
* must happen after, because it uses MyProc.) Once I have done this, I
* am visible to other backends!
* *
* Sets up MyBackendId, a unique backend identifier. * Sets up MyBackendId, a unique backend identifier.
*/ */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.24 2005/12/11 21:02:18 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.25 2006/01/04 21:06:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,6 +27,7 @@ typedef enum LWLockId ...@@ -27,6 +27,7 @@ typedef enum LWLockId
{ {
BufMappingLock, BufMappingLock,
BufFreelistLock, BufFreelistLock,
ShmemIndexLock,
OidGenLock, OidGenLock,
XidGenLock, XidGenLock,
ProcArrayLock, ProcArrayLock,
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.16 2005/10/15 02:49:46 momjian Exp $ * $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.17 2006/01/04 21:06:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,10 +27,11 @@ ...@@ -27,10 +27,11 @@
typedef struct PGShmemHeader /* standard header for all Postgres shmem */ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
{ {
int32 magic; /* magic # to identify Postgres segments */ int32 magic; /* magic # to identify Postgres segments */
#define PGShmemMagic 679834893 #define PGShmemMagic 679834894
pid_t creatorPID; /* PID of creating process */ pid_t creatorPID; /* PID of creating process */
Size totalsize; /* total size of segment */ Size totalsize; /* total size of segment */
Size freeoffset; /* offset to first free space */ Size freeoffset; /* offset to first free space */
Size indexoffset; /* offset to ShmemIndex table */
#ifndef WIN32 /* Windows doesn't have useful inode#s */ #ifndef WIN32 /* Windows doesn't have useful inode#s */
dev_t device; /* device data directory is on */ dev_t device; /* device data directory is on */
ino_t inode; /* inode number of data directory */ ino_t inode; /* inode number of data directory */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.85 2005/12/11 21:02:18 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.86 2006/01/04 21:06:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -114,9 +114,10 @@ typedef struct PROC_HDR ...@@ -114,9 +114,10 @@ typedef struct PROC_HDR
int spins_per_delay; int spins_per_delay;
} PROC_HDR; } PROC_HDR;
/*
#define DUMMY_PROC_DEFAULT 0 * We set aside some extra PGPROC structures for "dummy" processes,
#define DUMMY_PROC_BGWRITER 1 * ie things that aren't full-fledged backends but need shmem access.
*/
#define NUM_DUMMY_PROCS 2 #define NUM_DUMMY_PROCS 2
...@@ -134,7 +135,8 @@ extern int ProcGlobalSemas(void); ...@@ -134,7 +135,8 @@ extern int ProcGlobalSemas(void);
extern Size ProcGlobalShmemSize(void); extern Size ProcGlobalShmemSize(void);
extern void InitProcGlobal(void); extern void InitProcGlobal(void);
extern void InitProcess(void); extern void InitProcess(void);
extern void InitDummyProcess(int proctype); extern void InitProcessPhase2(void);
extern void InitDummyProcess(void);
extern bool HaveNFreeProcs(int n); extern bool HaveNFreeProcs(int n);
extern void ProcReleaseLocks(bool isCommit); extern void ProcReleaseLocks(bool isCommit);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.45 2005/08/20 23:26:35 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.46 2006/01/04 21:06:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -61,7 +61,8 @@ typedef struct SHM_QUEUE ...@@ -61,7 +61,8 @@ typedef struct SHM_QUEUE
} SHM_QUEUE; } SHM_QUEUE;
/* shmem.c */ /* shmem.c */
extern void InitShmemAllocation(void *seghdr, bool init); extern void InitShmemAccess(void *seghdr);
extern void InitShmemAllocation(void);
extern void *ShmemAlloc(Size size); extern void *ShmemAlloc(Size size);
extern bool ShmemIsValid(unsigned long addr); extern bool ShmemIsValid(unsigned long addr);
extern void InitShmemIndex(void); extern void InitShmemIndex(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment