From: Tom Lane Date: Sun, 2 Nov 2008 21:24:52 +0000 (+0000) Subject: Remove the last vestiges of the MAKE_PTR/MAKE_OFFSET mechanism. We haven't X-Git-Tag: REL8_4_BETA1~782 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d7112cfa884e5125a20a24590f193ceebedf0146;p=postgresql 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 --- diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index d24ea6b2a1..1148009844 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -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); diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 9f218d6bdc..6f056e0e16 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -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 diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 831a4add7d..67e8d378c8 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -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; diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c index 3e3b3a73b6..24542e7b63 100644 --- a/src/backend/storage/ipc/shmqueue.c +++ b/src/backend/storage/ipc/shmqueue.c @@ -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 */ diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index 8a564a1754..713d1065b1 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -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); diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 991d94fe35..7a990e0d7e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -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)); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 9548b6c0fa..0ceff0ffe3 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.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 diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index e5fd8e3ac2..cbe723d1d7 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -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 */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index d1ab71d0ee..ccdc48884a 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -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; diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index 4bee544fb6..cbfca69e67 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -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; /*