Skip to content

Commit e98e7ba

Browse files
authored
non-constructing / huge paging allocators (#60)
1 parent 0a112d5 commit e98e7ba

File tree

11 files changed

+433
-135
lines changed

11 files changed

+433
-135
lines changed

.github/workflows/build_nix.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: ubuntu-latest
22

3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
5+
cancel-in-progress: true
6+
37
on:
48
push:
59
branches: [ master ]
@@ -16,4 +20,4 @@ jobs:
1620
run: |
1721
curl -Lo mkn https://github.com/mkn/mkn/releases/download/latest/mkn_nix
1822
chmod +x mkn
19-
KLOG=3 ./mkn clean build run -dtOp test -a "-std=c++17 -fPIC"
23+
KLOG=3 ./mkn clean build run -dtOp test -a "-std=c++20 -fPIC"

.github/workflows/build_osx.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: macos-latest
22

3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
5+
cancel-in-progress: true
6+
37
on:
48
push:
59
branches: [ master ]
@@ -16,4 +20,4 @@ jobs:
1620
run: |
1721
curl -Lo mkn https://github.com/mkn/mkn/releases/download/latest/mkn_arm_osx
1822
chmod +x mkn
19-
KLOG=3 ./mkn clean build run -dtOp test -a "-std=c++17 -fPIC"
23+
KLOG=3 ./mkn clean build run -dtOp test -a "-std=c++20 -fPIC"

.github/workflows/build_win.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: windows-latest
22

3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
5+
cancel-in-progress: true
6+
37
on:
48
push:
59
branches: [ master ]
@@ -23,4 +27,4 @@ jobs:
2327
run: | # /bin/link interferes with cl/link.exe
2428
bash -c "rm /bin/link"
2529
bash -c "curl -Lo mkn.exe https://github.com/mkn/mkn/releases/download/latest/mkn.exe"
26-
bash -c 'KLOG=3 ./mkn clean build run -dtKOp test -a "-EHsc -std:c++17"'
30+
bash -c 'KLOG=3 ./mkn clean build run -dtKOp test -a "-EHsc -std:c++20"'

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# mkn.kul
44

5-
**Cross platform C++ wrapper for threading/process management/io/logging/signal handling and stack walking.**
5+
**Cross platform C++20 wrapper for threading/process management/io/logging/signal handling and stack walking.**
66

77
Supported Architectures/Operating Systems:
88

inc/mkn/kul/alloc.hpp

+3-99
Original file line numberDiff line numberDiff line change
@@ -31,104 +31,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
#ifndef _MKN_KUL_ALLOC_HPP_
3232
#define _MKN_KUL_ALLOC_HPP_
3333

34-
#include <new>
35-
#include <cstdint>
36-
#include <cstddef>
37-
#include <cstdlib>
38-
#include <type_traits>
39-
40-
namespace mkn::kul {
41-
42-
template <typename T, std::int32_t alignment = 32>
43-
class AlignedAllocator {
44-
using This = AlignedAllocator<T, alignment>;
45-
46-
public:
47-
using pointer = T*;
48-
using reference = T&;
49-
using value_type = T;
50-
using size_type = std::size_t;
51-
using difference_type = std::ptrdiff_t;
52-
53-
template <typename U>
54-
struct rebind {
55-
using other = AlignedAllocator<U, alignment>;
56-
};
57-
58-
T* allocate(std::size_t const n) const {
59-
if (n == 0) return nullptr;
60-
61-
auto size = n * sizeof(T);
62-
std::uint32_t diff = size % alignment;
63-
if (diff > 0) diff = alignment - diff;
64-
65-
void* p = std::aligned_alloc(alignment, size + diff);
66-
if (!p) throw std::bad_alloc();
67-
68-
return static_cast<T*>(p);
69-
}
70-
71-
void deallocate(T* const p) noexcept {
72-
if (p) std::free(p);
73-
}
74-
void deallocate(T* const p, std::size_t /*n*/) noexcept { // needed from std::
75-
deallocate(p);
76-
}
77-
78-
bool operator!=(This const& that) const { return !(*this == that); }
79-
80-
bool operator==(This const& /*that*/) const {
81-
return true; // stateless
82-
}
83-
};
84-
85-
template <typename T>
86-
class Allocator {
87-
using This = Allocator<T>;
88-
89-
public:
90-
using pointer = T*;
91-
using reference = T&;
92-
using value_type = T;
93-
using size_type = std::size_t;
94-
using difference_type = std::ptrdiff_t;
95-
96-
template <typename U>
97-
struct rebind {
98-
using other = Allocator<U>;
99-
};
100-
101-
T* allocate(std::size_t const n) const {
102-
if (n == 0) return nullptr;
103-
return static_cast<T*>(::operator new(n * sizeof(T)));
104-
}
105-
106-
void deallocate(T* const p) noexcept {
107-
if (p) ::operator delete(p);
108-
}
109-
void deallocate(T* const p, std::size_t /*n*/) noexcept { // needed from std::
110-
if (p) ::operator delete(p);
111-
}
112-
bool operator!=(This const& that) const { return !(*this == that); }
113-
bool operator==(This const& /*that*/) const {
114-
return true; // stateless
115-
}
116-
};
117-
118-
template <typename T>
119-
class NonConstructingAllocator : public Allocator<T> {
120-
public:
121-
template <typename U>
122-
struct rebind {
123-
using other = NonConstructingAllocator<U>;
124-
};
125-
126-
template <typename U, typename... Args>
127-
void construct(U* /*ptr*/, Args&&... /*args*/) {} // nothing
128-
template <typename U>
129-
void construct(U* /*ptr*/) noexcept(std::is_nothrow_default_constructible<U>::value) {}
130-
};
131-
132-
} // namespace mkn::kul
34+
#include "mkn/kul/alloc/base.hpp"
35+
#include "mkn/kul/alloc/aligned.hpp" // active if available
36+
#include "mkn/kul/alloc/huge.hpp" // active if available
13337

13438
#endif /*_MKN_KUL_ALLOC_HPP_*/

inc/mkn/kul/alloc/aligned.hpp

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
Copyright (c) 2022, Philip Deegan.
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are
7+
met:
8+
9+
* Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following disclaimer
13+
in the documentation and/or other materials provided with the
14+
distribution.
15+
* Neither the name of Philip Deegan nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
#ifndef _MKN_KUL_ALLOC_ALIGNED_HPP_
32+
#define _MKN_KUL_ALLOC_ALIGNED_HPP_
33+
34+
#if __has_include(<sys/mman.h>)
35+
36+
#include "mkn/kul/alloc/base.hpp"
37+
38+
#include <new>
39+
#include <cstddef>
40+
#include <cstdlib>
41+
#include <type_traits>
42+
43+
namespace mkn::kul {
44+
45+
template <typename T, std::int32_t alignment = 32>
46+
class AlignedAllocator : public Allocator<T> {
47+
using This = AlignedAllocator<T, alignment>;
48+
49+
public:
50+
using pointer = T*;
51+
using reference = T&;
52+
using value_type = T;
53+
using size_type = std::size_t;
54+
using difference_type = std::ptrdiff_t;
55+
56+
template <typename U>
57+
struct rebind {
58+
using other = AlignedAllocator<U, alignment>;
59+
};
60+
61+
T* allocate(std::size_t const n) const {
62+
if (n == 0) return nullptr;
63+
64+
auto size = n * sizeof(T);
65+
std::uint32_t diff = size % alignment;
66+
if (diff > 0) diff = alignment - diff;
67+
68+
void* p = std::aligned_alloc(alignment, size + diff);
69+
if (!p) throw std::bad_alloc();
70+
71+
return static_cast<T*>(p);
72+
}
73+
74+
void deallocate(T* const p) noexcept {
75+
if (p) std::free(p);
76+
}
77+
void deallocate(T* const p, std::size_t /*n*/) noexcept { // needed from std::
78+
deallocate(p);
79+
}
80+
81+
bool operator!=(This const& that) const { return !(*this == that); }
82+
83+
bool operator==(This const& /*that*/) const {
84+
return true; // stateless
85+
}
86+
};
87+
88+
} // namespace mkn::kul
89+
90+
#endif // __has_include(<sys/mman.h>)
91+
92+
#endif /*_MKN_KUL_ALLOC_ALIGNED_HPP_*/

inc/mkn/kul/alloc/base.hpp

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
Copyright (c) 2022, Philip Deegan.
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are
7+
met:
8+
9+
* Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following disclaimer
13+
in the documentation and/or other materials provided with the
14+
distribution.
15+
* Neither the name of Philip Deegan nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
#ifndef _MKN_KUL_ALLOC_BASE_HPP_
32+
#define _MKN_KUL_ALLOC_BASE_HPP_
33+
34+
#include <new>
35+
#include <cstdint>
36+
#include <cstddef>
37+
#include <cstdlib>
38+
#include <type_traits>
39+
40+
namespace mkn::kul {
41+
42+
template <typename T>
43+
class Allocator {
44+
using This = Allocator<T>;
45+
46+
public:
47+
using pointer = T*;
48+
using reference = T&;
49+
using value_type = T;
50+
using size_type = std::size_t;
51+
using difference_type = std::ptrdiff_t;
52+
53+
template <typename U>
54+
struct rebind {
55+
using other = Allocator<U>;
56+
};
57+
58+
T* allocate(std::size_t const n) const { return static_cast<T*>(::operator new(n * sizeof(T))); }
59+
60+
void deallocate(T* const p) noexcept {
61+
if (p) ::operator delete(p);
62+
}
63+
void deallocate(T* const p, std::size_t /*n*/) noexcept { // needed from std::
64+
if (p) ::operator delete(p);
65+
}
66+
bool operator!=(This const& that) const { return !(*this == that); }
67+
bool operator==(This const& /*that*/) const {
68+
return true; // stateless
69+
}
70+
};
71+
72+
template <typename T>
73+
class NonConstructingAllocator : public Allocator<T> {
74+
using This = NonConstructingAllocator<T>;
75+
76+
public:
77+
template <typename U>
78+
struct rebind {
79+
using other = NonConstructingAllocator<U>;
80+
};
81+
82+
T* allocate(std::size_t const n) const {
83+
// if (n == 0) return nullptr;
84+
return static_cast<T*>(malloc(n * sizeof(T)));
85+
}
86+
87+
template <typename U, typename... Args>
88+
void construct(U* ptr, Args&&... args) {
89+
::new ((void*)ptr) U(std::forward<Args>(args)...);
90+
}
91+
92+
template <typename U>
93+
void construct(U* /*ptr*/) noexcept(std::is_nothrow_default_constructible<U>::value) {}
94+
95+
bool operator!=(This const& that) const { return !(*this == that); }
96+
bool operator==(This const& /*that*/) const {
97+
return true; // stateless
98+
}
99+
};
100+
101+
} // namespace mkn::kul
102+
103+
#endif /*_MKN_KUL_ALLOC_BASE_HPP_*/

0 commit comments

Comments
 (0)