* while arena offsets can be stored in a 32-bit word. In fact, we
* reserve one bit in each such word as a mark bit, so the maximum size
* of the arena is 2^31 elements, a restriction that does not currently
- * appear to be problematic.
+ * appear to be problematic. An additional advantage of this representation
+ * is that aligned 32-bit loads and stores are atomic on all architectures
+ * we support, but 64-bit loads and stores are not.
*
* When an element is inserted, we copy the data from the backend-private
* object supplied by the caller into one of these shared-memory entities.
Size size;
bool found;
void *shmem;
+ uint32 i;
/*
* If we're under the postmaster, this must be the EXEC_BACKEND case where
/* Arena follows the various lists. */
table->arena = (void *) (&table->freelist[table->nfreelists]);
- /* XXX. Must initialize spinlocks, set lists to empty, and then put
- * all arena nodes on free lists. */
+ /* Initialize all three sets of lists to empty. */
+ for (i = 0; i < table->nbuckets; ++i)
+ {
+ table->bucket[i].head = InvalidCHashPtr;
+ SpinLockInit(&table->bucket[i].head);
+ }
+ for (i = 0; i < table->ngarbage; ++i)
+ {
+ table->garbage[i].head = InvalidCHashPtr;
+ SpinLockInit(&table->garbage[i].head);
+ }
+ for (i = 0; i < table->nfreelists; ++i)
+ {
+ table->freelist[i].head = InvalidCHashPtr;
+ SpinLockInit(&table->freelist[i].head);
+ }
+
+ /* Put all arena elements on the free lists. */
+ for (i = 0; i < table->arena_limit; ++i)
+ {
+ CHashBucket *f = &table->freelist[i % table->nfreelists];
+ CHashNode *n = CHashTableGetNode(table, i);
+
+ n->next = f->head;
+ f->head = i;
+ }
/*
* Copy table (with pointers now filled in) to shared memory. This is