1bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric //
7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric 
9bdd1243dSDimitry Andric #ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
10bdd1243dSDimitry Andric #define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
11bdd1243dSDimitry Andric 
12*06c3fb27SDimitry Andric #include <__availability>
13bdd1243dSDimitry Andric #include <__config>
14bdd1243dSDimitry Andric #include <__memory_resource/memory_resource.h>
15bdd1243dSDimitry Andric #include <__memory_resource/pool_options.h>
16bdd1243dSDimitry Andric #include <__memory_resource/unsynchronized_pool_resource.h>
17bdd1243dSDimitry Andric #include <cstddef>
18bdd1243dSDimitry Andric #include <mutex>
19bdd1243dSDimitry Andric 
20bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21bdd1243dSDimitry Andric #  pragma GCC system_header
22bdd1243dSDimitry Andric #endif
23bdd1243dSDimitry Andric 
24*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17
25bdd1243dSDimitry Andric 
26bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
27bdd1243dSDimitry Andric 
28bdd1243dSDimitry Andric namespace pmr {
29bdd1243dSDimitry Andric 
30bdd1243dSDimitry Andric // [mem.res.pool.overview]
31bdd1243dSDimitry Andric 
32*06c3fb27SDimitry Andric class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI synchronized_pool_resource : public memory_resource {
33bdd1243dSDimitry Andric public:
synchronized_pool_resource(const pool_options & __opts,memory_resource * __upstream)34bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream)
35bdd1243dSDimitry Andric       : __unsync_(__opts, __upstream) {}
36bdd1243dSDimitry Andric 
synchronized_pool_resource()37bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource()
38bdd1243dSDimitry Andric       : synchronized_pool_resource(pool_options(), get_default_resource()) {}
39bdd1243dSDimitry Andric 
synchronized_pool_resource(memory_resource * __upstream)40bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit synchronized_pool_resource(memory_resource* __upstream)
41bdd1243dSDimitry Andric       : synchronized_pool_resource(pool_options(), __upstream) {}
42bdd1243dSDimitry Andric 
synchronized_pool_resource(const pool_options & __opts)43bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit synchronized_pool_resource(const pool_options& __opts)
44bdd1243dSDimitry Andric       : synchronized_pool_resource(__opts, get_default_resource()) {}
45bdd1243dSDimitry Andric 
46bdd1243dSDimitry Andric   synchronized_pool_resource(const synchronized_pool_resource&) = delete;
47bdd1243dSDimitry Andric 
48*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~synchronized_pool_resource() override = default;
49bdd1243dSDimitry Andric 
50bdd1243dSDimitry Andric   synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;
51bdd1243dSDimitry Andric 
release()52bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void release() {
53bdd1243dSDimitry Andric #  if !defined(_LIBCPP_HAS_NO_THREADS)
54bdd1243dSDimitry Andric     unique_lock<mutex> __lk(__mut_);
55bdd1243dSDimitry Andric #  endif
56bdd1243dSDimitry Andric     __unsync_.release();
57bdd1243dSDimitry Andric   }
58bdd1243dSDimitry Andric 
upstream_resource()59bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __unsync_.upstream_resource(); }
60bdd1243dSDimitry Andric 
options()61bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI pool_options options() const { return __unsync_.options(); }
62bdd1243dSDimitry Andric 
63bdd1243dSDimitry Andric protected:
do_allocate(size_t __bytes,size_t __align)64bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void* do_allocate(size_t __bytes, size_t __align) override {
65bdd1243dSDimitry Andric #  if !defined(_LIBCPP_HAS_NO_THREADS)
66bdd1243dSDimitry Andric     unique_lock<mutex> __lk(__mut_);
67bdd1243dSDimitry Andric #  endif
68bdd1243dSDimitry Andric     return __unsync_.allocate(__bytes, __align);
69bdd1243dSDimitry Andric   }
70bdd1243dSDimitry Andric 
do_deallocate(void * __p,size_t __bytes,size_t __align)71bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void* __p, size_t __bytes, size_t __align) override {
72bdd1243dSDimitry Andric #  if !defined(_LIBCPP_HAS_NO_THREADS)
73bdd1243dSDimitry Andric     unique_lock<mutex> __lk(__mut_);
74bdd1243dSDimitry Andric #  endif
75bdd1243dSDimitry Andric     return __unsync_.deallocate(__p, __bytes, __align);
76bdd1243dSDimitry Andric   }
77bdd1243dSDimitry Andric 
78bdd1243dSDimitry Andric   bool do_is_equal(const memory_resource& __other) const noexcept override; // key function
79bdd1243dSDimitry Andric 
80bdd1243dSDimitry Andric private:
81bdd1243dSDimitry Andric #  if !defined(_LIBCPP_HAS_NO_THREADS)
82bdd1243dSDimitry Andric   mutex __mut_;
83bdd1243dSDimitry Andric #  endif
84bdd1243dSDimitry Andric   unsynchronized_pool_resource __unsync_;
85bdd1243dSDimitry Andric };
86bdd1243dSDimitry Andric 
87bdd1243dSDimitry Andric } // namespace pmr
88bdd1243dSDimitry Andric 
89bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
90bdd1243dSDimitry Andric 
91*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 17
92bdd1243dSDimitry Andric 
93bdd1243dSDimitry Andric #endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
94