diff options
Diffstat (limited to 'src/backend/storage')
-rw-r--r-- | src/backend/storage/buffer/bufmgr.c | 72 | ||||
-rw-r--r-- | src/backend/storage/ipc/ipci.c | 7 | ||||
-rw-r--r-- | src/backend/storage/ipc/pmsignal.c | 40 | ||||
-rw-r--r-- | src/backend/storage/lmgr/proc.c | 51 |
4 files changed, 70 insertions, 100 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 4f6772564a8..f718e33cd59 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.165 2004/05/08 19:09:25 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.166 2004/05/29 22:48:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -60,10 +60,6 @@ bool zero_damaged_pages = false; bool ShowPinTrace = false; #endif -int BgWriterDelay = 200; -int BgWriterPercent = 1; -int BgWriterMaxpages = 100; - long NDirectFileRead; /* some I/O's are direct file access. * bypass bufmgr */ long NDirectFileWrite; /* e.g., I/O in psort and hashjoin. */ @@ -863,72 +859,6 @@ FlushBufferPool(void) /* - * BufferBackgroundWriter - * - * Periodically flushes dirty blocks from the buffer pool to keep - * the LRU list clean, preventing regular backends from writing. - */ -void -BufferBackgroundWriter(void) -{ - if (BgWriterPercent == 0) - return; - - /* - * Loop forever - */ - for (;;) - { - int n; - long udelay; - - /* - * Call BufferSync() with instructions to keep just the - * LRU heads clean. - */ - n = BufferSync(BgWriterPercent, BgWriterMaxpages); - - /* - * Whatever signal is sent to us, let's just die gallantly. If - * it wasn't meant that way, the postmaster will reincarnate us. - */ - if (InterruptPending) - return; - - /* - * Whenever we have nothing to do, close all smgr files. This - * is so we won't hang onto smgr references to deleted files - * indefinitely. XXX this is a bogus, temporary solution. 'Twould - * be much better to do this once per checkpoint, but the bgwriter - * doesn't yet know anything about checkpoints. - */ - if (n == 0) - smgrcloseall(); - - /* - * Nap for the configured time or sleep for 10 seconds if - * there was nothing to do at all. - * - * On some platforms, signals won't interrupt the sleep. To ensure - * we respond reasonably promptly when the postmaster signals us, - * break down the sleep into 1-second increments, and check for - * interrupts after each nap. - */ - udelay = ((n > 0) ? BgWriterDelay : 10000) * 1000L; - while (udelay > 1000000L) - { - pg_usleep(1000000L); - udelay -= 1000000L; - if (InterruptPending) - return; - } - pg_usleep(udelay); - if (InterruptPending) - return; - } -} - -/* * Do whatever is needed to prepare for commit at the bufmgr and smgr levels */ void diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 4ce5c98b577..69c460306b4 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.67 2004/05/28 05:13:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.68 2004/05/29 22:48:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "miscadmin.h" #include "access/clog.h" #include "access/xlog.h" +#include "postmaster/bgwriter.h" #include "storage/bufmgr.h" #include "storage/freespace.h" #include "storage/ipc.h" @@ -72,6 +73,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, size += LWLockShmemSize(); size += SInvalShmemSize(maxBackends); size += FreeSpaceShmemSize(); + size += BgWriterShmemSize(); #ifdef EXEC_BACKEND size += ShmemBackendArraySize(); #endif @@ -155,9 +157,10 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, InitFreeSpaceMap(); /* - * Set up child-to-postmaster signaling mechanism + * Set up interprocess signaling mechanisms */ PMSignalInit(); + BgWriterShmemInit(); #ifdef EXEC_BACKEND /* diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index b0fc1aea0ff..4efa4adac6f 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.13 2004/02/08 22:28:56 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.14 2004/05/29 22:48:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -83,3 +83,41 @@ CheckPostmasterSignal(PMSignalReason reason) } return false; } + +/* + * PostmasterIsAlive - check whether postmaster process is still alive + * + * amDirectChild should be passed as "true" by code that knows it is + * executing in a direct child process of the postmaster; pass "false" + * if an indirect child or not sure. The "true" case uses a faster and + * more reliable test, so use it when possible. + */ +bool +PostmasterIsAlive(bool amDirectChild) +{ +#ifndef WIN32 + if (amDirectChild) + { + /* + * If the postmaster is alive, we'll still be its child. If it's + * died, we'll be reassigned as a child of the init process. + */ + return (getppid() == PostmasterPid); + } + else + { + /* + * Use kill() to see if the postmaster is still alive. This can + * sometimes give a false positive result, since the postmaster's PID + * may get recycled, but it is good enough for existing uses by + * indirect children. + */ + return (kill(PostmasterPid, 0) == 0); + } +#else /* WIN32 */ + /* + * XXX needs to be implemented by somebody + */ + return true; +#endif /* WIN32 */ +} diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 19ce44ff687..dbf5b414153 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.147 2004/02/18 16:25:12 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.148 2004/05/29 22:48:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -68,10 +68,9 @@ PGPROC *MyProc = NULL; */ NON_EXEC_STATIC slock_t *ProcStructLock = NULL; +/* Pointers to shared-memory structures */ static PROC_HDR *ProcGlobal = NULL; - -static PGPROC *DummyProc = NULL; -static int dummy_proc_type = -1; +static PGPROC *DummyProcs = NULL; static bool waitingForLock = false; static bool waitingForSignal = false; @@ -130,17 +129,16 @@ InitProcGlobal(int maxBackends) /* * Create or attach to the PGPROC structures for dummy (checkpoint) - * processes, too. This does not get linked into the freeProcs - * list. + * processes, too. These do not get linked into the freeProcs list. */ - DummyProc = (PGPROC *) - ShmemInitStruct("DummyProc",sizeof(PGPROC) * NUM_DUMMY_PROCS, &foundDummy); + DummyProcs = (PGPROC *) + ShmemInitStruct("DummyProcs", sizeof(PGPROC) * NUM_DUMMY_PROCS, + &foundDummy); if (foundProcGlobal || foundDummy) { /* both should be present or neither */ Assert(foundProcGlobal && foundDummy); - return; } else { @@ -170,11 +168,11 @@ InitProcGlobal(int maxBackends) ProcGlobal->freeProcs = MAKE_OFFSET(proc); } - MemSet(DummyProc, 0, sizeof(PGPROC) * NUM_DUMMY_PROCS); + MemSet(DummyProcs, 0, sizeof(PGPROC) * NUM_DUMMY_PROCS); for (i = 0; i < NUM_DUMMY_PROCS; i++) { - DummyProc[i].pid = 0; /* marks DummyProc as not in use */ - PGSemaphoreCreate(&(DummyProc[i].sem)); + DummyProcs[i].pid = 0; /* marks dummy proc as not in use */ + PGSemaphoreCreate(&(DummyProcs[i].sem)); } /* Create ProcStructLock spinlock, too */ @@ -249,7 +247,6 @@ InitProcess(void) MyProc->waitHolder = NULL; SHMQueueInit(&(MyProc->procHolders)); - /* * Arrange to clean up at backend exit. */ @@ -274,6 +271,9 @@ InitProcess(void) * This is called by checkpoint processes so that they will have a MyProc * value that's real enough to let them wait for LWLocks. The PGPROC and * sema that are assigned are the extra ones created during InitProcGlobal. + * + * Dummy processes are presently not expected to wait for real (lockmgr) + * locks, nor to participate in sinval messaging. */ void InitDummyProcess(int proctype) @@ -284,29 +284,29 @@ InitDummyProcess(int proctype) * ProcGlobal should be set by a previous call to InitProcGlobal (we * inherit this by fork() from the postmaster). */ - if (ProcGlobal == NULL || DummyProc == NULL) + if (ProcGlobal == NULL || DummyProcs == NULL) elog(PANIC, "proc header uninitialized"); if (MyProc != NULL) elog(ERROR, "you already exist"); - Assert(dummy_proc_type < 0); - dummy_proc_type = proctype; - dummyproc = &DummyProc[proctype]; + Assert(proctype >= 0 && proctype < NUM_DUMMY_PROCS); + + dummyproc = &DummyProcs[proctype]; /* * dummyproc should not presently be in use by anyone else */ if (dummyproc->pid != 0) elog(FATAL, "DummyProc[%d] is in use by PID %d", - proctype, dummyproc->pid); + proctype, dummyproc->pid); MyProc = dummyproc; /* * Initialize all fields of MyProc, except MyProc->sem which was set * up by InitProcGlobal. */ - MyProc->pid = MyProcPid; /* marks DummyProc as in use by me */ + MyProc->pid = MyProcPid; /* marks dummy proc as in use by me */ SHMQueueElemInit(&(MyProc->links)); MyProc->errType = STATUS_OK; MyProc->xid = InvalidTransactionId; @@ -323,7 +323,7 @@ InitDummyProcess(int proctype) /* * Arrange to clean up at process exit. */ - on_shmem_exit(DummyProcKill, proctype); + on_shmem_exit(DummyProcKill, Int32GetDatum(proctype)); /* * We might be reusing a semaphore that belonged to a failed process. @@ -459,13 +459,14 @@ ProcKill(int code, Datum arg) static void DummyProcKill(int code, Datum arg) { + int proctype = DatumGetInt32(arg); PGPROC *dummyproc; - Assert(dummy_proc_type >= 0 && dummy_proc_type < NUM_DUMMY_PROCS); + Assert(proctype >= 0 && proctype < NUM_DUMMY_PROCS); - dummyproc = &DummyProc[dummy_proc_type]; + dummyproc = &DummyProcs[proctype]; - Assert(MyProc != NULL && MyProc == dummyproc); + Assert(MyProc == dummyproc); /* Release any LW locks I am holding */ LWLockReleaseAll(); @@ -477,13 +478,11 @@ DummyProcKill(int code, Datum arg) /* I can't be on regular lock queues, so needn't check */ - /* Mark DummyProc no longer in use */ + /* Mark dummy proc no longer in use */ MyProc->pid = 0; /* PGPROC struct isn't mine anymore */ MyProc = NULL; - - dummy_proc_type = -1; } |