Remove the last vestiges of the MAKE_PTR/MAKE_OFFSET mechanism. We haven't

allowed different processes to have different addresses for the shmem segment
in quite a long time, but there were still a few places left that used the
old coding convention.  Clean them up to reduce confusion and improve the
compiler's ability to detect pointer type mismatches.

Kris Jurka
This commit is contained in:
Tom Lane 2008-11-02 21:24:52 +00:00
parent 902d1cb35f
commit d7112cfa88
10 changed files with 153 additions and 268 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.46 2008/10/20 19:18:18 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.47 2008/11/02 21:24:51 tgl Exp $
*
* NOTES
* Each global transaction is associated with a global transaction
@ -122,7 +122,7 @@ typedef struct GlobalTransactionData
typedef struct TwoPhaseStateData
{
/* Head of linked list of free GlobalTransactionData structs */
SHMEM_OFFSET freeGXacts;
GlobalTransaction freeGXacts;
/* Number of valid prepXacts entries. */
int numPrepXacts;
@ -184,7 +184,7 @@ TwoPhaseShmemInit(void)
int i;
Assert(!found);
TwoPhaseState->freeGXacts = INVALID_OFFSET;
TwoPhaseState->freeGXacts = NULL;
TwoPhaseState->numPrepXacts = 0;
/*
@ -196,8 +196,8 @@ TwoPhaseShmemInit(void)
sizeof(GlobalTransaction) * max_prepared_xacts));
for (i = 0; i < max_prepared_xacts; i++)
{
gxacts[i].proc.links.next = TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = MAKE_OFFSET(&gxacts[i]);
gxacts[i].proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = &gxacts[i];
}
}
else
@ -242,8 +242,8 @@ MarkAsPreparing(TransactionId xid, const char *gid,
TwoPhaseState->numPrepXacts--;
TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
gxact->proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = gxact;
/* Back up index count too, so we don't miss scanning one */
i--;
}
@ -263,14 +263,14 @@ MarkAsPreparing(TransactionId xid, const char *gid,
}
/* Get a free gxact from the freelist */
if (TwoPhaseState->freeGXacts == INVALID_OFFSET)
if (TwoPhaseState->freeGXacts == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("maximum number of prepared transactions reached"),
errhint("Increase max_prepared_transactions (currently %d).",
max_prepared_xacts)));
gxact = (GlobalTransaction) MAKE_PTR(TwoPhaseState->freeGXacts);
TwoPhaseState->freeGXacts = gxact->proc.links.next;
gxact = TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = (GlobalTransaction) gxact->proc.links.next;
/* Initialize it */
MemSet(&gxact->proc, 0, sizeof(PGPROC));
@ -451,8 +451,8 @@ RemoveGXact(GlobalTransaction gxact)
TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
gxact->proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = gxact;
LWLockRelease(TwoPhaseStateLock);

View File

