From 92dceadf58f8603cc02caa1cb17b71dd1a956e37 Mon Sep 17 00:00:00 2001 From: dpdani Date: Sat, 20 Jul 2024 15:57:33 +0200 Subject: [PATCH] bugfixes and minor improvements --- src/cereggii/__about__.py | 2 +- src/cereggii/atomic_dict/insert.c | 30 +++++++++++++---------- src/cereggii/atomic_dict/lookup.c | 2 +- src/cereggii/atomic_dict/migrate.c | 38 +++++++++++++----------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/cereggii/__about__.py b/src/cereggii/__about__.py index 10c5d5cd..e1b1588c 100644 --- a/src/cereggii/__about__.py +++ b/src/cereggii/__about__.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -__version__ = "0.2.0" +__version__ = "0.2.1" major, minor, patch, *_ = __version__.split(".") diff --git a/src/cereggii/atomic_dict/insert.c b/src/cereggii/atomic_dict/insert.c index 41a47f81..42907260 100644 --- a/src/cereggii/atomic_dict/insert.c +++ b/src/cereggii/atomic_dict/insert.c @@ -46,21 +46,21 @@ AtomicDict_ExpectedUpdateEntry(AtomicDict_Meta *meta, uint64_t entry_ix, // already been reached, thus we can proceed visiting // the probe. } else { - // expected != NOT_FOUND, value may be NULL - if (entry.value != expected && expected != ANY) { - *done = 1; - *expectation = 0; - return 1; - } - + // expected != NOT_FOUND do { + if (entry.value != expected && expected != ANY) { + *done = 1; + *expectation = 0; + return 1; + } + *current = entry.value; - *done = CereggiiAtomic_CompareExchangePtr((void **) &entry_p->value, entry.value, desired); + *done = CereggiiAtomic_CompareExchangePtr((void **) &entry_p->value, *current, desired); if (!*done) { AtomicDict_ReadEntry(entry_p, &entry); - if (entry.value == NULL || entry.flags & ENTRY_FLAGS_TOMBSTONE || entry.flags & ENTRY_FLAGS_SWAPPED) + if (*current == NULL || entry.flags & ENTRY_FLAGS_TOMBSTONE || entry.flags & ENTRY_FLAGS_SWAPPED) return 0; } } while (!*done); @@ -100,6 +100,10 @@ AtomicDict_ExpectedInsertOrUpdateCloseToDistance0(AtomicDict_Meta *meta, PyObjec goto empty_slot; if (!skip_entry_check) { + if (reader.buffer[i].tag != (hash & meta->tag_mask)) { + continue; + } + int updated = AtomicDict_ExpectedUpdateEntry(meta, reader.buffer[i].index, key, hash, expected, desired, current, done, expectation); if (updated < 0) @@ -391,7 +395,7 @@ AtomicDict_CompareAndSet(AtomicDict *self, PyObject *key, PyObject *expected, Py } if (result == NOT_FOUND && entry_loc.location != 0) { - storage->local_len++; + storage->local_len++; // TODO: overflow self->len_dirty = 1; } _PyMutex_unlock(&storage->self_mutex); @@ -406,8 +410,10 @@ AtomicDict_CompareAndSet(AtomicDict *self, PyObject *key, PyObject *expected, Py if (migrated < 0) goto fail; - Py_DECREF(meta); - goto beginning; + if (must_grow) { // insertion didn't happen + Py_DECREF(meta); + goto beginning; + } } Py_DECREF(meta); diff --git a/src/cereggii/atomic_dict/lookup.c b/src/cereggii/atomic_dict/lookup.c index 1399b90c..bc98af24 100644 --- a/src/cereggii/atomic_dict/lookup.c +++ b/src/cereggii/atomic_dict/lookup.c @@ -46,8 +46,8 @@ AtomicDict_Lookup(AtomicDict_Meta *meta, PyObject *key, Py_hash_t hash, goto not_found; } + check_entry: if (node.tag == (hash & meta->tag_mask)) { - check_entry: result->entry_p = AtomicDict_GetEntryAt(node.index, meta); AtomicDict_ReadEntry(result->entry_p, &result->entry); diff --git a/src/cereggii/atomic_dict/migrate.c b/src/cereggii/atomic_dict/migrate.c index 523737dd..c9c92038 100644 --- a/src/cereggii/atomic_dict/migrate.c +++ b/src/cereggii/atomic_dict/migrate.c @@ -186,19 +186,17 @@ AtomicDict_LeaderMigrate(AtomicDict *self, AtomicDict_Meta *current_meta /* borr Py_INCREF(new_meta->blocks[block_i]); } - if (from_log_size >= to_log_size) { - AtomicDictMeta_ClearIndex(new_meta); - AtomicDict_EndSynchronousOperation(self); - holding_sync_lock = 0; - } else { + if (from_log_size < to_log_size) { current_meta->accessor_key = self->accessor_key; current_meta->accessors = self->accessors; for (int64_t block = 0; block <= new_meta->greatest_allocated_block; ++block) { new_meta->blocks[block]->generation = new_meta->generation; } - - // AtomicDictMeta_ClearIndex(new_meta); + } else { + AtomicDictMeta_ClearIndex(new_meta); + AtomicDict_EndSynchronousOperation(self); + holding_sync_lock = 0; } // 👀 @@ -213,7 +211,8 @@ AtomicDict_LeaderMigrate(AtomicDict *self, AtomicDict_Meta *current_meta /* borr int set = AtomicRef_CompareAndSet(self->metadata, (PyObject *) current_meta, (PyObject *) new_meta); assert(set); - if (holding_sync_lock) { + if (from_log_size < to_log_size) { + assert(holding_sync_lock); for (int i = 0; i < PyList_Size(self->accessors); ++i) { AtomicDict_AccessorStorage *accessor = (AtomicDict_AccessorStorage *) PyList_GetItem(self->accessors, i); accessor->participant_in_migration = 0; @@ -322,20 +321,15 @@ AtomicDict_MigrateReInsertAll(AtomicDict_Meta *current_meta, AtomicDict_Meta *ne entry_loc.entry->flags & ENTRY_FLAGS_TOMBSTONE || entry_loc.entry->flags & ENTRY_FLAGS_SWAPPED) continue; - AtomicDict_SearchResult sr; - AtomicDict_Lookup(current_meta, entry_loc.entry->key, entry_loc.entry->hash, &sr); - - if (sr.found) { - int must_grow; - PyObject *result = AtomicDict_ExpectedInsertOrUpdate(new_meta, - entry_loc.entry->key, entry_loc.entry->hash, - NOT_FOUND, entry_loc.entry->value, - &entry_loc, &must_grow, 1); - assert(result != EXPECTATION_FAILED); - assert(!must_grow); - assert(result != NULL); - assert(result == NOT_FOUND); - } + int must_grow; + PyObject *result = AtomicDict_ExpectedInsertOrUpdate(new_meta, + entry_loc.entry->key, entry_loc.entry->hash, + NOT_FOUND, entry_loc.entry->value, + &entry_loc, &must_grow, 1); + assert(result != EXPECTATION_FAILED); + assert(!must_grow); + assert(result != NULL); + assert(result == NOT_FOUND); } mark_as_done: