6
6
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
- * src/include /storage/shm_toc.c
9
+ * src/backend /storage/ipc /shm_toc.c
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
20
20
typedef struct shm_toc_entry
21
21
{
22
22
uint64 key ;/* Arbitrary identifier */
23
- uint64 offset ;/*Bytes offset */
23
+ Size offset ;/*Offset, in bytes, from TOC start */
24
24
}shm_toc_entry ;
25
25
26
26
struct shm_toc
27
27
{
28
- uint64 toc_magic ;/* Magic numberfor this TOC */
28
+ uint64 toc_magic ;/* Magic numberidentifying this TOC */
29
29
slock_t toc_mutex ;/* Spinlock for mutual exclusion */
30
30
Size toc_total_bytes ;/* Bytes managed by this TOC */
31
31
Size 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 */
33
33
shm_toc_entry toc_entry [FLEXIBLE_ARRAY_MEMBER ];
34
34
};
35
35
@@ -53,7 +53,7 @@ shm_toc_create(uint64 magic, void *address, Size nbytes)
53
53
54
54
/*
55
55
* 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.
57
57
*/
58
58
extern shm_toc *
59
59
shm_toc_attach (uint64 magic ,void * address )
@@ -64,7 +64,7 @@ shm_toc_attach(uint64 magic, void *address)
64
64
return NULL ;
65
65
66
66
Assert (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 ));
68
68
69
69
return toc ;
70
70
}
@@ -76,7 +76,7 @@ shm_toc_attach(uint64 magic, void *address)
76
76
* just a way of dividing a single physical shared memory segment into logical
77
77
* chunks that may be used for different purposes.
78
78
*
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
80
80
* can grow forward from the start of the segment.
81
81
*/
82
82
extern void *
@@ -140,7 +140,7 @@ shm_toc_freespace(shm_toc *toc)
140
140
/*
141
141
* Insert a TOC entry.
142
142
*
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
144
144
* register the addresses of data structures within the segment using this
145
145
* function. Each data structure will be identified using a 64-bit key, which
146
146
* is assumed to be a well-known or discoverable integer. Other processes
@@ -155,17 +155,17 @@ shm_toc_freespace(shm_toc *toc)
155
155
* data structure here. But the real idea here is just to give someone mapping
156
156
* a dynamic shared memory the ability to find the bare minimum number of
157
157
* 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.
159
159
*/
160
160
void
161
161
shm_toc_insert (shm_toc * toc ,uint64 key ,void * address )
162
162
{
163
163
volatile 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 ;
169
169
170
170
/* Relativize pointer. */
171
171
Assert (address > (void * )toc );
@@ -181,7 +181,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
181
181
182
182
/* Check for memory exhaustion and overflow. */
183
183
if (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 )
185
186
{
186
187
SpinLockRelease (& toc -> toc_mutex );
187
188
ereport (ERROR ,
@@ -220,10 +221,13 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
220
221
void *
221
222
shm_toc_lookup (shm_toc * toc ,uint64 key ,bool noError )
222
223
{
223
- uint64 nentry ;
224
- uint64 i ;
224
+ uint32 nentry ;
225
+ uint32 i ;
225
226
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
+ */
227
231
nentry = toc -> toc_nentry ;
228
232
pg_read_barrier ();
229
233