[libcxx-commits] [libcxx] [libc++] Adds shared resource helper. (PR #72529)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 5 09:52:12 PST 2023


================
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <map>
+#include <mutex>
+#include <shared_mutex>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class __shared_resource {
+public:
+  _LIBCPP_HIDE_FROM_ABI __shared_resource()              = default;
+  __shared_resource(const __shared_resource&)            = delete;
+  __shared_resource& operator=(const __shared_resource&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI mutex& __inc_reference(const void* __ptr) {
+    _LIBCPP_ASSERT_NON_NULL(__ptr != nullptr, "not a valid resource");
+    unique_lock __lock{__mutex_};
+
+    auto& __resource = __lut_[reinterpret_cast<uintptr_t>(__ptr)];
+    ++__resource.__count;
+    return __resource.__mutex;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void __dec_reference(const void* __ptr) {
+    unique_lock __lock{__mutex_};
+
+    auto __it = __get_it(__ptr);
+    if (__it->second.__count == 1)
+      __lut_.erase(__it);
+    else
+      --__it->second.__count;
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI lock_guard<mutex> __get_lock(const void* __ptr) {
+    shared_lock __lock{__mutex_};
+    return lock_guard{__get_it(__ptr)->second.__mutex};
+  }
+
+  [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI __shared_resource& __instance() {
+    static __shared_resource __result;
+    return __result;
+  }
+
+private:
+  struct __value {
+    mutex __mutex;
+    size_t __count{0};
+  };
+
+  shared_mutex __mutex_;
+  map<uintptr_t, __value> __lut_;
----------------
ldionne wrote:

`map` is rarely the best way of storing data. I would suggest either using `unordered_map` or implementing a simple hash table for internal use only. Maybe `unordered_map` is easiest for now, especially since we can change it however we want since it's just in the dylib.

https://github.com/llvm/llvm-project/pull/72529


More information about the libcxx-commits mailing list