From f6df55787a74c0010074338b0f2b50ac803c2b22 Mon Sep 17 00:00:00 2001 From: CatboxParadox Date: Tue, 27 Jul 2021 11:54:51 +0200 Subject: [PATCH] Make get_or_set_index immune to memory address reuse --- CDS_test/safe_ptr.h | 9 +++++---- Real_app_bench/safe_ptr.h | 9 +++++---- bench_contfree/main.cpp | 9 +++++---- benchmark/main.cpp | 9 +++++---- contfree_shared_mutex/safe_ptr.h | 9 +++++---- safe_ptr.h | 9 +++++---- 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/CDS_test/safe_ptr.h b/CDS_test/safe_ptr.h index 0b850d7..8d5b73e 100644 --- a/CDS_test/safe_ptr.h +++ b/CDS_test/safe_ptr.h @@ -350,19 +350,20 @@ namespace sf { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) { diff --git a/Real_app_bench/safe_ptr.h b/Real_app_bench/safe_ptr.h index 3437769..d5b15fb 100644 --- a/Real_app_bench/safe_ptr.h +++ b/Real_app_bench/safe_ptr.h @@ -350,19 +350,20 @@ namespace sf { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) { diff --git a/bench_contfree/main.cpp b/bench_contfree/main.cpp index 025d91d..4bf8c57 100644 --- a/bench_contfree/main.cpp +++ b/bench_contfree/main.cpp @@ -235,19 +235,20 @@ class contention_free_shared_mutex { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) { diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 3d0f71c..401b64f 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -331,19 +331,20 @@ class contention_free_shared_mutex { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) { diff --git a/contfree_shared_mutex/safe_ptr.h b/contfree_shared_mutex/safe_ptr.h index 478dcc8..69e51a2 100644 --- a/contfree_shared_mutex/safe_ptr.h +++ b/contfree_shared_mutex/safe_ptr.h @@ -93,19 +93,20 @@ namespace sf { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) { diff --git a/safe_ptr.h b/safe_ptr.h index 0b850d7..8d5b73e 100644 --- a/safe_ptr.h +++ b/safe_ptr.h @@ -350,19 +350,20 @@ namespace sf { int get_or_set_index(index_op_t index_op = get_index_op, int set_index = -1) { thread_local static std::unordered_map thread_local_index_hashmap; - // get thread index - in any cases - auto it = thread_local_index_hashmap.find(this); + // get thread index - in any cases. Use shared_locks_array_ptr as key ("this" may get recycled if contfree-mtx under "it" was deleted) + void *ptr = shared_locks_array_ptr.get(); + auto it = thread_local_index_hashmap.find(ptr); if (it != thread_local_index_hashmap.cend()) set_index = it->second.thread_index; if (index_op == unregister_thread_op) { // unregister thread if (shared_locks_array[set_index].value == 1) // if isn't shared_lock now - thread_local_index_hashmap.erase(this); + thread_local_index_hashmap.erase(ptr); else return -1; } else if (index_op == register_thread_op) { // register thread - thread_local_index_hashmap.emplace(this, unregister_t(set_index, shared_locks_array_ptr)); + thread_local_index_hashmap.emplace(ptr, unregister_t(set_index, shared_locks_array_ptr)); // remove info about deleted contfree-mutexes for (auto it = thread_local_index_hashmap.begin(), ite = thread_local_index_hashmap.end(); it != ite;) {