+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * shmqueue.c
- * shared memory linked lists
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * src/backend/storage/ipc/shmqueue.c
- *
- * NOTES
- *
- * Package for managing doubly-linked lists in shared memory.
- * The only tricky thing is that SHM_QUEUE will usually be a field
- * in a larger record. SHMQueueNext has to return a pointer
- * to the record itself instead of a pointer to the SHMQueue field
- * of the record. It takes an extra parameter and does some extra
- * pointer arithmetic to do this correctly.
- *
- * NOTE: These are set up so they can be turned into macros some day.
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "storage/shmem.h"
-
-
-/*
- * ShmemQueueInit -- make the head of a new queue point
- * to itself
- */
-void
-SHMQueueInit(SHM_QUEUE *queue)
-{
- Assert(ShmemAddrIsValid(queue));
- queue->prev = queue->next = queue;
-}
-
-/*
- * SHMQueueIsDetached -- true if element is not currently
- * in a queue.
- */
-bool
-SHMQueueIsDetached(const SHM_QUEUE *queue)
-{
- Assert(ShmemAddrIsValid(queue));
- return (queue->prev == NULL);
-}
-
-/*
- * SHMQueueElemInit -- clear an element's links
- */
-void
-SHMQueueElemInit(SHM_QUEUE *queue)
-{
- Assert(ShmemAddrIsValid(queue));
- queue->prev = queue->next = NULL;
-}
-
-/*
- * SHMQueueDelete -- remove an element from the queue and
- * close the links
- */
-void
-SHMQueueDelete(SHM_QUEUE *queue)
-{
- SHM_QUEUE *nextElem = queue->next;
- SHM_QUEUE *prevElem = queue->prev;
-
- Assert(ShmemAddrIsValid(queue));
- Assert(ShmemAddrIsValid(nextElem));
- Assert(ShmemAddrIsValid(prevElem));
-
- prevElem->next = queue->next;
- nextElem->prev = queue->prev;
-
- queue->prev = queue->next = NULL;
-}
-
-/*
- * SHMQueueInsertBefore -- put elem in queue before the given queue
- * element. Inserting "before" the queue head puts the elem
- * at the tail of the queue.
- */
-void
-SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
-{
- SHM_QUEUE *prevPtr = queue->prev;
-
- Assert(ShmemAddrIsValid(queue));
- Assert(ShmemAddrIsValid(elem));
-
- elem->next = prevPtr->next;
- elem->prev = queue->prev;
- queue->prev = elem;
- prevPtr->next = elem;
-}
-
-/*
- * SHMQueueInsertAfter -- put elem in queue after the given queue
- * element. Inserting "after" the queue head puts the elem
- * at the head of the queue.
- */
-void
-SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
-{
- SHM_QUEUE *nextPtr = queue->next;
-
- Assert(ShmemAddrIsValid(queue));
- Assert(ShmemAddrIsValid(elem));
-
- elem->prev = nextPtr->prev;
- elem->next = queue->next;
- queue->next = elem;
- nextPtr->prev = elem;
-}
-
-/*--------------------
- * SHMQueueNext -- Get the next element from a queue
- *
- * To start the iteration, pass the queue head as both queue and curElem.
- * Returns NULL if no more elements.
- *
- * 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.
- * For example,
- * struct {
- * int stuff;
- * SHMQueue elem;
- * } ELEMType;
- * 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(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, Size linkOffset)
-{
- SHM_QUEUE *elemPtr = curElem->next;
-
- Assert(ShmemAddrIsValid(curElem));
-
- if (elemPtr == queue) /* back to the queue head? */
- return NULL;
-
- return (Pointer) (((char *) elemPtr) - linkOffset);
-}
-
-/*--------------------
- * SHMQueuePrev -- Get the previous element from a queue
- *
- * Same as SHMQueueNext, just starting at tail and moving towards head.
- * All other comments and usage applies.
- */
-Pointer
-SHMQueuePrev(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, Size linkOffset)
-{
- SHM_QUEUE *elemPtr = curElem->prev;
-
- Assert(ShmemAddrIsValid(curElem));
-
- if (elemPtr == queue) /* back to the queue head? */
- return NULL;
-
- return (Pointer) (((char *) elemPtr) - linkOffset);
-}
-
-/*
- * SHMQueueEmpty -- true if queue head is only element, false otherwise
- */
-bool
-SHMQueueEmpty(const SHM_QUEUE *queue)
-{
- Assert(ShmemAddrIsValid(queue));
-
- if (queue->prev == queue)
- {
- Assert(queue->next == queue);
- return true;
- }
- return false;
-}
#include "utils/hsearch.h"
-/* shmqueue.c */
-typedef struct SHM_QUEUE
-{
- struct SHM_QUEUE *prev;
- struct SHM_QUEUE *next;
-} SHM_QUEUE;
-
/* shmem.c */
extern void InitShmemAccess(void *seghdr);
extern void InitShmemAllocation(void);
Size allocated_size; /* # bytes actually allocated */
} ShmemIndexEnt;
-/*
- * prototypes for functions in shmqueue.c
- */
-extern void SHMQueueInit(SHM_QUEUE *queue);
-extern void SHMQueueElemInit(SHM_QUEUE *queue);
-extern void SHMQueueDelete(SHM_QUEUE *queue);
-extern void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem);
-extern void SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem);
-extern Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem,
- Size linkOffset);
-extern Pointer SHMQueuePrev(const SHM_QUEUE *queue, const SHM_QUEUE *curElem,
- Size linkOffset);
-extern bool SHMQueueEmpty(const SHM_QUEUE *queue);
-extern bool SHMQueueIsDetached(const SHM_QUEUE *queue);
-
#endif /* SHMEM_H */