@ -55,7 +55,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.84 2008/08/13 00:07:50 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.85 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -244,9 +244,9 @@ typedef struct
{
sig_atomic_t av_signal[AutoVacNumSignals];
pid_t av_launcherpid;
SHMEM_OFFSET av_freeWorkers;
WorkerInfo av_freeWorkers;
SHM_QUEUE av_runningWorkers;
SHMEM_OFFSET av_startingWorker;
WorkerInfo av_startingWorker;
} AutoVacuumShmemStruct;
static AutoVacuumShmemStruct *AutoVacuumShmem;
@ -556,8 +556,8 @@ AutoVacLauncherMain(int argc, char *argv[])
if (!PostmasterIsAlive(true))
exit(1);
launcher_determine_sleep(AutoVacuumShmem->av_freeWorkers !=
INVALID_OFFSET, false, &nap);
launcher_determine_sleep((AutoVacuumShmem->av_freeWorkers != NULL),
false, &nap);
/*
* Sleep for a while according to schedule.
@ -662,13 +662,12 @@ AutoVacLauncherMain(int argc, char *argv[])
current_time = GetCurrentTimestamp();
LWLockAcquire(AutovacuumLock, LW_SHARED);
can_launch = (AutoVacuumShmem->av_freeWorkers != INVALID_OFFSET);
can_launch = (AutoVacuumShmem->av_freeWorkers != NULL);
if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
if (AutoVacuumShmem->av_startingWorker != NULL)
{
int waittime;
WorkerInfo worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
WorkerInfo worker = AutoVacuumShmem->av_startingWorker;
/*
* We can't launch another worker when another one is still
@ -698,16 +697,16 @@ AutoVacLauncherMain(int argc, char *argv[])
* we assume it's the same one we saw above (so we don't
* recheck the launch time).
*/
if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
if (AutoVacuumShmem->av_startingWorker != NULL)
{
worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
worker = AutoVacuumShmem->av_startingWorker;
worker->wi_dboid = InvalidOid;
worker->wi_tableoid = InvalidOid;
worker->wi_proc = NULL;
worker->wi_launchtime = 0;
worker->wi_links.next = AutoVacuumShmem->av_freeWorkers;
AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(worker);
AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
worker->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
AutoVacuumShmem->av_freeWorkers = worker;
AutoVacuumShmem->av_startingWorker = NULL;
elog(WARNING, "worker took too long to start; cancelled");
}
}
@ -1061,7 +1060,7 @@ do_start_worker(void)
/* return quickly when there are no free workers */
LWLockAcquire(AutovacuumLock, LW_SHARED);
if (AutoVacuumShmem->av_freeWorkers == INVALID_OFFSET)
if (AutoVacuumShmem->av_freeWorkers == NULL)
{
LWLockRelease(AutovacuumLock);
return InvalidOid;
@ -1192,7 +1191,6 @@ do_start_worker(void)
if (avdb != NULL)
{
WorkerInfo worker;
SHMEM_OFFSET sworker;
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
@ -1201,18 +1199,17 @@ do_start_worker(void)
* really should be a free slot -- complain very loudly if there
* isn't.
*/
sworker = AutoVacuumShmem->av_freeWorkers;
if (sworker == INVALID_OFFSET)
worker = AutoVacuumShmem->av_freeWorkers;
if (worker == NULL)
elog(FATAL, "no free worker found");
worker = (WorkerInfo) MAKE_PTR(sworker);
AutoVacuumShmem->av_freeWorkers = worker->wi_links.next;
AutoVacuumShmem->av_freeWorkers = (WorkerInfo) worker->wi_links.next;
worker->wi_dboid = avdb->adw_datid;
worker->wi_proc = NULL;
worker->wi_launchtime = GetCurrentTimestamp();
AutoVacuumShmem->av_startingWorker = sworker;
AutoVacuumShmem->av_startingWorker = worker;
LWLockRelease(AutovacuumLock);
@ -1549,9 +1546,9 @@ AutoVacWorkerMain(int argc, char *argv[])
* launcher might have decided to remove it from the queue and start
* again.
*/
if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
if (AutoVacuumShmem->av_startingWorker != NULL)
{
MyWorkerInfo = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
MyWorkerInfo = AutoVacuumShmem->av_startingWorker;
dbid = MyWorkerInfo->wi_dboid;
MyWorkerInfo->wi_proc = MyProc;
@ -1563,7 +1560,7 @@ AutoVacWorkerMain(int argc, char *argv[])
* remove from the "starting" pointer, so that the launcher can start
* a new worker if required
*/
AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
AutoVacuumShmem->av_startingWorker = NULL;
LWLockRelease(AutovacuumLock);
on_shmem_exit(FreeWorkerInfo, 0);
@ -1648,7 +1645,7 @@ FreeWorkerInfo(int code, Datum arg)
AutovacuumLauncherPid = AutoVacuumShmem->av_launcherpid;
SHMQueueDelete(&MyWorkerInfo->wi_links);
MyWorkerInfo->wi_links.next = AutoVacuumShmem->av_freeWorkers;
MyWorkerInfo->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
MyWorkerInfo->wi_dboid = InvalidOid;
MyWorkerInfo->wi_tableoid = InvalidOid;
MyWorkerInfo->wi_proc = NULL;
@ -1656,7 +1653,7 @@ FreeWorkerInfo(int code, Datum arg)
MyWorkerInfo->wi_cost_delay = 0;
MyWorkerInfo->wi_cost_limit = 0;
MyWorkerInfo->wi_cost_limit_base = 0;
AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(MyWorkerInfo);
AutoVacuumShmem->av_freeWorkers = MyWorkerInfo;
/* not mine anymore */
MyWorkerInfo = NULL;
@ -2793,9 +2790,9 @@ AutoVacuumShmemInit(void)
Assert(!found);
AutoVacuumShmem->av_launcherpid = 0;
AutoVacuumShmem->av_freeWorkers = INVALID_OFFSET;
AutoVacuumShmem->av_freeWorkers = NULL;
SHMQueueInit(&AutoVacuumShmem->av_runningWorkers);
AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
AutoVacuumShmem->av_startingWorker = NULL;
worker = (WorkerInfo) ((char *) AutoVacuumShmem +
MAXALIGN(sizeof(AutoVacuumShmemStruct)));
@ -2803,8 +2800,8 @@ AutoVacuumShmemInit(void)
/* initialize the WorkerInfo free list */
for (i = 0; i < autovacuum_max_workers; i++)
{
worker[i].wi_links.next = AutoVacuumShmem->av_freeWorkers;
AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(&worker[i]);
worker[i].wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
AutoVacuumShmem->av_freeWorkers = &worker[i];
}
}
else

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.100 2008/01/01 19:45:51 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.101 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -77,9 +77,9 @@
static PGShmemHeader *ShmemSegHdr; /* shared mem segment header */
SHMEM_OFFSET ShmemBase; /* start address of shared memory */
static void *ShmemBase; /* start address of shared memory */
static SHMEM_OFFSET ShmemEnd; /* end+1 address of shared memory */
static void *ShmemEnd; /* end+1 address of shared memory */
slock_t *ShmemLock; /* spinlock for shared memory and LWLock
* allocation */
@ -99,8 +99,8 @@ InitShmemAccess(void *seghdr)
PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr;
ShmemSegHdr = shmhdr;
ShmemBase = (SHMEM_OFFSET) shmhdr;
ShmemEnd = ShmemBase + shmhdr->totalsize;
ShmemBase = (void *) shmhdr;
ShmemEnd = (char *) ShmemBase + shmhdr->totalsize;
}
/*
@ -127,7 +127,7 @@ InitShmemAllocation(void)
SpinLockInit(ShmemLock);
/* ShmemIndex can't be set up yet (need LWLocks first) */
shmhdr->indexoffset = 0;
shmhdr->index = NULL;
ShmemIndex = (HTAB *) NULL;
/*
@ -176,7 +176,7 @@ ShmemAlloc(Size size)
newFree = newStart + size;
if (newFree <= shmemseghdr->totalsize)
{
newSpace = (void *) MAKE_PTR(newStart);
newSpace = (void *) ((char *) ShmemBase + newStart);
shmemseghdr->freeoffset = newFree;
}
else
@ -193,14 +193,14 @@ ShmemAlloc(Size size)
}
/*
* ShmemIsValid -- test if an offset refers to valid shared memory
* ShmemAddrIsValid -- test if an address refers to shared memory
*
* Returns TRUE if the pointer is valid.
* Returns TRUE if the pointer points within the shared memory segment.
*/
bool
ShmemIsValid(unsigned long addr)
ShmemAddrIsValid(void *addr)
{
return (addr < ShmemEnd) && (addr >= ShmemBase);
return (addr >= ShmemBase) && (addr < ShmemEnd);
}
/*
@ -324,8 +324,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
if (IsUnderPostmaster)
{
/* Must be initializing a (non-standalone) backend */
Assert(shmemseghdr->indexoffset != 0);
structPtr = (void *) MAKE_PTR(shmemseghdr->indexoffset);
Assert(shmemseghdr->index != NULL);
structPtr = shmemseghdr->index;
*foundPtr = TRUE;
}
else
@ -338,9 +338,9 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
* index has been initialized. This should be OK because no other
* process can be accessing shared memory yet.
*/
Assert(shmemseghdr->indexoffset == 0);
Assert(shmemseghdr->index == NULL);
structPtr = ShmemAlloc(size);
shmemseghdr->indexoffset = MAKE_OFFSET(structPtr);
shmemseghdr->index = structPtr;
*foundPtr = FALSE;
}
LWLockRelease(ShmemIndexLock);
@ -374,7 +374,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
/* let caller print its message too */
return NULL;
}
structPtr = (void *) MAKE_PTR(result->location);
structPtr = result->location;
}
else
{
@ -395,9 +395,9 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
return NULL;
}
result->size = size;
result->location = MAKE_OFFSET(structPtr);
result->location = structPtr;
}
Assert(ShmemIsValid((unsigned long) structPtr));
Assert(ShmemAddrIsValid(structPtr));
LWLockRelease(ShmemIndexLock);
return structPtr;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmqueue.c,v 1.31 2008/01/01 19:45:51 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmqueue.c,v 1.32 2008/11/02 21:24:52 tgl Exp $
*
* NOTES
*
@ -27,12 +27,6 @@
#include "storage/shmem.h"
/*#define SHMQUEUE_DEBUG*/
#ifdef SHMQUEUE_DEBUG
static void dumpQ(SHM_QUEUE *q, char *s);
#endif
/*
* ShmemQueueInit -- make the head of a new queue point
@ -41,8 +35,8 @@ static void dumpQ(SHM_QUEUE *q, char *s);
void
SHMQueueInit(SHM_QUEUE *queue)
{
Assert(SHM_PTR_VALID(queue));
(queue)->prev = (queue)->next = MAKE_OFFSET(queue);
Assert(ShmemAddrIsValid(queue));
queue->prev = queue->next = queue;
}
/*
@ -53,8 +47,8 @@ SHMQueueInit(SHM_QUEUE *queue)
bool
SHMQueueIsDetached(SHM_QUEUE *queue)
{
Assert(SHM_PTR_VALID(queue));
return (queue)->prev == INVALID_OFFSET;
Assert(ShmemAddrIsValid(queue));
return (queue->prev == NULL);
}
#endif
@ -64,8 +58,8 @@ SHMQueueIsDetached(SHM_QUEUE *queue)
void
SHMQueueElemInit(SHM_QUEUE *queue)
{
Assert(SHM_PTR_VALID(queue));
(queue)->prev = (queue)->next = INVALID_OFFSET;
Assert(ShmemAddrIsValid(queue));
queue->prev = queue->next = NULL;
}
/*
@ -75,21 +69,17 @@ SHMQueueElemInit(SHM_QUEUE *queue)
void
SHMQueueDelete(SHM_QUEUE *queue)
{
SHM_QUEUE *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
SHM_QUEUE *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
SHM_QUEUE *nextElem = queue->next;
SHM_QUEUE *prevElem = queue->prev;
Assert(SHM_PTR_VALID(queue));
Assert(SHM_PTR_VALID(nextElem));
Assert(SHM_PTR_VALID(prevElem));
Assert(ShmemAddrIsValid(queue));
Assert(ShmemAddrIsValid(nextElem));
Assert(ShmemAddrIsValid(prevElem));
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueDelete: begin");
#endif
prevElem->next = queue->next;
nextElem->prev = queue->prev;
prevElem->next = (queue)->next;
nextElem->prev = (queue)->prev;
(queue)->prev = (queue)->next = INVALID_OFFSET;
queue->prev = queue->next = NULL;
}
/*
@ -100,24 +90,15 @@ SHMQueueDelete(SHM_QUEUE *queue)
void
SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
{
SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
SHM_QUEUE *prevPtr = queue->prev;
Assert(SHM_PTR_VALID(queue));
Assert(SHM_PTR_VALID(elem));
Assert(ShmemAddrIsValid(queue));
Assert(ShmemAddrIsValid(elem));
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertBefore: begin");
#endif
(elem)->next = prevPtr->next;
(elem)->prev = queue->prev;
(queue)->prev = elemOffset;
prevPtr->next = elemOffset;
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertBefore: end");
#endif
elem->next = prevPtr->next;
elem->prev = queue->prev;
queue->prev = elem;
prevPtr->next = elem;
}
/*
@ -129,24 +110,15 @@ SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
void
SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
{
SHM_QUEUE *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
SHM_QUEUE *nextPtr = queue->next;
Assert(SHM_PTR_VALID(queue));
Assert(SHM_PTR_VALID(elem));
Assert(ShmemAddrIsValid(queue));
Assert(ShmemAddrIsValid(elem));
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertAfter: begin");
#endif
(elem)->prev = nextPtr->prev;
(elem)->next = queue->next;
(queue)->next = elemOffset;
nextPtr->prev = elemOffset;
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertAfter: end");
#endif
elem->prev = nextPtr->prev;
elem->next = queue->next;
queue->next = elem;
nextPtr->prev = elem;
}
#endif /* NOT_USED */
@ -159,15 +131,15 @@ SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
* Next element is at curElem->next. If SHMQueue is part of
* a larger structure, we want to return a pointer to the
* whole structure rather than a pointer to its SHMQueue field.
* I.E. struct {
* For example,
* struct {
* int stuff;
* SHMQueue elem;
* } ELEMType;
* When this element is in a queue, (prevElem->next) is struct.elem.
* When this element is in a queue, prevElem->next points at struct.elem.
* We subtract linkOffset to get the correct start address of the structure.
*
* calls to SHMQueueNext should take these parameters:
*
* &(queueHead), &(queueHead), offsetof(ELEMType, elem)
* or
* &(queueHead), &(curElem->elem), offsetof(ELEMType, elem)
@ -176,9 +148,9 @@ SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
Pointer
SHMQueueNext(SHM_QUEUE *queue, SHM_QUEUE *curElem, Size linkOffset)
{
SHM_QUEUE *elemPtr = (SHM_QUEUE *) MAKE_PTR((curElem)->next);
SHM_QUEUE *elemPtr = curElem->next;
Assert(SHM_PTR_VALID(curElem));
Assert(ShmemAddrIsValid(curElem));
if (elemPtr == queue) /* back to the queue head? */
return NULL;
@ -192,64 +164,12 @@ SHMQueueNext(SHM_QUEUE *queue, SHM_QUEUE *curElem, Size linkOffset)
bool
SHMQueueEmpty(SHM_QUEUE *queue)
{
Assert(SHM_PTR_VALID(queue));
Assert(ShmemAddrIsValid(queue));
if (queue->prev == MAKE_OFFSET(queue))
if (queue->prev == queue)
{
Assert(queue->next = MAKE_OFFSET(queue));
Assert(queue->next == queue);
return TRUE;
}
return FALSE;
}
#ifdef SHMQUEUE_DEBUG
static void
dumpQ(SHM_QUEUE *q, char *s)
{
char elem[NAMEDATALEN];
char buf[1024];
SHM_QUEUE *start = q;
int count = 0;
snprintf(buf, sizeof(buf), "q prevs: %lx", MAKE_OFFSET(q));
q = (SHM_QUEUE *) MAKE_PTR(q->prev);
while (q != start)
{
snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
strcat(buf, elem);
q = (SHM_QUEUE *) MAKE_PTR(q->prev);
if (q->prev == MAKE_OFFSET(q))
break;
if (count++ > 40)
{
strcat(buf, "BAD PREV QUEUE!!");
break;
}
}
snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
strcat(buf, elem);
elog(DEBUG2, "%s: %s", s, buf);
snprintf(buf, sizeof(buf), "q nexts: %lx", MAKE_OFFSET(q));
count = 0;
q = (SHM_QUEUE *) MAKE_PTR(q->next);
while (q != start)
{
snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
strcat(buf, elem);
q = (SHM_QUEUE *) MAKE_PTR(q->next);
if (q->next == MAKE_OFFSET(q))
break;
if (count++ > 10)
{
strcat(buf, "BAD NEXT QUEUE!!");
break;
}
}
snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
strcat(buf, elem);
elog(DEBUG2, "%s: %s", s, buf);
}
#endif /* SHMQUEUE_DEBUG */

View File

@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.54 2008/08/01 13:16:09 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.55 2008/11/02 21:24:52 tgl Exp $
*
* Interface:
*
@ -495,7 +495,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
/*
* If the proc is not waiting, we have no outgoing waits-for edges.
*/
if (checkProc->links.next == INVALID_OFFSET)
if (checkProc->links.next == NULL)
return false;
lock = checkProc->waitLock;
if (lock == NULL)
@ -629,7 +629,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
waitQueue = &(lock->waitProcs);
queue_size = waitQueue->size;
proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
proc = (PGPROC *) waitQueue->links.next;
while (queue_size-- > 0)
{
@ -662,7 +662,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
}
}
proc = (PGPROC *) MAKE_PTR(proc->links.next);
proc = (PGPROC *) proc->links.next;
}
}
@ -772,11 +772,11 @@ TopoSort(LOCK *lock,
last;
/* First, fill topoProcs[] array with the procs in their current order */
proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
proc = (PGPROC *) waitQueue->links.next;
for (i = 0; i < queue_size; i++)
{
topoProcs[i] = proc;
proc = (PGPROC *) MAKE_PTR(proc->links.next);
proc = (PGPROC *) proc->links.next;
}
/*
@ -864,12 +864,12 @@ PrintLockQueue(LOCK *lock, const char *info)
PGPROC *proc;
int i;
printf("%s lock %lx queue ", info, MAKE_OFFSET(lock));
proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
printf("%s lock %p queue ", info, lock);
proc = (PGPROC *) waitQueue->links.next;
for (i = 0; i < queue_size; i++)
{
printf(" %d", proc->pid);
proc = (PGPROC *) MAKE_PTR(proc->links.next);
proc = (PGPROC *) proc->links.next;
}
printf("\n");
fflush(stdout);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.184 2008/08/01 13:16:09 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.185 2008/11/02 21:24:52 tgl Exp $
*
* NOTES
* A lock table is a shared memory hash table. When
@ -1214,7 +1214,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
/* Make sure proc is waiting */
Assert(proc->waitStatus == STATUS_WAITING);
Assert(proc->links.next != INVALID_OFFSET);
Assert(proc->links.next != NULL);
Assert(waitLock);
Assert(waitLock->waitProcs.size > 0);
Assert(0 < lockmethodid && lockmethodid < lengthof(LockMethods));

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.201 2008/06/09 18:23:05 neilc Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.202 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -170,8 +170,8 @@ InitProcGlobal(void)
/*
* Initialize the data structures.
*/
ProcGlobal->freeProcs = INVALID_OFFSET;
ProcGlobal->autovacFreeProcs = INVALID_OFFSET;
ProcGlobal->freeProcs = NULL;
ProcGlobal->autovacFreeProcs = NULL;
ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
@ -187,8 +187,8 @@ InitProcGlobal(void)
for (i = 0; i < MaxConnections; i++)
{
PGSemaphoreCreate(&(procs[i].sem));
procs[i].links.next = ProcGlobal->freeProcs;
ProcGlobal->freeProcs = MAKE_OFFSET(&procs[i]);
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
ProcGlobal->freeProcs = &procs[i];
}
procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers) * sizeof(PGPROC));
@ -200,8 +200,8 @@ InitProcGlobal(void)
for (i = 0; i < autovacuum_max_workers; i++)
{
PGSemaphoreCreate(&(procs[i].sem));
procs[i].links.next = ProcGlobal->autovacFreeProcs;
ProcGlobal->autovacFreeProcs = MAKE_OFFSET(&procs[i]);
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
ProcGlobal->autovacFreeProcs = &procs[i];
}
MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
@ -224,7 +224,6 @@ InitProcess(void)
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
SHMEM_OFFSET myOffset;
int i;
/*
@ -249,17 +248,16 @@ InitProcess(void)
set_spins_per_delay(procglobal->spins_per_delay);
if (IsAutoVacuumWorkerProcess())
myOffset = procglobal->autovacFreeProcs;
MyProc = procglobal->autovacFreeProcs;
else
myOffset = procglobal->freeProcs;
MyProc = procglobal->freeProcs;
if (myOffset != INVALID_OFFSET)
if (MyProc != NULL)
{
MyProc = (PGPROC *) MAKE_PTR(myOffset);
if (IsAutoVacuumWorkerProcess())
procglobal->autovacFreeProcs = MyProc->links.next;
procglobal->autovacFreeProcs = (PGPROC *) MyProc->links.next;
else
procglobal->freeProcs = MyProc->links.next;
procglobal->freeProcs = (PGPROC *) MyProc->links.next;
SpinLockRelease(ProcStructLock);
}
else
@ -461,7 +459,6 @@ InitAuxiliaryProcess(void)
bool
HaveNFreeProcs(int n)
{
SHMEM_OFFSET offset;
PGPROC *proc;
/* use volatile pointer to prevent code rearrangement */
@ -469,12 +466,11 @@ HaveNFreeProcs(int n)
SpinLockAcquire(ProcStructLock);
offset = procglobal->freeProcs;
proc = procglobal->freeProcs;
while (n > 0 && offset != INVALID_OFFSET)
while (n > 0 && proc != NULL)
{
proc = (PGPROC *) MAKE_PTR(offset);
offset = proc->links.next;
proc = (PGPROC *) proc->links.next;
n--;
}
@ -506,7 +502,7 @@ LockWaitCancel(void)
partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
if (MyProc->links.next != INVALID_OFFSET)
if (MyProc->links.next != NULL)
{
/* We could not have been granted the lock yet */
RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
@ -601,13 +597,13 @@ ProcKill(int code, Datum arg)
/* Return PGPROC structure (and semaphore) to freelist */
if (IsAutoVacuumWorkerProcess())
{
MyProc->links.next = procglobal->autovacFreeProcs;
procglobal->autovacFreeProcs = MAKE_OFFSET(MyProc);
MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
procglobal->autovacFreeProcs = MyProc;
}
else
{
MyProc->links.next = procglobal->freeProcs;
procglobal->freeProcs = MAKE_OFFSET(MyProc);
MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
procglobal->freeProcs = MyProc;
}
/* PGPROC struct isn't mine anymore */
@ -752,7 +748,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
{
LOCKMASK aheadRequests = 0;
proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
proc = (PGPROC *) waitQueue->links.next;
for (i = 0; i < waitQueue->size; i++)
{
/* Must he wait for me? */
@ -790,7 +786,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
}
/* Nope, so advance to next waiter */
aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
proc = (PGPROC *) MAKE_PTR(proc->links.next);
proc = (PGPROC *) proc->links.next;
}
/*
@ -1054,13 +1050,13 @@ ProcWakeup(PGPROC *proc, int waitStatus)
PGPROC *retProc;
/* Proc should be sleeping ... */
if (proc->links.prev == INVALID_OFFSET ||
proc->links.next == INVALID_OFFSET)
if (proc->links.prev == NULL ||
proc->links.next == NULL)
return NULL;
Assert(proc->waitStatus == STATUS_WAITING);
/* Save next process before we zap the list link */
retProc = (PGPROC *) MAKE_PTR(proc->links.next);
retProc = (PGPROC *) proc->links.next;
/* Remove process from wait queue */
SHMQueueDelete(&(proc->links));
@ -1097,7 +1093,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
if (queue_size == 0)
return;
proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
proc = (PGPROC *) waitQueue->links.next;
while (queue_size-- > 0)
{
@ -1130,7 +1126,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
* Cannot wake this guy. Remember his request for later checks.
*/
aheadRequests |= LOCKBIT_ON(lockmode);
proc = (PGPROC *) MAKE_PTR(proc->links.next);
proc = (PGPROC *) proc->links.next;
}
}
@ -1179,8 +1175,8 @@ CheckDeadLock(void)
* This is quicker than checking our semaphore's state, since no kernel
* call is needed, and it is safe because we hold the lock partition lock.
*/
if (MyProc->links.prev == INVALID_OFFSET ||
MyProc->links.next == INVALID_OFFSET)
if (MyProc->links.prev == NULL ||
MyProc->links.next == NULL)
goto check_done;
#ifdef LOCK_DEBUG

