Commit d7112cfa authored by Tom Lane's avatar Tom Lane

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
parent 902d1cb3
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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);
Assert(SHM_PTR_VALID(queue));
Assert(SHM_PTR_VALID(elem));
SHM_QUEUE *prevPtr = queue->prev;
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertBefore: begin");
#endif
(elem)->next = prevPtr->next;
(elem)->prev = queue->prev;
(queue)->prev = elemOffset;
prevPtr->next = elemOffset;
Assert(ShmemAddrIsValid(queue));
Assert(ShmemAddrIsValid(elem));
#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);
Assert(SHM_PTR_VALID(queue));
Assert(SHM_PTR_VALID(elem));
#ifdef SHMQUEUE_DEBUG
dumpQ(queue, "in SHMQueueInsertAfter: begin");
#endif
SHM_QUEUE *nextPtr = queue->next;
(elem)->prev = nextPtr->prev;
(elem)->next = queue->next;
(queue)->next = elemOffset;
nextPtr->prev = elemOffset;
Assert(ShmemAddrIsValid(queue));
Assert(ShmemAddrIsValid(elem));
#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 */
......@@ -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);
......
......@@ -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));
......
......@@ -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
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
/*
......
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