Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

mt_pooled_secure.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2018 The Dash Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_SUPPORT_ALLOCATORS_MT_POOLED_SECURE_H
6 #define BITCOIN_SUPPORT_ALLOCATORS_MT_POOLED_SECURE_H
7 
9 
10 #include <thread>
11 #include <mutex>
12 
13 //
14 // Manages a pool of pools to balance allocation between those when multiple threads are involved
15 // This allocator is fully thread safe
16 //
17 template <typename T>
18 struct mt_pooled_secure_allocator : public std::allocator<T> {
19  // MSVC8 default copy constructor is broken
20  typedef std::allocator<T> base;
21  typedef typename base::size_type size_type;
22  typedef typename base::difference_type difference_type;
23  typedef typename base::pointer pointer;
24  typedef typename base::const_pointer const_pointer;
25  typedef typename base::reference reference;
26  typedef typename base::const_reference const_reference;
27  typedef typename base::value_type value_type;
28  mt_pooled_secure_allocator(size_type nrequested_size = 32,
29  size_type nnext_size = 32,
30  size_type nmax_size = 0) noexcept
31  {
32  // we add enough bytes to the requested size so that we can store the bucket as well
33  nrequested_size += sizeof(size_t);
34 
35  size_t pools_count = std::thread::hardware_concurrency();
36  pools.resize(pools_count);
37  for (size_t i = 0; i < pools_count; i++) {
38  pools[i] = std::make_unique<internal_pool>(nrequested_size, nnext_size, nmax_size);
39  }
40  }
42 
43  T* allocate(std::size_t n, const void* hint = 0)
44  {
45  size_t bucket = get_bucket();
46  std::lock_guard<std::mutex> lock(pools[bucket]->mutex);
47  uint8_t* ptr = pools[bucket]->allocate(n * sizeof(T) + sizeof(size_t));
48  *(size_t*)ptr = bucket;
49  return static_cast<T*>(ptr + sizeof(size_t));
50  }
51 
52  void deallocate(T* p, std::size_t n)
53  {
54  if (!p) {
55  return;
56  }
57  uint8_t* ptr = (uint8_t*)p - sizeof(size_t);
58  size_t bucket = *(size_t*)ptr;
59  std::lock_guard<std::mutex> lock(pools[bucket]->mutex);
60  pools[bucket]->deallocate(ptr, n * sizeof(T));
61  }
62 
63 private:
64  size_t get_bucket()
65  {
66  auto tid = std::this_thread::get_id();
67  size_t x = std::hash<std::thread::id>{}(std::this_thread::get_id());
68  return x % pools.size();
69  }
70 
72  internal_pool(size_type nrequested_size,
73  size_type nnext_size,
74  size_type nmax_size) :
75  pooled_secure_allocator(nrequested_size, nnext_size, nmax_size)
76  {
77  }
78  std::mutex mutex;
79  };
80 
81 private:
82  std::vector<std::unique_ptr<internal_pool>> pools;
83 };
84 
85 #endif // BITCOIN_SUPPORT_ALLOCATORS_MT_POOLED_SECURE_H
mt_pooled_secure_allocator(size_type nrequested_size=32, size_type nnext_size=32, size_type nmax_size=0) noexcept
internal_pool(size_type nrequested_size, size_type nnext_size, size_type nmax_size)
std::vector< std::unique_ptr< internal_pool > > pools
std::size_t size_t
Definition: bits.hpp:21
std::allocator< T > base
void deallocate(T *p, std::size_t n)
base::const_pointer const_pointer
base::difference_type difference_type
T * allocate(std::size_t n, const void *hint=0)
base::const_reference const_reference
Released under the MIT license