[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:11 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 {
----------------
ldionne wrote:
@huixie90
I think there are many similarities with what we do in `stop_token` here. This is basically a ref-counted mutex, and that's very close to what we do with `__intrusive_shared_ptr` and `__atomic_unique_lock` in the `stop_token` implementation. I wonder whether it would make sense to reuse some of that work here. In particular, we know for sure that `std::map` + `std::mutex` is probably not the best way of implementing the storage for this, so perhaps we can do something clever by using a slightly different data structure.
I'd be curious if you have thoughts about this.
https://github.com/llvm/llvm-project/pull/72529
More information about the libcxx-commits
mailing list