dshash_table_control *control; /* Control object in DSM. */
dsa_pointer *buckets; /* Current bucket pointers in DSM. */
size_t size_log2; /* log2(number of buckets) */
- bool find_locked; /* Is any partition lock held by 'find'? */
- bool find_exclusively_locked; /* ... exclusively? */
};
/* Given a pointer to an item, find the entry (user data) it holds. */
#define PARTITION_LOCK(hash_table, i) \
(&(hash_table)->control->partitions[(i)].lock)
+#define ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table) \
+ Assert(!LWLockAnyHeldByMe(&(hash_table)->control->partitions[0].lock, \
+ DSHASH_NUM_PARTITIONS, sizeof(dshash_partition)))
+
/*
* Create a new hash table backed by the given dynamic shared area, with the
* given parameters. The returned object is allocated in backend-local memory
}
}
- hash_table->find_locked = false;
- hash_table->find_exclusively_locked = false;
-
/*
* Set up the initial array of buckets. Our initial size is the same as
* the number of partitions.
hash_table->params = *params;
hash_table->arg = arg;
hash_table->control = dsa_get_address(area, control);
- hash_table->find_locked = false;
- hash_table->find_exclusively_locked = false;
Assert(hash_table->control->magic == DSHASH_MAGIC);
/*
void
dshash_detach(dshash_table *hash_table)
{
- Assert(!hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table);
/* The hash table may have been destroyed. Just free local memory. */
pfree(hash_table);
partition = PARTITION_FOR_HASH(hash);
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(!hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table);
LWLockAcquire(PARTITION_LOCK(hash_table, partition),
exclusive ? LW_EXCLUSIVE : LW_SHARED);
else
{
/* The caller will free the lock by calling dshash_release_lock. */
- hash_table->find_locked = true;
- hash_table->find_exclusively_locked = exclusive;
return ENTRY_FROM_ITEM(item);
}
}
partition = &hash_table->control->partitions[partition_index];
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(!hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table);
restart:
LWLockAcquire(PARTITION_LOCK(hash_table, partition_index),
}
/* The caller must release the lock with dshash_release_lock. */
- hash_table->find_locked = true;
- hash_table->find_exclusively_locked = true;
return ENTRY_FROM_ITEM(item);
}
bool found;
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(!hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table);
hash = hash_key(hash_table, key);
partition = PARTITION_FOR_HASH(hash);
size_t partition = PARTITION_FOR_HASH(item->hash);
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(hash_table->find_locked);
- Assert(hash_table->find_exclusively_locked);
Assert(LWLockHeldByMeInMode(PARTITION_LOCK(hash_table, partition),
LW_EXCLUSIVE));
delete_item(hash_table, item);
- hash_table->find_locked = false;
- hash_table->find_exclusively_locked = false;
LWLockRelease(PARTITION_LOCK(hash_table, partition));
}
size_t partition_index = PARTITION_FOR_HASH(item->hash);
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(hash_table->find_locked);
- Assert(LWLockHeldByMeInMode(PARTITION_LOCK(hash_table, partition_index),
- hash_table->find_exclusively_locked
- ? LW_EXCLUSIVE : LW_SHARED));
- hash_table->find_locked = false;
- hash_table->find_exclusively_locked = false;
LWLockRelease(PARTITION_LOCK(hash_table, partition_index));
}
if (status->curpartition == -1)
{
Assert(status->curbucket == 0);
- Assert(!status->hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(status->hash_table);
status->curpartition = 0;
status->curitem =
dsa_get_address(status->hash_table->area, next_item_pointer);
- status->hash_table->find_locked = true;
- status->hash_table->find_exclusively_locked = status->exclusive;
/*
* The caller may delete the item. Store the next item in case of
void
dshash_seq_term(dshash_seq_status *status)
{
- status->hash_table->find_locked = false;
- status->hash_table->find_exclusively_locked = false;
-
if (status->curpartition >= 0)
LWLockRelease(PARTITION_LOCK(status->hash_table, status->curpartition));
}
Assert(status->exclusive);
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(hash_table->find_locked);
- Assert(hash_table->find_exclusively_locked);
Assert(LWLockHeldByMeInMode(PARTITION_LOCK(hash_table, partition),
LW_EXCLUSIVE));
size_t j;
Assert(hash_table->control->magic == DSHASH_MAGIC);
- Assert(!hash_table->find_locked);
+ ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table);
for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
{