* 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
typedef struct TwoPhaseStateData
{
/* Head of linked list of free GlobalTransactionData structs */
- SHMEM_OFFSET freeGXacts;
+ GlobalTransaction freeGXacts;
/* Number of valid prepXacts entries. */
int numPrepXacts;
int i;
Assert(!found);
- TwoPhaseState->freeGXacts = INVALID_OFFSET;
+ TwoPhaseState->freeGXacts = NULL;
TwoPhaseState->numPrepXacts = 0;
/*
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
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--;
}
}
/* 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));
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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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;
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.
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
* 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");
}
}
/* 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;
if (avdb != NULL)
{
WorkerInfo worker;
- SHMEM_OFFSET sworker;
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
* 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);
* 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;
* 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);
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;
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;
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)));
/* 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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 */
PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr;
ShmemSegHdr = shmhdr;
- ShmemBase = (SHMEM_OFFSET) shmhdr;
- ShmemEnd = ShmemBase + shmhdr->totalsize;
+ ShmemBase = (void *) shmhdr;
+ ShmemEnd = (char *) ShmemBase + shmhdr->totalsize;
}
/*
SpinLockInit(ShmemLock);
/* ShmemIndex can't be set up yet (need LWLocks first) */
- shmhdr->indexoffset = 0;
+ shmhdr->index = NULL;
ShmemIndex = (HTAB *) NULL;
/*
newFree = newStart + size;
if (newFree <= shmemseghdr->totalsize)
{
- newSpace = (void *) MAKE_PTR(newStart);
+ newSpace = (void *) ((char *) ShmemBase + newStart);
shmemseghdr->freeoffset = newFree;
}
else
}
/*
- * 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);
}
/*
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
* 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);
/* let caller print its message too */
return NULL;
}
- structPtr = (void *) MAKE_PTR(result->location);
+ structPtr = result->location;
}
else
{
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;
*
*
* 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
*
#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
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;
}
/*
bool
SHMQueueIsDetached(SHM_QUEUE *queue)
{
- Assert(SHM_PTR_VALID(queue));
- return (queue)->prev == INVALID_OFFSET;
+ Assert(ShmemAddrIsValid(queue));
+ return (queue->prev == NULL);
}
#endif
void
SHMQueueElemInit(SHM_QUEUE *queue)
{
- Assert(SHM_PTR_VALID(queue));
- (queue)->prev = (queue)->next = INVALID_OFFSET;
+ Assert(ShmemAddrIsValid(queue));
+ queue->prev = queue->next = NULL;
}
/*
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;
}
/*
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;
}
/*
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 */
* 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)
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;
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 */
*
*
* 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:
*
/*
* 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)
waitQueue = &(lock->waitProcs);
queue_size = waitQueue->size;
- proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+ proc = (PGPROC *) waitQueue->links.next;
while (queue_size-- > 0)
{
}
}
- proc = (PGPROC *) MAKE_PTR(proc->links.next);
+ proc = (PGPROC *) proc->links.next;
}
}
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;
}
/*
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);
*
*
* 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
/* 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));
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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;
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));
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));
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
- SHMEM_OFFSET myOffset;
int i;
/*
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
bool
HaveNFreeProcs(int n)
{
- SHMEM_OFFSET offset;
PGPROC *proc;
/* use volatile pointer to prevent code rearrangement */
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--;
}
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);
/* 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 */
{
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? */
}
/* Nope, so advance to next waiter */
aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
- proc = (PGPROC *) MAKE_PTR(proc->links.next);
+ proc = (PGPROC *) proc->links.next;
}
/*
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));
if (queue_size == 0)
return;
- proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+ proc = (PGPROC *) waitQueue->links.next;
while (queue_size-- > 0)
{
* 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;
}
}
* 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
* 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 $
*
*-------------------------------------------------------------------------
*/
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 */
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
* 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 $
*
*-------------------------------------------------------------------------
*/
#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);
/* 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;
/*