*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.106 2001/01/07 22:14:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.107 2001/01/12 21:53:54 tgl Exp $
*
*
* INTERFACE ROUTINES
buffer = RelationGetBufferForTuple(relation, tup->t_len);
/* NO ELOG(ERROR) from here till changes are logged */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
RelationPutHeapTuple(relation, buffer, tup);
/* XLOG stuff */
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
WriteBuffer(buffer);
return result;
}
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/* store transaction information of xact deleting the tuple */
TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
tp.t_data->t_cmax = GetCurrentCommandId();
PageSetLSN(dp, recptr);
PageSetSUI(dp, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
#ifdef TUPLE_TOASTER_ACTIVE
/* ----------
}
/* NO ELOG(ERROR) from here till changes are logged */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
RelationPutHeapTuple(relation, newbuf, newtup); /* insert new tuple */
if (buffer == newbuf)
PageSetLSN(BufferGetPage(buffer), recptr);
PageSetSUI(BufferGetPage(buffer), ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
if (newbuf != buffer)
LockBuffer(newbuf, BUFFER_LOCK_UNLOCK);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.72 2000/12/29 20:47:16 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.73 2001/01/12 21:53:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
else
{
- START_CRIT_CODE;
+ START_CRIT_SECTION();
_bt_pgaddtup(rel, page, itemsz, btitem, newitemoff, "page");
itup_off = newitemoff;
itup_blkno = BufferGetBlockNumber(buf);
PageSetSUI(page, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
/* Write out the updated page and release pin/lock */
_bt_wrtbuf(rel, buf);
}
* NO ELOG(ERROR) till right sibling is updated.
*
*/
- START_CRIT_CODE;
+ START_CRIT_SECTION();
{
xl_btree_split xlrec;
int flag = (newitemonleft) ?
/* write and release the old right sibling */
if (!P_RIGHTMOST(ropaque))
_bt_wrtbuf(rel, sbuf);
- END_CRIT_CODE;
+ END_CRIT_SECTION();
/* split's done */
return rbuf;
metad = BTPageGetMeta(metapg);
/* NO ELOG(ERROR) from here till newroot op is logged */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/* set btree special data */
rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage);
PageSetSUI(metapg, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
/* write and let go of the new root buffer */
_bt_wrtbuf(rel, rootbuf);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.45 2000/12/29 20:47:17 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.46 2001/01/12 21:53:55 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
rootpage = BufferGetPage(rootbuf);
/* NO ELOG(ERROR) till meta is updated */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
metad->btm_root = rootblkno;
metad->btm_level = 1;
PageSetSUI(metapg, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
_bt_wrtnorelbuf(rel, rootbuf);
buf = _bt_getbuf(rel, blkno, BT_WRITE);
page = BufferGetPage(buf);
- START_CRIT_CODE;
+ START_CRIT_SECTION();
PageIndexTupleDelete(page, offno);
/* XLOG stuff */
{
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
/* write the buffer and release the lock */
_bt_wrtbuf(rel, buf);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.91 2000/12/28 13:00:08 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.92 2001/01/12 21:53:56 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
rdata.len = SizeOfXactCommit;
rdata.next = NULL;
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/*
* SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
*/
TransactionIdCommit(xid);
MyProc->logRec.xrecoff = 0;
- END_CRIT_CODE;
+ END_CRIT_SECTION();
}
if (leak)
rdata.len = SizeOfXactAbort;
rdata.next = NULL;
- START_CRIT_CODE;
+ START_CRIT_SECTION();
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, &rdata);
TransactionIdAbort(xid);
MyProc->logRec.xrecoff = 0;
- END_CRIT_CODE;
+ END_CRIT_SECTION();
}
/*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.48 2001/01/09 06:24:32 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.49 2001/01/12 21:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int XLOGbuffers = 8;
int XLOGfiles = 0; /* how many files to pre-allocate */
XLogRecPtr MyLastRecPtr = {0, 0};
-uint32 CritSectionCount = 0;
+volatile uint32 CritSectionCount = 0;
bool InRecovery = false;
StartUpID ThisStartUpID = 0;
XLogRecPtr RedoRecPtr;
if (len == 0 || len > MAXLOGRECSZ)
elog(STOP, "XLogInsert: invalid record len %u", len);
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/* obtain xlog insert lock */
if (TAS(&(XLogCtl->insert_lck))) /* busy */
if (repeat)
{
S_UNLOCK(&(XLogCtl->insert_lck));
- END_CRIT_CODE;
+ END_CRIT_SECTION();
goto begin;
}
S_UNLOCK(&(XLogCtl->info_lck));
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return (RecPtr);
}
if (XLByteLE(record, LgwrResult.Flush))
return;
- START_CRIT_CODE;
+ START_CRIT_SECTION();
WriteRqst = LgwrRqst.Write;
for (;;)
if (XLByteLE(record, LgwrResult.Flush))
{
S_UNLOCK(&(XLogCtl->info_lck));
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return;
}
if (XLByteLT(XLogCtl->LgwrRqst.Flush, record))
if (XLByteLE(record, LgwrResult.Flush))
{
S_UNLOCK(&(XLogCtl->lgwr_lck));
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return;
}
if (XLByteLT(LgwrResult.Write, WriteRqst))
S_UNLOCK(&(XLogCtl->lgwr_lck));
if (XLByteLT(LgwrResult.Flush, record))
elog(STOP, "XLogFlush: request is not satisfied");
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return;
}
break;
S_UNLOCK(&(XLogCtl->lgwr_lck));
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return;
}
if (MyLastRecPtr.xrecoff != 0)
elog(ERROR, "CreateCheckPoint: cannot be called inside transaction block");
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/* Grab lock, using larger than normal sleep between tries (1 sec) */
while (TAS(&(XLogCtl->chkp_lck)))
S_UNLOCK(&(XLogCtl->chkp_lck));
MyLastRecPtr.xrecoff = 0; /* to avoid commit record */
- END_CRIT_CODE;
+ END_CRIT_SECTION();
return;
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.47 2000/12/28 13:00:17 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.48 2001/01/12 21:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
elm->last = result; /* last returned number */
elm->cached = last; /* last fetched number */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
if (logit)
{
xl_seq_rec xlrec;
seq->is_called = 't';
Assert(log >= 0);
seq->log_cnt = log; /* how much is logged */
- END_CRIT_CODE;
+ END_CRIT_SECTION();
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
elm->last = next; /* last returned number */
elm->cached = next; /* last cached number (forget cached values) */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
seq->last_value = next; /* last fetched number */
seq->is_called = iscalled ? 't' : 'f';
seq->log_cnt = (iscalled) ? 0 : 1;
- END_CRIT_CODE;
+ END_CRIT_SECTION();
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.181 2000/12/30 15:19:55 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.182 2001/01/12 21:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Cpage = BufferGetPage(Cbuf);
/* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
Citemid = PageGetItemId(Cpage,
ItemPointerGetOffsetNumber(&(tuple.t_self)));
PageSetLSN(ToPage, recptr);
PageSetSUI(ToPage, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
if (((int) destvacpage->blkno) > last_move_dest_block)
last_move_dest_block = destvacpage->blkno;
newtup.t_data->t_infomask |= HEAP_MOVED_IN;
/* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
- START_CRIT_CODE;
+ START_CRIT_SECTION();
/* add tuple to the page */
newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len,
PageSetLSN(ToPage, recptr);
PageSetSUI(ToPage, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
cur_page->offsets_used++;
num_moved++;
buf = ReadBuffer(onerel, vacpage->blkno);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
- START_CRIT_CODE;
+ START_CRIT_SECTION();
page = BufferGetPage(buf);
num_tuples = 0;
for (offnum = FirstOffsetNumber;
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
WriteBuffer(buf);
}
/* There shouldn't be any tuples moved onto the page yet! */
Assert(vacpage->offsets_used == 0);
- START_CRIT_CODE;
+ START_CRIT_SECTION();
for (i = 0; i < vacpage->offsets_free; i++)
{
itemid = &(((PageHeader) page)->pd_linp[vacpage->offsets[i] - 1]);
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
- END_CRIT_CODE;
+ END_CRIT_SECTION();
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.102 2001/01/08 18:31:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.103 2001/01/12 21:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
if ((buf->flags & BM_IO_ERROR) != 0)
{
- PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
- buf->refcount--;
+ UnpinBuffer(buf);
buf = (BufferDesc *) NULL;
continue;
}
while ((buf->flags & BM_IO_IN_PROGRESS) != 0)
{
SpinRelease(spinlock);
+ START_CRIT_SECTION(); /* don't want to die() holding the lock... */
S_LOCK(&(buf->io_in_progress_lock));
S_UNLOCK(&(buf->io_in_progress_lock));
+ END_CRIT_SECTION();
SpinAcquire(spinlock);
}
}
* ResetBufferPool
*
* This routine is supposed to be called when a transaction aborts.
- * it will release all the buffer pins held by the transaction.
+ * It will release all the buffer pins held by the transaction.
* Currently, we also call it during commit if BufferPoolCheckLeak
* detected a problem --- in that case, isCommit is TRUE, and we
* only clean up buffer pin counts.
*
- * During abort, we also forget any pending fsync requests. Dirtied buffers
- * will still get written, eventually, but there will be no fsync for them.
- *
* ----------------------------------------------
*/
void
BufferDesc *buf = &BufferDescriptors[i];
SpinAcquire(BufMgrLock);
+ PrivateRefCount[i] = 0;
Assert(buf->refcount > 0);
buf->refcount--;
if (buf->refcount == 0)
}
SpinRelease(BufMgrLock);
}
- PrivateRefCount[i] = 0;
}
ResetLocalBufferPool();
}
void
-UnlockBuffers()
+UnlockBuffers(void)
{
BufferDesc *buf;
int i;
Assert(BufferIsValid(i + 1));
buf = &(BufferDescriptors[i]);
+ START_CRIT_SECTION(); /* don't want to die() holding the lock... */
+
S_LOCK(&(buf->cntx_lock));
if (BufferLocks[i] & BL_R_LOCK)
S_UNLOCK(&(buf->cntx_lock));
BufferLocks[i] = 0;
+
+ END_CRIT_SECTION();
}
}
buf = &(BufferDescriptors[buffer - 1]);
buflock = &(BufferLocks[buffer - 1]);
+ START_CRIT_SECTION(); /* don't want to die() holding the lock... */
+
S_LOCK(&(buf->cntx_lock));
if (mode == BUFFER_LOCK_UNLOCK)
else
{
S_UNLOCK(&(buf->cntx_lock));
+ END_CRIT_SECTION();
elog(ERROR, "UNLockBuffer: buffer %lu is not locked", buffer);
}
}
while (buf->ri_lock || buf->w_lock)
{
S_UNLOCK(&(buf->cntx_lock));
+ END_CRIT_SECTION();
S_LOCK_SLEEP(&(buf->cntx_lock), i++);
+ START_CRIT_SECTION();
S_LOCK(&(buf->cntx_lock));
}
(buf->r_locks)++;
buf->ri_lock = true;
}
S_UNLOCK(&(buf->cntx_lock));
+ END_CRIT_SECTION();
S_LOCK_SLEEP(&(buf->cntx_lock), i++);
+ START_CRIT_SECTION();
S_LOCK(&(buf->cntx_lock));
}
buf->w_lock = true;
else
{
S_UNLOCK(&(buf->cntx_lock));
+ END_CRIT_SECTION();
elog(ERROR, "LockBuffer: unknown lock mode %d", mode);
}
S_UNLOCK(&(buf->cntx_lock));
+ END_CRIT_SECTION();
}
/*
* BM_IO_IN_PROGRESS mask is not set for the buffer
* The buffer is Pinned
*
-*/
+ * Because BufMgrLock is held, we are already in a CRIT_SECTION here,
+ * and do not need another.
+ */
static void
StartBufferIO(BufferDesc *buf, bool forInput)
{
* BufMgrLock is held
* The buffer is Pinned
*
-*/
+ * Because BufMgrLock is held, we are already in a CRIT_SECTION here,
+ * and do not need another.
+ */
static void
TerminateBufferIO(BufferDesc *buf)
{
* BufMgrLock is held
* The buffer is Pinned
*
-*/
+ * Because BufMgrLock is held, we are already in a CRIT_SECTION here,
+ * and do not need another.
+ */
static void
ContinueBufferIO(BufferDesc *buf, bool forInput)
{
* This function is called from ProcReleaseSpins().
* BufMgrLock isn't held when this function is called.
*
- * If I/O was in progress, BM_IO_ERROR is always set.
+ * If I/O was in progress, we always set BM_IO_ERROR.
*/
void
AbortBufferIO(void)
if (buf)
{
- Assert(buf->flags & BM_IO_IN_PROGRESS);
SpinAcquire(BufMgrLock);
+ Assert(buf->flags & BM_IO_IN_PROGRESS);
if (IsForInput)
Assert(!(buf->flags & BM_DIRTY) && !(buf->cntxDirty));
else
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.69 2000/12/08 22:21:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.70 2001/01/12 21:53:58 tgl Exp $
*
* NOTES:
*
* Delete the file if it was temporary
*/
if (VfdCache[file].fdstate & FD_TEMPORARY)
+ {
+ /* reset flag so that die() interrupt won't cause problems */
+ VfdCache[file].fdstate &= ~FD_TEMPORARY;
unlink(VfdCache[file].fileName);
+ }
/*
* Return the Vfd slot to the free list
TryAgain:
if ((file = fopen(name, mode)) != NULL)
{
- allocatedFiles[numAllocatedFiles++] = file;
+ allocatedFiles[numAllocatedFiles] = file;
+ numAllocatedFiles++;
return file;
}
{
if (allocatedFiles[i] == file)
{
- allocatedFiles[i] = allocatedFiles[--numAllocatedFiles];
+ numAllocatedFiles--;
+ allocatedFiles[i] = allocatedFiles[numAllocatedFiles];
break;
}
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.27 2000/12/11 00:49:52 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.28 2001/01/12 21:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
SLock *slckP = &(SLockArray[lockid]);
PRINT_SLDEBUG("SpinAcquire", lockid, slckP);
+ /*
+ * Lock out die() until we exit the critical section protected by the
+ * spinlock. This ensures that die() will not interrupt manipulations
+ * of data structures in shared memory. We don't want die() to
+ * interrupt this routine between S_LOCK and PROC_INCR_SLOCK, either,
+ * so must do it before acquiring the lock, not after.
+ */
+ START_CRIT_SECTION();
+ /*
+ * Acquire the lock, then record that we have done so (for recovery
+ * in case of elog(ERROR) during the critical section).
+ */
S_LOCK(&(slckP->shlock));
PROC_INCR_SLOCK(lockid);
+
PRINT_SLDEBUG("SpinAcquire/done", lockid, slckP);
}
{
SLock *slckP = &(SLockArray[lockid]);
+ PRINT_SLDEBUG("SpinRelease", lockid, slckP);
/*
* Check that we are actually holding the lock we are releasing. This
* can be done only after MyProc has been initialized.
*/
Assert(!MyProc || MyProc->sLocks[lockid] > 0);
-
+ /*
+ * Record that we no longer hold the spinlock, and release it.
+ */
PROC_DECR_SLOCK(lockid);
- PRINT_SLDEBUG("SpinRelease", lockid, slckP);
S_UNLOCK(&(slckP->shlock));
+ /*
+ * Exit the critical section entered in SpinAcquire().
+ */
+ END_CRIT_SECTION();
+
PRINT_SLDEBUG("SpinRelease/done", lockid, slckP);
}
*
* Note that the SpinLockIds array is not in shared memory; it is filled
* by the postmaster and then inherited through fork() by backends. This
- * is OK because its contents do not change after system startup.
+ * is OK because its contents do not change after shmem initialization.
*/
#define SPINLOCKS_PER_SET PROC_NSEMS_PER_SET
if (SpinLockIds[i] >= 0)
IpcSemaphoreKill(SpinLockIds[i]);
}
+ free(SpinLockIds);
+ SpinLockIds = NULL;
}
/*
void
SpinAcquire(SPINLOCK lock)
{
+ /* See the TAS() version of this routine for commentary */
+ START_CRIT_SECTION();
IpcSemaphoreLock(SpinLockIds[0], lock);
PROC_INCR_SLOCK(lock);
}
void
SpinRelease(SPINLOCK lock)
{
+ /* See the TAS() version of this routine for commentary */
#ifdef USE_ASSERT_CHECKING
/* Check it's locked */
int semval;
semval = IpcSemaphoreGetValue(SpinLockIds[0], lock);
Assert(semval < 1);
+ Assert(!MyProc || MyProc->sLocks[lockid] > 0);
#endif
PROC_DECR_SLOCK(lock);
IpcSemaphoreUnlock(SpinLockIds[0], lock);
+ END_CRIT_SECTION();
}
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.90 2001/01/09 09:38:57 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.91 2001/01/12 21:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95
*
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.90 2001/01/09 09:38:57 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.91 2001/01/12 21:53:59 tgl Exp $
*/
#include "postgres.h"
MemSet(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
MyProc->sLocks[ProcStructLock] = 1;
-
if (IsUnderPostmaster)
{
IpcSemaphoreId semId;
else
MyProc->sem.semId = -1;
- /* ----------------------
- * Release the lock.
- * ----------------------
- */
- SpinRelease(ProcStructLock);
-
MyProc->pid = MyProcPid;
MyProc->databaseId = MyDatabaseId;
MyProc->xid = InvalidTransactionId;
MyProc->xmin = InvalidTransactionId;
- /* ----------------
- * Start keeping spin lock stats from here on. Any botch before
- * this initialization is forever botched
- * ----------------
+ /* ----------------------
+ * Release the lock.
+ * ----------------------
*/
- MemSet(MyProc->sLocks, 0, MAX_SPINS * sizeof(*MyProc->sLocks));
+ SpinRelease(ProcStructLock);
/* -------------------------
* Install ourselves in the shmem index table. The name to
{
PROC *proc;
- /* --------------------
- * If this is a FATAL exit the postmaster will have to kill all the
- * existing backends and reinitialize shared memory. So we don't
- * need to do anything here.
- * --------------------
- */
- if (exitStatus != 0)
- return;
-
if ((int) pid == MyProcPid)
{
proc = MyProc;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.199 2001/01/07 04:17:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.200 2001/01/12 21:53:59 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
/*
* This is split out of die() so that it can be invoked later from
- * END_CRIT_CODE.
+ * END_CRIT_SECTION().
*/
void
ForceProcDie(void)
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.199 $ $Date: 2001/01/07 04:17:29 $\n");
+ puts("$Revision: 1.200 $ $Date: 2001/01/12 21:53:59 $\n");
}
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.32 2000/12/22 23:12:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.33 2001/01/12 21:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
temp_rel->created_in_cur_xact)
{
/* This entry must be removed */
- pfree(temp_rel);
- /* remove from linked list */
if (prev != NIL)
{
lnext(prev) = lnext(l);
pfree(l);
l = temp_rels;
}
+ pfree(temp_rel);
}
else
{
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.76 2000/12/18 00:44:48 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.77 2001/01/12 21:54:00 tgl Exp $
*
*
*-------------------------------------------------------------------------
* We don't want to do any inessential cleanup, since that just raises
* the odds of failure --- but there's some stuff we need to do.
*
- * Release any spinlocks that we may hold. This is a kluge to improve
- * the odds that we won't get into a self-made stuck spinlock scenario
- * while trying to shut down.
+ * Release any spinlocks or buffer context locks we might be holding.
+ * This is a kluge to improve the odds that we won't get into a self-made
+ * stuck-spinlock scenario while trying to shut down.
*/
ProcReleaseSpins(NULL);
+ UnlockBuffers();
/*
* In case a transaction is open, delete any files it created. This
* has to happen before bufmgr shutdown, so having smgr register a
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.36 2001/01/06 21:59:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.37 2001/01/12 21:54:01 tgl Exp $
*
* NOTE:
* This is a new (Feb. 05, 1999) implementation of the allocation set
AllocSetCheck(context);
#endif
+ /* Clear chunk freelists */
+ MemSet(set->freelist, 0, sizeof(set->freelist));
+ /* New blocks list is either empty or just the keeper block */
+ set->blocks = set->keeper;
+
while (block != NULL)
{
AllocBlock next = block->next;
}
block = next;
}
-
- /* Now blocks list is either empty or just the keeper block */
- set->blocks = set->keeper;
- /* Clear chunk freelists in any case */
- MemSet(set->freelist, 0, sizeof(set->freelist));
}
/*
AllocSetCheck(context);
#endif
+ /* Make it look empty, just in case... */
+ MemSet(set->freelist, 0, sizeof(set->freelist));
+ set->blocks = NULL;
+ set->keeper = NULL;
+
while (block != NULL)
{
AllocBlock next = block->next;
free(block);
block = next;
}
-
- /* Make it look empty, just in case... */
- set->blocks = NULL;
- MemSet(set->freelist, 0, sizeof(set->freelist));
- set->keeper = NULL;
}
/*
}
chunk = (AllocChunk) (block->freeptr);
+
+ block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
+ availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
+
chunk->size = availchunk;
#ifdef MEMORY_CONTEXT_CHECKING
chunk->requested_size = 0; /* mark it free */
#endif
chunk->aset = (void *) set->freelist[a_fidx];
set->freelist[a_fidx] = chunk;
-
- block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
- availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
}
/* Mark that we need to create a new block */
* OK, do the allocation
*/
chunk = (AllocChunk) (block->freeptr);
+
+ block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
+ Assert(block->freeptr <= block->endptr);
+
chunk->aset = (void *) set;
chunk->size = chunk_size;
#ifdef MEMORY_CONTEXT_CHECKING
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
#endif
- block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
- Assert(block->freeptr <= block->endptr);
-
AllocAllocInfo(set, chunk);
return AllocChunkGetPointer(chunk);
}
*
* PostgreSQL transaction log manager
*
- * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.15 2000/12/28 13:00:25 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.16 2001/01/12 21:54:01 tgl Exp $
*/
#ifndef XLOG_H
#define XLOG_H
extern StartUpID ThisStartUpID; /* current SUI */
extern bool InRecovery;
extern XLogRecPtr MyLastRecPtr;
-extern uint32 CritSectionCount;
+extern volatile uint32 CritSectionCount;
typedef struct RmgrData
{
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: elog.h,v 1.22 2001/01/07 04:17:28 tgl Exp $
+ * $Id: elog.h,v 1.23 2001/01/12 21:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* ProcDiePending will be honored at critical section exit,
* but QueryCancel is only checked at specified points.
*/
-extern uint32 CritSectionCount; /* duplicates access/xlog.h */
+extern volatile uint32 CritSectionCount; /* duplicates access/xlog.h */
extern volatile bool ProcDiePending;
extern void ForceProcDie(void); /* in postgres.c */
-#define START_CRIT_CODE (CritSectionCount++)
+#define START_CRIT_SECTION() (CritSectionCount++)
-#define END_CRIT_CODE \
+#define END_CRIT_SECTION() \
do { \
- if (CritSectionCount == 0) \
- elog(STOP, "Not in critical section"); \
+ Assert(CritSectionCount > 0); \
CritSectionCount--; \
if (CritSectionCount == 0 && ProcDiePending) \
ForceProcDie(); \