cpp-msgpack-rpc
0.2.0
An RPC library implementing MessagePack RPC.
Toggle main menu visibility
Loading...
Searching...
No Matches
sharable_binary_header.h
Go to the documentation of this file.
1
/*
2
* Copyright 2024 MusicScience37 (Kenta Kabashima)
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
20
#pragma once
21
22
#include <atomic>
23
#include <cassert>
24
#include <cstddef>
25
#include <cstdlib>
26
#include <limits>
27
#include <new>
28
29
#include "
msgpack_rpc/messages/impl/sharable_binary_header_fwd.h
"
// IWYU pragma: keep
30
31
namespace
msgpack_rpc::messages::impl
{
32
36
struct
SharableBinaryHeader
{
37
public
:
39
std::size_t
total_memory_size
;
40
42
std::size_t
binary_size
;
43
45
std::size_t
binary_capacity
;
46
48
alignas
(
alignof
(std::atomic<int>))
// NOLINTNEXTLINE
49
char
reference_count_buffer
[
sizeof
(std::atomic<int>)];
50
52
bool
is_reference_count_enabled
;
53
};
54
56
constexpr
std::size_t
SHARABLE_BINARY_ALIGNMENT
=
alignof
(
SharableBinaryHeader
);
57
58
// Assumption to use std::malloc, std::realloc, std::free.
59
static_assert
(
SHARABLE_BINARY_ALIGNMENT
<=
alignof
(std::max_align_t));
60
67
[[nodiscard]]
inline
SharableBinaryHeader
*
allocate_sharable_binary
(
68
std::size_t binary_size) {
69
constexpr
std::size_t header_size =
sizeof
(
SharableBinaryHeader
);
70
const
std::size_t total_memory_size = header_size + binary_size;
71
72
void
* raw_ptr = std::malloc(total_memory_size);
// NOLINT(*-no-malloc)
73
if
(raw_ptr ==
nullptr
) {
74
// Since memory allocation has failed, the class of exceptions with
75
// memory allocation like MsgpackRPCException cannot be used.
76
throw
std::bad_alloc();
77
}
78
79
auto
* ptr =
static_cast<
SharableBinaryHeader
*
>
(raw_ptr);
80
ptr->
total_memory_size
= total_memory_size;
81
ptr->binary_size = binary_size;
82
ptr->binary_capacity = binary_size;
83
ptr->is_reference_count_enabled =
false
;
84
85
return
ptr;
86
}
87
93
[[nodiscard]]
inline
SharableBinaryHeader
*
allocate_shared_binary
() {
94
constexpr
std::size_t header_size =
sizeof
(
SharableBinaryHeader
);
95
// This value is not tuned.
96
constexpr
std::size_t total_memory_size = 128;
97
static_assert
(total_memory_size > header_size);
98
99
void
* raw_ptr = std::malloc(total_memory_size);
// NOLINT(*-no-malloc)
100
if
(raw_ptr ==
nullptr
) {
101
// Since memory allocation has failed, the class of exceptions with
102
// memory allocation like MsgpackRPCException cannot be used.
103
throw
std::bad_alloc();
104
}
105
106
auto
* ptr =
static_cast<
SharableBinaryHeader
*
>
(raw_ptr);
107
ptr->
total_memory_size
= total_memory_size;
108
ptr->binary_size = 0U;
109
ptr->binary_capacity = total_memory_size - header_size;
110
ptr->is_reference_count_enabled =
false
;
111
112
return
ptr;
113
}
114
122
[[nodiscard]]
inline
SharableBinaryHeader
*
expand_sharable_binary
(
123
SharableBinaryHeader
* buffer, std::size_t required_size) {
124
// std::realloc is not safe when reference count (use of std::atomic<int>)
125
// is enabled.
126
assert(!buffer->
is_reference_count_enabled
);
127
128
std::size_t new_capacity = buffer->
binary_capacity
;
129
while
(
true
) {
130
// TODO Prevent overflow.
131
new_capacity <<= 1U;
132
if
(new_capacity >= required_size) {
133
break
;
134
}
135
}
136
constexpr
std::size_t header_size =
sizeof
(
SharableBinaryHeader
);
137
const
std::size_t new_total_memory_size = header_size + new_capacity;
138
139
void
* raw_ptr =
140
std::realloc(buffer, new_total_memory_size);
// NOLINT(*-no-malloc)
141
if
(raw_ptr ==
nullptr
) {
142
// Since memory allocation has failed, the class of exceptions with
143
// memory allocation like MsgpackRPCException cannot be used.
144
throw
std::bad_alloc();
145
}
146
147
auto
* ptr =
static_cast<
SharableBinaryHeader
*
>
(raw_ptr);
148
ptr->
total_memory_size
= new_total_memory_size;
149
ptr->binary_capacity = new_total_memory_size - header_size;
150
151
return
ptr;
152
}
153
160
[[nodiscard]]
inline
std::atomic<int>&
reference_count_of
(
161
SharableBinaryHeader
* buffer)
noexcept
{
162
assert(buffer->is_reference_count_enabled);
163
// NOLINTNEXTLINE(*-reinterpret-cast)
164
return
*
reinterpret_cast<
std::atomic<int>*
>
(buffer->reference_count_buffer);
165
}
166
172
inline
void
deallocate_sharable_binary
(
SharableBinaryHeader
* buffer)
noexcept
{
173
if
(buffer ==
nullptr
) {
174
return
;
175
}
176
if
(buffer->is_reference_count_enabled) {
177
using
AtomicType = std::atomic<int>;
178
reference_count_of
(buffer).~AtomicType();
179
}
180
std::free(buffer);
// NOLINT(*-no-malloc)
181
}
182
188
inline
void
enable_reference_count_of_sharable_binary
(
189
SharableBinaryHeader
* buffer)
noexcept
{
190
assert(!buffer->is_reference_count_enabled);
191
new
(
static_cast<
void
*
>
(buffer->reference_count_buffer))
192
std::atomic<int>(1);
193
buffer->is_reference_count_enabled =
true
;
194
}
195
201
inline
void
add_reference_count_of_sharable_binary
(
202
SharableBinaryHeader
* buffer)
noexcept
{
203
reference_count_of
(buffer).fetch_add(1, std::memory_order_relaxed);
204
}
205
212
inline
void
decrease_reference_count_of_sharable_binary
(
213
SharableBinaryHeader
* buffer)
noexcept
{
214
const
int
reference_count_before =
215
reference_count_of
(buffer).fetch_sub(1, std::memory_order_acq_rel);
216
if
(reference_count_before == 1) {
217
deallocate_sharable_binary
(buffer);
218
}
219
}
220
227
inline
char
*
binary_buffer_of
(
SharableBinaryHeader
* buffer)
noexcept
{
228
// NOLINTNEXTLINE
229
return
reinterpret_cast<
char
*
>
(buffer) +
sizeof
(
SharableBinaryHeader
);
230
}
231
232
}
// namespace msgpack_rpc::messages::impl
msgpack_rpc::messages::impl
Namespace of internal implementations.
Definition
serialization_buffer.h:28
msgpack_rpc::messages::impl::decrease_reference_count_of_sharable_binary
void decrease_reference_count_of_sharable_binary(SharableBinaryHeader *buffer) noexcept
Decrease a reference count of a buffer of sharable binary data, and deallocate the buffer if possible...
Definition
sharable_binary_header.h:212
msgpack_rpc::messages::impl::binary_buffer_of
char * binary_buffer_of(SharableBinaryHeader *buffer) noexcept
Get buffer of binary data from a buffer of sharable binary data.
Definition
sharable_binary_header.h:227
msgpack_rpc::messages::impl::expand_sharable_binary
SharableBinaryHeader * expand_sharable_binary(SharableBinaryHeader *buffer, std::size_t required_size)
Expand a buffer of sharable binary data.
Definition
sharable_binary_header.h:122
msgpack_rpc::messages::impl::add_reference_count_of_sharable_binary
void add_reference_count_of_sharable_binary(SharableBinaryHeader *buffer) noexcept
Add a reference count of a buffer of sharable binary data.
Definition
sharable_binary_header.h:201
msgpack_rpc::messages::impl::SHARABLE_BINARY_ALIGNMENT
constexpr std::size_t SHARABLE_BINARY_ALIGNMENT
Alignment of sharable binary data.
Definition
sharable_binary_header.h:56
msgpack_rpc::messages::impl::deallocate_sharable_binary
void deallocate_sharable_binary(SharableBinaryHeader *buffer) noexcept
Deallocate a buffer of sharable binary data.
Definition
sharable_binary_header.h:172
msgpack_rpc::messages::impl::reference_count_of
std::atomic< int > & reference_count_of(SharableBinaryHeader *buffer) noexcept
Access the reference count of a buffer of sharable binary data.
Definition
sharable_binary_header.h:160
msgpack_rpc::messages::impl::allocate_shared_binary
SharableBinaryHeader * allocate_shared_binary()
Allocate a buffer of sharable binary data with automatic initial size.
Definition
sharable_binary_header.h:93
msgpack_rpc::messages::impl::enable_reference_count_of_sharable_binary
void enable_reference_count_of_sharable_binary(SharableBinaryHeader *buffer) noexcept
Enable reference count of a buffer of sharable binary data.
Definition
sharable_binary_header.h:188
msgpack_rpc::messages::impl::allocate_sharable_binary
SharableBinaryHeader * allocate_sharable_binary(std::size_t binary_size)
Allocate a buffer of sharable binary data.
Definition
sharable_binary_header.h:67
sharable_binary_header_fwd.h
Declaration of SharableBinaryHeader struct.
msgpack_rpc::messages::impl::SharableBinaryHeader
Struct of headers of sharable binary data.
Definition
sharable_binary_header.h:36
msgpack_rpc::messages::impl::SharableBinaryHeader::binary_size
std::size_t binary_size
Size of the binary data.
Definition
sharable_binary_header.h:42
msgpack_rpc::messages::impl::SharableBinaryHeader::binary_capacity
std::size_t binary_capacity
Capacity of the binary data.
Definition
sharable_binary_header.h:45
msgpack_rpc::messages::impl::SharableBinaryHeader::total_memory_size
std::size_t total_memory_size
Total size of the memory buffer allocated for the binary data.
Definition
sharable_binary_header.h:39
msgpack_rpc::messages::impl::SharableBinaryHeader::is_reference_count_enabled
bool is_reference_count_enabled
Whether reference count is enabled.
Definition
sharable_binary_header.h:52
msgpack_rpc::messages::impl::SharableBinaryHeader::reference_count_buffer
char reference_count_buffer[sizeof(std::atomic< int >)]
Buffer of the object of reference count.
Definition
sharable_binary_header.h:49
src
msgpack_rpc
messages
impl
sharable_binary_header.h
Generated on
for cpp-msgpack-rpc by
1.18.0