66 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
9- * src/include /storage/shm_toc.c
9+ * src/backend /storage/ipc /shm_toc.c
1010 *
1111 *-------------------------------------------------------------------------
1212 */
2020typedef struct shm_toc_entry
2121{
2222uint64 key ;/* Arbitrary identifier */
23- uint64 offset ;/*Bytes offset */
23+ Size offset ;/*Offset, in bytes, from TOC start */
2424}shm_toc_entry ;
2525
2626struct shm_toc
2727{
28- uint64 toc_magic ;/* Magic numberfor this TOC */
28+ uint64 toc_magic ;/* Magic numberidentifying this TOC */
2929slock_t toc_mutex ;/* Spinlock for mutual exclusion */
3030Size toc_total_bytes ;/* Bytes managed by this TOC */
3131Size toc_allocated_bytes ;/* Bytes allocated of those managed */
32- Size toc_nentry ;/* Number of entries in TOC */
32+ uint32 toc_nentry ;/* Number of entries in TOC */
3333shm_toc_entry toc_entry [FLEXIBLE_ARRAY_MEMBER ];
3434};
3535
@@ -53,7 +53,7 @@ shm_toc_create(uint64 magic, void *address, Size nbytes)
5353
5454/*
5555 * Attach to an existing table of contents. If the magic number found at
56- * the target address doesn't match our expectations,returns NULL.
56+ * the target address doesn't match our expectations,return NULL.
5757 */
5858extern shm_toc *
5959shm_toc_attach (uint64 magic ,void * address )
@@ -64,7 +64,7 @@ shm_toc_attach(uint64 magic, void *address)
6464return NULL ;
6565
6666Assert (toc -> toc_total_bytes >=toc -> toc_allocated_bytes );
67- Assert (toc -> toc_total_bytes >= offsetof(shm_toc ,toc_entry ));
67+ Assert (toc -> toc_total_bytes > offsetof(shm_toc ,toc_entry ));
6868
6969return toc ;
7070}
@@ -76,7 +76,7 @@ shm_toc_attach(uint64 magic, void *address)
7676 * just a way of dividing a single physical shared memory segment into logical
7777 * chunks that may be used for different purposes.
7878 *
79- * Weallocated backwards from the end of the segment, so that the TOC entries
79+ * Weallocate backwards from the end of the segment, so that the TOC entries
8080 * can grow forward from the start of the segment.
8181 */
8282extern void *
@@ -140,7 +140,7 @@ shm_toc_freespace(shm_toc *toc)
140140/*
141141 * Insert a TOC entry.
142142 *
143- * The idea here is that process setting up the shared memory segment will
143+ * The idea here is thatthe process setting up the shared memory segment will
144144 * register the addresses of data structures within the segment using this
145145 * function. Each data structure will be identified using a 64-bit key, which
146146 * is assumed to be a well-known or discoverable integer. Other processes
@@ -155,17 +155,17 @@ shm_toc_freespace(shm_toc *toc)
155155 * data structure here. But the real idea here is just to give someone mapping
156156 * a dynamic shared memory the ability to find the bare minimum number of
157157 * pointers that they need to bootstrap. If you're storing a lot of stuff in
158- *here , you're doing it wrong.
158+ *the TOC , you're doing it wrong.
159159 */
160160void
161161shm_toc_insert (shm_toc * toc ,uint64 key ,void * address )
162162{
163163volatile shm_toc * vtoc = toc ;
164- uint64 total_bytes ;
165- uint64 allocated_bytes ;
166- uint64 nentry ;
167- uint64 toc_bytes ;
168- uint64 offset ;
164+ Size total_bytes ;
165+ Size allocated_bytes ;
166+ Size nentry ;
167+ Size toc_bytes ;
168+ Size offset ;
169169
170170/* Relativize pointer. */
171171Assert (address > (void * )toc );
@@ -181,7 +181,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
181181
182182/* Check for memory exhaustion and overflow. */
183183if (toc_bytes + sizeof (shm_toc_entry )> total_bytes ||
184- toc_bytes + sizeof (shm_toc_entry )< toc_bytes )
184+ toc_bytes + sizeof (shm_toc_entry )< toc_bytes ||
185+ nentry >=PG_UINT32_MAX )
185186{
186187SpinLockRelease (& toc -> toc_mutex );
187188ereport (ERROR ,
@@ -220,10 +221,13 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
220221void *
221222shm_toc_lookup (shm_toc * toc ,uint64 key ,bool noError )
222223{
223- uint64 nentry ;
224- uint64 i ;
224+ uint32 nentry ;
225+ uint32 i ;
225226
226- /* Read the number of entries before we examine any entry. */
227+ /*
228+ * Read the number of entries before we examine any entry. We assume that
229+ * reading a uint32 is atomic.
230+ */
227231nentry = toc -> toc_nentry ;
228232pg_read_barrier ();
229233