aboutsummaryrefslogtreecommitdiff
path: root/src/ptr_set.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ptr_set.cpp')
-rw-r--r--src/ptr_set.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp
index 5097e2bb6..06c1e4a58 100644
--- a/src/ptr_set.cpp
+++ b/src/ptr_set.cpp
@@ -135,6 +135,44 @@ gb_internal bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it pre
}
template <typename T>
+gb_internal bool ptr_set_update_with_mutex(PtrSet<T> *s, T ptr, RWSpinLock *m) { // returns true if it previously existsed
+ rwlock_acquire_upgrade(m);
+ if (ptr_set_exists(s, ptr)) {
+ rwlock_release_upgrade(m);
+ return true;
+ }
+
+ rwlock_release_upgrade_and_acquire_write(m);
+ defer (rwlock_release_write(m));
+
+ if (s->keys == nullptr) {
+ ptr_set_init(s);
+ } else if (ptr_set__full(s)) {
+ ptr_set_grow(s);
+ }
+ GB_ASSERT(s->count < s->capacity);
+ GB_ASSERT(s->capacity >= 0);
+
+ usize mask = s->capacity-1;
+ u32 hash = ptr_map_hash_key(ptr);
+ usize hash_index = (cast(usize)hash) & mask;
+ GB_ASSERT(hash_index < s->capacity);
+ for (usize i = 0; i < s->capacity; i++) {
+ T *key = &s->keys[hash_index];
+ GB_ASSERT(*key != ptr);
+ if (*key == (T)PtrSet<T>::TOMBSTONE || *key == 0) {
+ *key = ptr;
+ s->count++;
+ return false;
+ }
+ hash_index = (hash_index+1)&mask;
+ }
+
+ GB_PANIC("ptr set out of memory");
+ return false;
+}
+
+template <typename T>
gb_internal T ptr_set_add(PtrSet<T> *s, T ptr) {
ptr_set_update(s, ptr);
return ptr;