View File

@ -17,7 +17,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.23 2008/01/01 19:45:59 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.24 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -31,7 +31,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
pid_t creatorPID; /* PID of creating process */
Size totalsize; /* total size of segment */
Size freeoffset; /* offset to first free space */
Size indexoffset; /* offset to ShmemIndex table */
void *index; /* pointer to ShmemIndex table */
#ifndef WIN32 /* Windows doesn't have useful inode#s */
dev_t device; /* device data directory is on */
ino_t inode; /* inode number of data directory */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.106 2008/04/15 20:28:47 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.107 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -128,9 +128,9 @@ extern PGDLLIMPORT PGPROC *MyProc;
typedef struct PROC_HDR
{
/* Head of list of free PGPROC structures */
SHMEM_OFFSET freeProcs;
PGPROC *freeProcs;
/* Head of list of autovacuum's free PGPROC structures */
SHMEM_OFFSET autovacFreeProcs;
PGPROC *autovacFreeProcs;
/* Current shared estimate of appropriate spins_per_delay value */
int spins_per_delay;
} PROC_HDR;

View File

@ -3,11 +3,18 @@
* shmem.h
* shared memory management structures
*
* Historical note:
* A long time ago, Postgres' shared memory region was allowed to be mapped
* at a different address in each process, and shared memory "pointers" were
* passed around as offsets relative to the start of the shared memory region.
* That is no longer the case: each process must map the shared memory region
* at the same address. This means shared memory pointers can be passed
* around directly between different processes.
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.53 2008/01/01 19:45:59 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.54 2008/11/02 21:24:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,53 +24,18 @@
#include "utils/hsearch.h"
/*
* The shared memory region can start at a different address
* in every process. Shared memory "pointers" are actually
* offsets relative to the start of the shared memory region(s).
*
* In current usage, this is not actually a problem, but we keep
* the code that used to handle it...
*/
typedef unsigned long SHMEM_OFFSET;
#define INVALID_OFFSET (-1)
/*
* Start of the primary shared memory region, in this process' address space.
* The macros in this header file can only cope with offsets into this
* shared memory region!
*/
extern PGDLLIMPORT SHMEM_OFFSET ShmemBase;
/* coerce an offset into a pointer in this process's address space */
#define MAKE_PTR(xx_offs)\
(ShmemBase+((unsigned long)(xx_offs)))
/* coerce a pointer into a shmem offset */
#define MAKE_OFFSET(xx_ptr)\
((SHMEM_OFFSET) (((unsigned long)(xx_ptr))-ShmemBase))
#define SHM_PTR_VALID(xx_ptr)\
(((unsigned long)(xx_ptr)) > ShmemBase)
/* cannot have an offset to ShmemFreeStart (offset 0) */
#define SHM_OFFSET_VALID(xx_offs)\
(((xx_offs) != 0) && ((xx_offs) != INVALID_OFFSET))
/* shmqueue.c */
typedef struct SHM_QUEUE
{
SHMEM_OFFSET prev;
SHMEM_OFFSET next;
struct SHM_QUEUE *prev;
struct SHM_QUEUE *next;
} SHM_QUEUE;
/* shmem.c */
extern void InitShmemAccess(void *seghdr);
extern void InitShmemAllocation(void);
extern void *ShmemAlloc(Size size);
extern bool ShmemIsValid(unsigned long addr);
extern bool ShmemAddrIsValid(void *addr);
extern void InitShmemIndex(void);
extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,
HASHCTL *infoP, int hash_flags);
@ -77,15 +49,15 @@ extern void RequestAddinShmemSpace(Size size);
/* size constants for the shmem index table */
/* max size of data structure string name */
#define SHMEM_INDEX_KEYSIZE (48)
/* max size of the shmem index table (not a hard limit) */
/* estimated size of the shmem index table (not a hard limit) */
#define SHMEM_INDEX_SIZE (32)
/* this is a hash bucket in the shmem index table */
typedef struct
{
char key[SHMEM_INDEX_KEYSIZE]; /* string name */
unsigned long location; /* location in shared mem */
unsigned long size; /* numbytes allocated for the structure */
void *location; /* location in shared mem */
Size size; /* # bytes allocated for the structure */
} ShmemIndexEnt;
/*