summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/shm_toc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc/shm_toc.c')
-rw-r--r--src/backend/storage/ipc/shm_toc.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 5e290df3366..50334cd7978 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * src/include/storage/shm_toc.c
+ * src/backend/storage/ipc/shm_toc.c
*
*-------------------------------------------------------------------------
*/
@@ -20,16 +20,16 @@
typedef struct shm_toc_entry
{
uint64 key; /* Arbitrary identifier */
- uint64 offset; /* Bytes offset */
+ Size offset; /* Offset, in bytes, from TOC start */
} shm_toc_entry;
struct shm_toc
{
- uint64 toc_magic; /* Magic number for this TOC */
+ uint64 toc_magic; /* Magic number identifying this TOC */
slock_t toc_mutex; /* Spinlock for mutual exclusion */
Size toc_total_bytes; /* Bytes managed by this TOC */
Size toc_allocated_bytes; /* Bytes allocated of those managed */
- Size toc_nentry; /* Number of entries in TOC */
+ uint32 toc_nentry; /* Number of entries in TOC */
shm_toc_entry toc_entry[FLEXIBLE_ARRAY_MEMBER];
};
@@ -53,7 +53,7 @@ shm_toc_create(uint64 magic, void *address, Size nbytes)
/*
* Attach to an existing table of contents. If the magic number found at
- * the target address doesn't match our expectations, returns NULL.
+ * the target address doesn't match our expectations, return NULL.
*/
extern shm_toc *
shm_toc_attach(uint64 magic, void *address)
@@ -64,7 +64,7 @@ shm_toc_attach(uint64 magic, void *address)
return NULL;
Assert(toc->toc_total_bytes >= toc->toc_allocated_bytes);
- Assert(toc->toc_total_bytes >= offsetof(shm_toc, toc_entry));
+ Assert(toc->toc_total_bytes > offsetof(shm_toc, toc_entry));
return toc;
}
@@ -76,7 +76,7 @@ shm_toc_attach(uint64 magic, void *address)
* just a way of dividing a single physical shared memory segment into logical
* chunks that may be used for different purposes.
*
- * We allocated backwards from the end of the segment, so that the TOC entries
+ * We allocate backwards from the end of the segment, so that the TOC entries
* can grow forward from the start of the segment.
*/
extern void *
@@ -140,7 +140,7 @@ shm_toc_freespace(shm_toc *toc)
/*
* Insert a TOC entry.
*
- * The idea here is that process setting up the shared memory segment will
+ * The idea here is that the process setting up the shared memory segment will
* register the addresses of data structures within the segment using this
* function. Each data structure will be identified using a 64-bit key, which
* is assumed to be a well-known or discoverable integer. Other processes
@@ -155,17 +155,17 @@ shm_toc_freespace(shm_toc *toc)
* data structure here. But the real idea here is just to give someone mapping
* a dynamic shared memory the ability to find the bare minimum number of
* pointers that they need to bootstrap. If you're storing a lot of stuff in
- * here, you're doing it wrong.
+ * the TOC, you're doing it wrong.
*/
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
volatile shm_toc *vtoc = toc;
- uint64 total_bytes;
- uint64 allocated_bytes;
- uint64 nentry;
- uint64 toc_bytes;
- uint64 offset;
+ Size total_bytes;
+ Size allocated_bytes;
+ Size nentry;
+ Size toc_bytes;
+ Size offset;
/* Relativize pointer. */
Assert(address > (void *) toc);
@@ -181,7 +181,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
/* Check for memory exhaustion and overflow. */
if (toc_bytes + sizeof(shm_toc_entry) > total_bytes ||
- toc_bytes + sizeof(shm_toc_entry) < toc_bytes)
+ toc_bytes + sizeof(shm_toc_entry) < toc_bytes ||
+ nentry >= PG_UINT32_MAX)
{
SpinLockRelease(&toc->toc_mutex);
ereport(ERROR,
@@ -220,10 +221,13 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void *
shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
{
- uint64 nentry;
- uint64 i;
+ uint32 nentry;
+ uint32 i;
- /* Read the number of entries before we examine any entry. */
+ /*
+ * Read the number of entries before we examine any entry. We assume that
+ * reading a uint32 is atomic.
+ */
nentry = toc->toc_nentry;
pg_read_barrier();