Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
memory.hh
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#ifndef __ASE_MEMORY_HH__
3#define __ASE_MEMORY_HH__
4
5#include <ase/utils.hh>
6
7namespace Ase {
8
10namespace FastMemory {
11
13inline constexpr size_t cache_line_size = 64;
14
15} // FastMemory
16
17// Allocate cache-line aligned memory block from fast memory pool, MT-Safe.
18void* fast_mem_alloc (size_t size);
19// Free a memory block allocated with aligned_malloc(), MT-Safe.
20void fast_mem_free (void *mem);
21
23template<typename T, size_t ALIGNMENT = FastMemory::cache_line_size>
26 static_assert (ALIGNMENT <= FastMemory::cache_line_size);
27 static_assert ((ALIGNMENT & (ALIGNMENT - 1)) == 0);
28 static_assert (alignof (T) <= ALIGNMENT);
29 const size_t n_elements_ = 0;
30 T *const data_ = nullptr;
32protected:
33 void range_check (size_t n) const
34 {
35 if (n >= n_elements_)
36 throw std::out_of_range (string_format ("FastMemArray::range_check: n >= size(): %u >= %u", n, size()));
37 }
38public:
39 FastMemArray (size_t n_elements) :
40 n_elements_ (n_elements),
41 data_ ((T*) fast_mem_alloc (sizeof (T) * n_elements_))
42 {
43 std::fill (begin(), end(), T());
44 }
45 FastMemArray (const std::vector<T>& elements) :
46 n_elements_ (elements.size()),
47 data_ ((T*) fast_mem_alloc (sizeof (T) * n_elements_))
48 {
49 std::copy (elements.begin(), elements.end(), begin());
50 }
52 {
54 fast_mem_free (data_);
55 }
56 T* begin () { return &data_[0]; }
57 T* end () { return &data_[n_elements_]; }
58 size_t size () const { return n_elements_; }
59 T& operator[] (size_t n) { return data_[n]; }
60 const T& operator[] (size_t n) const { return data_[n]; }
61 T& at (size_t n) { range_check (n); return data_[n]; }
62 const T& at (size_t n) const { range_check (n); return data_[n]; }
63};
64
65namespace FastMemory {
66
67// == NewDeleteBase ==
69 static constexpr const std::align_val_t __cxxalignment = std::align_val_t (__STDCPP_DEFAULT_NEW_ALIGNMENT__);
70 static void delete_ (void *ptr, std::size_t sz, std::align_val_t al);
71 static void* new_ (std::size_t sz, std::align_val_t al);
72public:
73 // 'static' is implicit for operator new/delete
74 void* operator new (std::size_t sz) { return new_ (sz, __cxxalignment); }
75 void* operator new[] (std::size_t sz) { return new_ (sz, __cxxalignment); }
76 void* operator new (std::size_t sz, std::align_val_t al) { return new_ (sz, al); }
77 void* operator new[] (std::size_t sz, std::align_val_t al) { return new_ (sz, al); }
78 // variants without size_t MUST NOT be defined for the following to be used
79 void operator delete (void *ptr, std::size_t sz) { delete_ (ptr, sz, __cxxalignment); }
80 void operator delete[] (void *ptr, std::size_t sz) { delete_ (ptr, sz, __cxxalignment); }
81 void operator delete (void *ptr, std::size_t sz, std::align_val_t al) { delete_ (ptr, sz, al); }
82 void operator delete[] (void *ptr, std::size_t sz, std::align_val_t al) { delete_ (ptr, sz, al); }
83};
84
86struct Allocator;
88
90struct Block {
91 void *const block_start = nullptr;
92 const uint32 block_length = 0;
93 Block& operator= (const Block &src) { this->~Block(); new (this) Block (src); return *this; }
94 /*ctor*/ Block (void *b, uint32 l) : block_start (b), block_length (l) {}
95 /*copy*/ Block (const Block &src) = default;
96 /*dflt*/ Block () = default;
97};
98
100struct Arena {
102 explicit Arena (uint32 mem_size, uint32 alignment = cache_line_size);
104 size_t alignment () const;
106 uint64 location () const;
108 uint64 reserved () const;
110 Block allocate (uint32 length) const;
111 Block allocate (uint32 length, std::nothrow_t) const;
113 void release (Block allocatedblock) const;
114protected:
115 explicit Arena (AllocatorP);
117};
118
120struct HugePage {
123 size_t alignment () const { return start_ ? size_t (1) << __builtin_ctz (size_t (start_)) : 0; }
124 size_t size () const { return size_; }
125 char* mem () const { return (char*) start_; }
126 static HugePageP allocate (size_t minimum_alignment, size_t bytelength);
127protected:
128 void *const start_;
129 const size_t size_;
130 explicit HugePage (void *m, size_t s);
131 virtual ~HugePage () {}
132};
133using HugePageP = HugePage::HugePageP;
134
135} // FastMemory
136
138class CString final {
139 uint quark_ = 0;
140 constexpr void qset (uint quark) noexcept { quark_ = quark; }
141public:
142 using size_type = std::string::size_type;
143 using const_iterator = std::string::const_iterator;
144 using const_reference = std::string::const_reference;
145 using const_reverse_iterator = std::string::const_reverse_iterator;
146 /*dtor*/ ~CString () noexcept { qset (0); }
147 /*ctor*/ CString (const char *c) { assign (c); }
148 /*ctor*/ CString (const char *c, size_type s) { assign (c, s); }
149 /*ctor*/ CString (const std::string &s) { assign (s); }
150 /*ctor*/ constexpr CString () noexcept = default;
151 /*copy*/ constexpr CString (const CString &c) noexcept { assign (c); }
152 /*move*/ constexpr CString (CString &&c) noexcept { assign (c); }
153 constexpr CString& operator= (const CString &c) noexcept { return assign (c); }
154 constexpr CString& operator= (CString &&c) noexcept { return assign (c); }
155 CString& operator= (const std::string &s) noexcept { return assign (s); }
156 CString& operator= (const char *c) noexcept { return assign (c); }
157 CString& operator= (char ch) noexcept { return assign (std::addressof (ch), 1); }
158 CString& operator= (std::initializer_list<char> l) { return assign (l.begin(), l.size()); }
159 constexpr CString& assign (const CString &c) noexcept { qset (c.quark_); return *this; }
160 CString& assign (const std::string &s) noexcept;
161 CString& assign (const char *c, size_type s) { return assign (std::string (c, s)); }
162 CString& assign (const char *c) noexcept { return assign (std::string (c)); }
163 CString& assign (size_type count, char ch) noexcept { return this->operator= (std::string (count, ch)); }
164 const std::string& string () const;
165 const char* c_str () const noexcept { return string().c_str(); }
166 const char* data () const noexcept { return string().data(); }
167 const_reference at (size_type pos) const { return string().at (pos); }
168 const_reference operator[] (size_type pos) const { return string().operator[] (pos); }
169 size_type capacity () const noexcept { return string().capacity(); }
170 size_type length () const noexcept { return string().length(); }
171 bool empty () const noexcept { return string().empty(); }
172 size_type size () const noexcept { return string().size(); }
173 const_iterator begin () const noexcept { return string().begin(); }
174 const_iterator cbegin () const noexcept { return string().cbegin(); }
175 const_iterator end () const noexcept { return string().end(); }
176 const_iterator cend () const noexcept { return string().cend(); }
177 const_reverse_iterator rbegin () const noexcept { return string().rbegin(); }
178 const_reverse_iterator crbegin () const noexcept { return string().crbegin(); }
179 const_reverse_iterator rend () const noexcept { return string().rend(); }
180 const_reverse_iterator crend () const noexcept { return string().crend(); }
181 /*conv*/ operator std::string () const noexcept { return string(); }
182 friend bool operator== (CString a, CString b) { return a.quark_ == b.quark_; }
183 friend bool operator== (CString a, const std::string &b) { return a.string() == b; }
184 friend bool operator== (const std::string &a, CString b) { return a == b.string(); }
185 friend bool operator== (CString a, const char *b) { return a.string() == b; }
186 friend bool operator== (const char *a, CString b) { return a == b.string(); }
187 friend std::strong_ordering operator<=> (CString a, CString b) { return a.string() <=> b.string(); }
188 friend std::strong_ordering operator<=> (CString a, const String &b) { return a.string() <=> b; }
189 friend std::strong_ordering operator<=> (const String &a, CString b) { return a <=> b.string(); }
190 friend std::strong_ordering operator<=> (CString a, const char *b) { return a.string() <=> b; }
191 friend std::strong_ordering operator<=> (const char *a, CString b) { return a <=> b.string(); }
192 friend std::string operator+ (const std::string &s, CString c) { return s + c.string(); }
193 friend std::string operator+ (CString c, const std::string &s) { return c.string() + s; }
194 static CString lookup (const std::string &s);
195 static uint temp_quark_impl (CString c);
196 static CString temp_quark_impl (uint maybequark);
197 friend std::ostream& operator<< (std::ostream &os, CString c) { os << c.string(); return os; }
198 static constexpr const std::string::size_type npos = -1;
199};
201
202} // Ase
203
204namespace std {
205template<>
208 size_t
209 operator() (const ::Ase::CString &cs) const
210 {
211 return ::std::hash<::std::string>{} (cs.string());
212 }
213};
214} // std
215
216#endif /* __ASE_MEMORY_HH__ */
T addressof(T... args)
T at(T... args)
T begin(T... args)
T c_str(T... args)
T capacity(T... args)
Compact, deduplicating string variant for constant strings.
Definition memory.hh:138
static CString lookup(const std::string &s)
Definition memory.cc:631
const std::string & string() const
Convert CString into a std::string.
Definition memory.cc:640
Array with cache-line-alignment containing a fixed numer of PODs.
Definition memory.hh:24
T copy(T... args)
#define ASE_CLASS_NON_COPYABLE(ClassName)
Delete copy ctor and assignment operator.
Definition cxxaux.hh:106
T data(T... args)
T empty(T... args)
T end(T... args)
T fill(T... args)
constexpr size_t cache_line_size
Minimum alignment >= cache line size, see getconf LEVEL1_DCACHE_LINESIZE.
Definition memory.hh:13
The Anklang C++ API namespace.
Definition api.hh:9
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:25
uint32_t uint32
A 32-bit unsigned integer.
Definition cxxaux.hh:24
uint32_t uint
Provide 'uint' as convenience type.
Definition cxxaux.hh:18
T operator()(T... args)
T rbegin(T... args)
T rend(T... args)
T length(T... args)
Memory area (over-)aligned to cache size and utilizing huge pages.
Definition memory.hh:100
uint64 location() const
Address of memory area.
Definition memory.cc:340
size_t alignment() const
Alignment for block addresses and length.
Definition memory.cc:352
uint64 reserved() const
Reserved memory area in bytes.
Definition memory.cc:346
Block allocate(uint32 length) const
Create a memory block from cache-line aligned memory area, MT-Unsafe.
Definition memory.cc:371
void release(Block allocatedblock) const
Realease a previously allocated block, MT-Unsafe.
Definition memory.cc:380
AllocatorP fma
Identifier for the associated memory allocator.
Definition memory.hh:116
Reference for an allocated memory block.
Definition memory.hh:90
Interface to the OS huge page allocator.
Definition memory.hh:120
char * mem() const
Allocated memroy area.
Definition memory.hh:125
size_t alignment() const
Alignment of the memory area.
Definition memory.hh:123
static HugePageP allocate(size_t minimum_alignment, size_t bytelength)
Try to allocate a HugePage >= bytelength with minimum_alignment, usual sizes are 2MB.
Definition memory.cc:52
size_t size() const
Size in bytes of the memroy area.
Definition memory.hh:124
typedef size_t