PyCyBase 0.1.8.post4__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cbase/__infra__.pxd +6 -0
- cbase/__init__.pxd +6 -0
- cbase/__init__.py +28 -0
- cbase/allocator_protocol/__infra__.pxd +58 -0
- cbase/allocator_protocol/__init__.pxd +58 -0
- cbase/allocator_protocol/__init__.py +45 -0
- cbase/allocator_protocol/c_allocator_protocol.c +31818 -0
- cbase/allocator_protocol/c_allocator_protocol.cp313-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_allocator_protocol.h +352 -0
- cbase/allocator_protocol/c_allocator_protocol.pxd +64 -0
- cbase/allocator_protocol/c_allocator_protocol.pyi +144 -0
- cbase/allocator_protocol/c_allocator_protocol.pyx +209 -0
- cbase/allocator_protocol/c_heap_allocator.c +38144 -0
- cbase/allocator_protocol/c_heap_allocator.cp313-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_heap_allocator.h +444 -0
- cbase/allocator_protocol/c_heap_allocator.pxd +97 -0
- cbase/allocator_protocol/c_heap_allocator.pyi +161 -0
- cbase/allocator_protocol/c_heap_allocator.pyx +300 -0
- cbase/allocator_protocol/c_nt_shm_allocator.c +33399 -0
- cbase/allocator_protocol/c_nt_shm_allocator.cp313-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_nt_shm_allocator.h +996 -0
- cbase/allocator_protocol/c_nt_shm_allocator.pxd +102 -0
- cbase/allocator_protocol/c_nt_shm_allocator.pyx +223 -0
- cbase/allocator_protocol/c_shm_allocator.h +1168 -0
- cbase/allocator_protocol/c_shm_allocator.pxd +142 -0
- cbase/allocator_protocol/c_shm_allocator.pyi +299 -0
- cbase/allocator_protocol/c_shm_allocator.pyx +442 -0
- cbase/allocator_protocol/c_shm_comp.c +4643 -0
- cbase/allocator_protocol/c_shm_comp.cp313-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_shm_comp.h +49 -0
- cbase/allocator_protocol/c_shm_comp.pxd +38 -0
- cbase/allocator_protocol/c_shm_comp.pyx +1 -0
- cbase/backports/__infra__.pxd +17 -0
- cbase/backports/__init__.pxd +17 -0
- cbase/backports/__init__.py +9 -0
- cbase/backports/pydict.h +55 -0
- cbase/backports/pydict.pxd +5 -0
- cbase/backports/pylong.c +9946 -0
- cbase/backports/pylong.cp313-win_amd64.pyd +0 -0
- cbase/backports/pylong.h +79 -0
- cbase/backports/pylong.pxd +23 -0
- cbase/backports/pylong.pyx +61 -0
- cbase/bytemap/__infra__.pxd +42 -0
- cbase/bytemap/__init__.pxd +42 -0
- cbase/bytemap/__init__.py +21 -0
- cbase/bytemap/c_bytemap.c +52076 -0
- cbase/bytemap/c_bytemap.cp313-win_amd64.pyd +0 -0
- cbase/bytemap/c_bytemap.h +867 -0
- cbase/bytemap/c_bytemap.pxd +370 -0
- cbase/bytemap/c_bytemap.pyx +1758 -0
- cbase/bytemap/xxh3.h +55 -0
- cbase/bytemap/xxhash.c +42 -0
- cbase/bytemap/xxhash.h +7487 -0
- cbase/env.c +11109 -0
- cbase/env.cp313-win_amd64.pyd +0 -0
- cbase/env.pxd +8 -0
- cbase/env.pyi +48 -0
- cbase/env.pyx +46 -0
- cbase/includes/cbase/allocator_protocol/c_allocator_protocol.c +31818 -0
- cbase/includes/cbase/allocator_protocol/c_allocator_protocol.h +352 -0
- cbase/includes/cbase/allocator_protocol/c_heap_allocator.c +38144 -0
- cbase/includes/cbase/allocator_protocol/c_heap_allocator.h +444 -0
- cbase/includes/cbase/allocator_protocol/c_nt_shm_allocator.c +33399 -0
- cbase/includes/cbase/allocator_protocol/c_nt_shm_allocator.h +996 -0
- cbase/includes/cbase/allocator_protocol/c_shm_allocator.h +1168 -0
- cbase/includes/cbase/allocator_protocol/c_shm_comp.c +4643 -0
- cbase/includes/cbase/allocator_protocol/c_shm_comp.h +49 -0
- cbase/includes/cbase/backports/pydict.h +55 -0
- cbase/includes/cbase/backports/pylong.c +9946 -0
- cbase/includes/cbase/backports/pylong.h +79 -0
- cbase/includes/cbase/bytemap/c_bytemap.c +52076 -0
- cbase/includes/cbase/bytemap/c_bytemap.h +867 -0
- cbase/includes/cbase/bytemap/xxh3.h +55 -0
- cbase/includes/cbase/bytemap/xxhash.c +42 -0
- cbase/includes/cbase/bytemap/xxhash.h +7487 -0
- cbase/includes/cbase/env.c +11109 -0
- cbase/includes/cbase/int128.h +81 -0
- cbase/includes/cbase/intern_string/c_intern_string.c +28081 -0
- cbase/includes/cbase/intern_string/c_intern_string.h +614 -0
- cbase/includes/cbase/nt/pthread_nt_compat.h +102 -0
- cbase/includes/cbase/nt/regex_nt_compat.h +133 -0
- cbase/includes/cbase/nt/time_sched_nt_compat.h +32 -0
- cbase/int128.h +81 -0
- cbase/int128.pxd +15 -0
- cbase/intern_string/BENCHMARK.md +157 -0
- cbase/intern_string/__infra__.pxd +11 -0
- cbase/intern_string/__init__.pxd +11 -0
- cbase/intern_string/__init__.py +19 -0
- cbase/intern_string/c_intern_string.c +28081 -0
- cbase/intern_string/c_intern_string.cp313-win_amd64.pyd +0 -0
- cbase/intern_string/c_intern_string.h +614 -0
- cbase/intern_string/c_intern_string.pxd +118 -0
- cbase/intern_string/c_intern_string.pyi +376 -0
- cbase/intern_string/c_intern_string.pyx +765 -0
- cbase/nt/pthread_nt_compat.h +102 -0
- cbase/nt/regex_nt_compat.h +133 -0
- cbase/nt/time_sched_nt_compat.h +32 -0
- pycybase-0.1.8.post4.dist-info/METADATA +180 -0
- pycybase-0.1.8.post4.dist-info/RECORD +101 -0
- pycybase-0.1.8.post4.dist-info/WHEEL +5 -0
- pycybase-0.1.8.post4.dist-info/top_level.txt +1 -0
|
Binary file
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
#ifndef C_ALLOCATOR_PROTOCOL_H
|
|
2
|
+
#define C_ALLOCATOR_PROTOCOL_H
|
|
3
|
+
|
|
4
|
+
#include <stdatomic.h>
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
|
|
10
|
+
#include <cbase/allocator_protocol/c_heap_allocator.h>
|
|
11
|
+
|
|
12
|
+
#ifdef _WIN32
|
|
13
|
+
#include <cbase/allocator_protocol/c_nt_shm_allocator.h>
|
|
14
|
+
// Type aliases -- NT structs masquerade as POSIX names
|
|
15
|
+
typedef nt_shm_allocator shm_allocator;
|
|
16
|
+
typedef nt_shm_allocator_ctx shm_allocator_ctx;
|
|
17
|
+
typedef nt_shm_page shm_page;
|
|
18
|
+
typedef nt_shm_page_ctx shm_page_ctx;
|
|
19
|
+
typedef nt_shm_memory_block shm_memory_block;
|
|
20
|
+
// Function aliases -- NT implementations with identical signatures
|
|
21
|
+
#define c_shm_allocator_new c_nt_shm_allocator_new
|
|
22
|
+
#define c_shm_allocator_free c_nt_shm_allocator_free
|
|
23
|
+
#define c_shm_request c_nt_shm_request
|
|
24
|
+
#define c_shm_calloc c_nt_shm_calloc
|
|
25
|
+
#define c_shm_free c_nt_shm_free
|
|
26
|
+
#define c_shm_reclaim c_nt_shm_reclaim
|
|
27
|
+
#else
|
|
28
|
+
#include <cbase/allocator_protocol/c_shm_allocator.h>
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
// ========== Constants ==========
|
|
32
|
+
|
|
33
|
+
#ifndef AP_ALLOC_VIGILANT
|
|
34
|
+
#define AP_ALLOC_VIGILANT 1
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#ifndef AP_ALLOC_MAGIC
|
|
38
|
+
#define AP_ALLOC_MAGIC 0xCFBBBBFCULL
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#ifndef AP_DEALLOC_MAGIC
|
|
42
|
+
#define AP_DEALLOC_MAGIC 0xDEADDEADULL
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#ifndef AP_DECREF_AUTOFREE
|
|
46
|
+
#define AP_DECREF_AUTOFREE 1
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
#ifndef AP_ALLOC_WITH_LOCK
|
|
50
|
+
#define AP_ALLOC_WITH_LOCK 1
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
#ifndef AP_ALLOC_WITH_SHM
|
|
54
|
+
#define AP_ALLOC_WITH_SHM 0
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
#ifndef AP_ALLOC_WITH_FREELIST
|
|
58
|
+
#define AP_ALLOC_WITH_FREELIST 1
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
// ========== Structs ==========
|
|
62
|
+
|
|
63
|
+
typedef struct allocator_protocol {
|
|
64
|
+
shm_allocator* shm_allocator;
|
|
65
|
+
shm_allocator_ctx* shm_allocator_ctx;
|
|
66
|
+
heap_allocator* heap_allocator;
|
|
67
|
+
bool with_lock;
|
|
68
|
+
bool with_shm;
|
|
69
|
+
bool with_freelist;
|
|
70
|
+
size_t size;
|
|
71
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
72
|
+
uint64_t magic;
|
|
73
|
+
#endif
|
|
74
|
+
_Atomic int64_t ref_count;
|
|
75
|
+
char buf[];
|
|
76
|
+
} allocator_protocol;
|
|
77
|
+
|
|
78
|
+
// ========== Forward Declaration ==========
|
|
79
|
+
|
|
80
|
+
static inline allocator_protocol* c_ap_allocator_protocol_new(size_t size, shm_allocator_ctx* shm_allocator, heap_allocator* heap_allocator, bool with_lock);
|
|
81
|
+
static inline void c_ap_allocator_protocol_free(allocator_protocol* protocol);
|
|
82
|
+
static inline int64_t c_ap_allocator_protocol_acquire_owner(allocator_protocol* protocol);
|
|
83
|
+
static inline int64_t c_ap_allocator_protocol_release_owner(allocator_protocol* protocol);
|
|
84
|
+
|
|
85
|
+
static inline allocator_protocol* c_ap_protocol_from_ptr(const void* ptr);
|
|
86
|
+
static inline void* c_ap_alloc(size_t size, allocator_protocol* schematic);
|
|
87
|
+
static inline void c_ap_free(void* ptr);
|
|
88
|
+
static inline void c_ap_incref(void* ptr);
|
|
89
|
+
static inline void c_ap_decref(void* ptr);
|
|
90
|
+
static inline char* c_ap_strdup(const char* src, allocator_protocol* allocator);
|
|
91
|
+
static inline void* c_ap_realloc(void* src, size_t new_size, allocator_protocol* allocator);
|
|
92
|
+
static inline bool c_ap_is_allocator_buf(const void* ptr);
|
|
93
|
+
|
|
94
|
+
// ========== Utilities Functions ==========
|
|
95
|
+
|
|
96
|
+
static inline allocator_protocol* c_ap_allocator_protocol_new(size_t size, shm_allocator_ctx* shm_allocator, heap_allocator* heap_allocator, bool with_lock) {
|
|
97
|
+
if (size == 0) return NULL;
|
|
98
|
+
size_t ttl_size = sizeof(allocator_protocol) + size;
|
|
99
|
+
allocator_protocol* protocol;
|
|
100
|
+
|
|
101
|
+
if (shm_allocator) {
|
|
102
|
+
pthread_mutex_t* lock = with_lock ? &shm_allocator->shm_allocator->lock : NULL;
|
|
103
|
+
protocol = (allocator_protocol*) c_shm_request(shm_allocator, ttl_size, 0, lock);
|
|
104
|
+
if (!protocol) return NULL;
|
|
105
|
+
protocol->shm_allocator = shm_allocator->shm_allocator;
|
|
106
|
+
protocol->shm_allocator_ctx = shm_allocator;
|
|
107
|
+
protocol->with_lock = with_lock;
|
|
108
|
+
protocol->with_shm = true;
|
|
109
|
+
}
|
|
110
|
+
else if (heap_allocator) {
|
|
111
|
+
pthread_mutex_t* lock = with_lock ? &heap_allocator->lock : NULL;
|
|
112
|
+
protocol = (allocator_protocol*) c_heap_request(heap_allocator, ttl_size, 0, lock);
|
|
113
|
+
if (!protocol) return NULL;
|
|
114
|
+
protocol->heap_allocator = heap_allocator;
|
|
115
|
+
protocol->with_lock = with_lock;
|
|
116
|
+
protocol->with_freelist = true;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
protocol = (allocator_protocol*) calloc(1, ttl_size);
|
|
120
|
+
if (!protocol) return NULL;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
protocol->with_lock = with_lock;
|
|
124
|
+
protocol->size = size;
|
|
125
|
+
// _new method DOES NOT manipulate ref_count! So as the _free method.
|
|
126
|
+
// atomic_store_explicit(&protocol->ref_count, 1, memory_order_release);
|
|
127
|
+
|
|
128
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
129
|
+
protocol->magic = AP_ALLOC_MAGIC;
|
|
130
|
+
#endif
|
|
131
|
+
|
|
132
|
+
return protocol;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static inline void c_ap_allocator_protocol_free(allocator_protocol* protocol) {
|
|
136
|
+
if (!protocol) return;
|
|
137
|
+
|
|
138
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
139
|
+
// Invalidate magic to catch double free or invalid free attempts
|
|
140
|
+
protocol->magic = AP_DEALLOC_MAGIC;
|
|
141
|
+
#endif
|
|
142
|
+
bool with_lock = protocol->with_lock;
|
|
143
|
+
bool with_shm = protocol->with_shm;
|
|
144
|
+
bool with_freelist = protocol->with_freelist;
|
|
145
|
+
|
|
146
|
+
// _free method DOES NOT manipulate ref_count! So as the _new method.
|
|
147
|
+
// atomic_store_explicit(&protocol->ref_count, 0, memory_order_release);
|
|
148
|
+
|
|
149
|
+
if (with_shm && with_freelist) {
|
|
150
|
+
fprintf(stderr, "[c_ap_allocator_protocol_free] ERROR: Protocol cannot have both with_shm and with_freelist set to true!\n");
|
|
151
|
+
abort();
|
|
152
|
+
}
|
|
153
|
+
else if (with_shm) {
|
|
154
|
+
shm_allocator* shm_allocator = protocol->shm_allocator;
|
|
155
|
+
pthread_mutex_t* lock = with_lock ? &shm_allocator->lock : NULL;
|
|
156
|
+
c_shm_free((void*) protocol, lock);
|
|
157
|
+
}
|
|
158
|
+
else if (with_freelist) {
|
|
159
|
+
heap_allocator* heap_allocator = protocol->heap_allocator;
|
|
160
|
+
pthread_mutex_t* lock = with_lock ? &heap_allocator->lock : NULL;
|
|
161
|
+
c_heap_free((void*) protocol, lock);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
free((void*) protocol);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static inline int64_t c_ap_allocator_protocol_acquire_owner(allocator_protocol* protocol) {
|
|
169
|
+
if (!protocol) return 0;
|
|
170
|
+
return atomic_fetch_add_explicit(&protocol->ref_count, 1, memory_order_acq_rel) + 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static inline int64_t c_ap_allocator_protocol_release_owner(allocator_protocol* protocol) {
|
|
174
|
+
if (!protocol) return 0;
|
|
175
|
+
return atomic_fetch_sub_explicit(&protocol->ref_count, 1, memory_order_acq_rel) - 1;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ========== Public APIs ==========
|
|
179
|
+
|
|
180
|
+
static inline allocator_protocol* c_ap_protocol_from_ptr(const void* ptr) {
|
|
181
|
+
if (!ptr) return NULL;
|
|
182
|
+
allocator_protocol* protocol = (allocator_protocol*) ((char*) ptr - offsetof(allocator_protocol, buf));
|
|
183
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
184
|
+
if (protocol->magic != AP_ALLOC_MAGIC) {
|
|
185
|
+
if (protocol->magic == AP_DEALLOC_MAGIC) {
|
|
186
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: Use-after-free detected in c_ap_protocol_from_ptr!\n");
|
|
187
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] Pointer %p was already freed (dealloc magic: 0x%llx).\n", ptr, (unsigned long long) AP_DEALLOC_MAGIC);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: Magic mismatch in c_ap_protocol_from_ptr! Not an ap-allocated pointer!\n");
|
|
191
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] Expected: 0x%llx, Got: 0x%llx\n", (unsigned long long) AP_ALLOC_MAGIC, (unsigned long long) protocol->magic);
|
|
192
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] This is likely a raw malloc / calloc'd pointer.\n");
|
|
193
|
+
}
|
|
194
|
+
fflush(stderr);
|
|
195
|
+
abort();
|
|
196
|
+
}
|
|
197
|
+
#endif
|
|
198
|
+
|
|
199
|
+
return protocol;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static inline void* c_ap_alloc(size_t size, allocator_protocol* schematic) {
|
|
203
|
+
allocator_protocol* clone;
|
|
204
|
+
|
|
205
|
+
if (!schematic) {
|
|
206
|
+
clone = (allocator_protocol*) calloc(1, sizeof(allocator_protocol) + size);
|
|
207
|
+
if (!clone) return NULL;
|
|
208
|
+
clone->size = size;
|
|
209
|
+
atomic_store_explicit(&clone->ref_count, 1, memory_order_release);
|
|
210
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
211
|
+
clone->magic = AP_ALLOC_MAGIC;
|
|
212
|
+
#endif
|
|
213
|
+
return (void*) clone->buf;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (schematic->with_shm) {
|
|
217
|
+
bool with_lock = schematic->with_lock;
|
|
218
|
+
shm_allocator_ctx* ctx = schematic->shm_allocator_ctx;
|
|
219
|
+
shm_allocator* allocator = schematic->shm_allocator;
|
|
220
|
+
pthread_mutex_t* lock = with_lock ? &allocator->lock : NULL;
|
|
221
|
+
clone = (allocator_protocol*) c_shm_request(ctx, sizeof(allocator_protocol) + size, 0, lock);
|
|
222
|
+
if (!clone) return NULL;
|
|
223
|
+
clone->shm_allocator = allocator;
|
|
224
|
+
clone->shm_allocator_ctx = ctx;
|
|
225
|
+
clone->with_lock = with_lock;
|
|
226
|
+
clone->with_shm = 1;
|
|
227
|
+
}
|
|
228
|
+
else if (schematic->with_freelist) {
|
|
229
|
+
bool with_lock = schematic->with_lock;
|
|
230
|
+
heap_allocator* allocator = schematic->heap_allocator;
|
|
231
|
+
pthread_mutex_t* lock = with_lock ? &allocator->lock : NULL;
|
|
232
|
+
clone = (allocator_protocol*) c_heap_request(allocator, sizeof(allocator_protocol) + size, 0, lock);
|
|
233
|
+
if (!clone) return NULL;
|
|
234
|
+
clone->heap_allocator = allocator;
|
|
235
|
+
clone->with_lock = with_lock;
|
|
236
|
+
clone->with_freelist = 1;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
clone = (allocator_protocol*) calloc(1, sizeof(allocator_protocol) + size);
|
|
240
|
+
if (!clone) return NULL;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
clone->with_lock = schematic->with_lock;
|
|
244
|
+
clone->size = size;
|
|
245
|
+
atomic_store_explicit(&clone->ref_count, 1, memory_order_release);
|
|
246
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
247
|
+
clone->magic = AP_ALLOC_MAGIC;
|
|
248
|
+
#endif
|
|
249
|
+
return (void*) clone->buf;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static inline void c_ap_free(void* ptr) {
|
|
253
|
+
if (!ptr) return;
|
|
254
|
+
allocator_protocol* protocol = c_ap_protocol_from_ptr(ptr);
|
|
255
|
+
|
|
256
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
257
|
+
if (protocol->magic != AP_ALLOC_MAGIC) {
|
|
258
|
+
if (protocol->magic == AP_DEALLOC_MAGIC) {
|
|
259
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: Double free detected in c_ap_free!\n");
|
|
260
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] Pointer %p was already freed (dealloc magic: 0x%llx).\n", ptr, (unsigned long long) AP_DEALLOC_MAGIC);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: Magic mismatch in c_ap_free! Not an ap-allocated pointer!\n");
|
|
264
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] Expected: 0x%llx, Got: 0x%llx\n", (unsigned long long) AP_ALLOC_MAGIC, (unsigned long long) protocol->magic);
|
|
265
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] This is likely a raw malloc / calloc'd pointer.\n");
|
|
266
|
+
}
|
|
267
|
+
fflush(stderr);
|
|
268
|
+
abort();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (atomic_load_explicit(&protocol->ref_count, memory_order_acquire) > 1) {
|
|
272
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: c_ap_free is not allowed while buffer is shared (ref_count>1)!\n");
|
|
273
|
+
fflush(stderr);
|
|
274
|
+
abort();
|
|
275
|
+
}
|
|
276
|
+
#endif
|
|
277
|
+
|
|
278
|
+
atomic_store_explicit(&protocol->ref_count, 0, memory_order_release);
|
|
279
|
+
c_ap_allocator_protocol_free(protocol);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
static inline void c_ap_incref(void* ptr) {
|
|
283
|
+
if (!ptr) return;
|
|
284
|
+
allocator_protocol* protocol = c_ap_protocol_from_ptr(ptr);
|
|
285
|
+
int64_t ref_count = c_ap_allocator_protocol_acquire_owner(protocol);
|
|
286
|
+
|
|
287
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
288
|
+
if (ref_count <= 1) {
|
|
289
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: incref on non-owned allocator protocol (new_ref_count=%lld)!\n", (long long) ref_count);
|
|
290
|
+
fflush(stderr);
|
|
291
|
+
abort();
|
|
292
|
+
}
|
|
293
|
+
#endif
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
static inline void c_ap_decref(void* ptr) {
|
|
297
|
+
if (!ptr) return;
|
|
298
|
+
allocator_protocol* protocol = c_ap_protocol_from_ptr(ptr);
|
|
299
|
+
int64_t ref_count = c_ap_allocator_protocol_release_owner(protocol);
|
|
300
|
+
|
|
301
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
302
|
+
if (ref_count < 0) {
|
|
303
|
+
fprintf(stderr, "[AP_ALLOC_VIGILANT] ERROR: decref on unowned allocator protocol (new_ref_count=%lld)!\n", (long long) ref_count);
|
|
304
|
+
fflush(stderr);
|
|
305
|
+
abort();
|
|
306
|
+
}
|
|
307
|
+
#endif
|
|
308
|
+
|
|
309
|
+
#if AP_DECREF_AUTOFREE > 0
|
|
310
|
+
if (ref_count == 0) {
|
|
311
|
+
c_ap_allocator_protocol_free(protocol);
|
|
312
|
+
}
|
|
313
|
+
#endif
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
static inline char* c_ap_strdup(const char* src, allocator_protocol* allocator) {
|
|
317
|
+
if (!src) return NULL;
|
|
318
|
+
size_t len = strlen(src);
|
|
319
|
+
char* trg = (char*) c_ap_alloc(len + 1, allocator);
|
|
320
|
+
if (!trg) return NULL;
|
|
321
|
+
memcpy(trg, src, len);
|
|
322
|
+
return trg;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static inline void* c_ap_realloc(void* src, size_t new_size, allocator_protocol* allocator) {
|
|
326
|
+
if (!src) return c_ap_alloc(new_size, allocator);
|
|
327
|
+
if (new_size == 0) {
|
|
328
|
+
c_ap_free(src);
|
|
329
|
+
return NULL;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
allocator_protocol* protocol = c_ap_protocol_from_ptr(src);
|
|
333
|
+
size_t copy_size = protocol->size < new_size ? protocol->size : new_size;
|
|
334
|
+
void* new_ptr = c_ap_alloc(new_size, allocator);
|
|
335
|
+
if (!new_ptr) return NULL;
|
|
336
|
+
memcpy(new_ptr, src, copy_size);
|
|
337
|
+
c_ap_free(src);
|
|
338
|
+
return new_ptr;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static inline bool c_ap_is_allocator_buf(const void* ptr) {
|
|
342
|
+
if (!ptr) return false;
|
|
343
|
+
#if AP_ALLOC_VIGILANT > 0
|
|
344
|
+
allocator_protocol* protocol = (allocator_protocol*) ((char*) ptr - offsetof(allocator_protocol, buf));
|
|
345
|
+
return protocol->magic == AP_ALLOC_MAGIC;
|
|
346
|
+
#else
|
|
347
|
+
(void) ptr;
|
|
348
|
+
return true;
|
|
349
|
+
#endif
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#endif /* C_ALLOCATOR_PROTOCOL_H */
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from libc.stdint cimport int64_t, uint64_t, uint8_t
|
|
2
|
+
from libcpp cimport bool as c_bool
|
|
3
|
+
|
|
4
|
+
from cbase.env cimport EnvConfigContext
|
|
5
|
+
|
|
6
|
+
from .c_heap_allocator cimport heap_allocator as heap_allocator_t
|
|
7
|
+
from .c_shm_comp cimport shm_allocator as shm_allocator_t, shm_allocator_ctx as shm_allocator_ctx_t
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
cdef extern from "cbase/allocator_protocol/c_allocator_protocol.h":
|
|
11
|
+
const uint8_t AP_ALLOC_VIGILANT
|
|
12
|
+
const uint64_t AP_ALLOC_MAGIC
|
|
13
|
+
const c_bool AP_ALLOC_WITH_LOCK
|
|
14
|
+
const c_bool AP_ALLOC_WITH_SHM
|
|
15
|
+
const c_bool AP_ALLOC_WITH_FREELIST
|
|
16
|
+
|
|
17
|
+
ctypedef struct allocator_protocol:
|
|
18
|
+
shm_allocator_t* shm_allocator
|
|
19
|
+
shm_allocator_ctx_t* shm_allocator_ctx
|
|
20
|
+
heap_allocator_t* heap_allocator
|
|
21
|
+
c_bool with_lock
|
|
22
|
+
c_bool with_shm
|
|
23
|
+
c_bool with_freelist
|
|
24
|
+
size_t size
|
|
25
|
+
uint64_t magic
|
|
26
|
+
int64_t ref_count
|
|
27
|
+
char buf[]
|
|
28
|
+
|
|
29
|
+
allocator_protocol* c_ap_allocator_protocol_new(size_t size, shm_allocator_ctx_t* shm_allocator, heap_allocator_t* heap_allocator, c_bool with_lock) noexcept nogil
|
|
30
|
+
void c_ap_allocator_protocol_free(allocator_protocol* protocol) noexcept nogil
|
|
31
|
+
int64_t c_ap_allocator_protocol_acquire_owner(allocator_protocol* protocol) noexcept nogil
|
|
32
|
+
int64_t c_ap_allocator_protocol_release_owner(allocator_protocol* protocol) noexcept nogil
|
|
33
|
+
|
|
34
|
+
allocator_protocol* c_ap_protocol_from_ptr(const void* ptr) noexcept nogil
|
|
35
|
+
void* c_ap_alloc(size_t size, allocator_protocol* schematic) noexcept nogil
|
|
36
|
+
void c_ap_free(void* ptr) noexcept nogil
|
|
37
|
+
void c_ap_incref(void* ptr) noexcept nogil
|
|
38
|
+
void c_ap_decref(void* ptr) noexcept nogil
|
|
39
|
+
char* c_ap_strdup(const char* src, allocator_protocol* allocator) noexcept nogil
|
|
40
|
+
void* c_ap_realloc(void* src, size_t new_size, allocator_protocol* allocator) noexcept nogil
|
|
41
|
+
c_bool c_ap_is_allocator_buf(const void* ptr) noexcept nogil
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
cdef class AllocatorConfigContext(EnvConfigContext):
|
|
45
|
+
cdef allocator_protocol* allocator_schematic
|
|
46
|
+
|
|
47
|
+
cdef void c_bind(self, allocator_protocol* schematic=?)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
cdef class AllocatorProtocol:
|
|
51
|
+
cdef allocator_protocol* protocol
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
cdef AllocatorProtocol c_from_protocol(allocator_protocol* protocol)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
cdef allocator_protocol* AP_DEFAULT_ALLOCATOR
|
|
58
|
+
cdef allocator_protocol* AP_SHM_ALLOCATOR
|
|
59
|
+
cdef allocator_protocol* AP_HEAP_ALLOCATOR
|
|
60
|
+
|
|
61
|
+
cdef AllocatorConfigContext AP_SHARED
|
|
62
|
+
cdef AllocatorConfigContext AP_LOCKED
|
|
63
|
+
cdef AllocatorConfigContext AP_LOCKFREE
|
|
64
|
+
cdef AllocatorConfigContext AP_FREELIST
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from cbase.env import EnvConfigContext
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AllocatorConfigContext(EnvConfigContext):
|
|
7
|
+
"""Context manager that extends EnvConfigContext to also dispatch config
|
|
8
|
+
changes to the underlying heap and shared-memory allocators.
|
|
9
|
+
|
|
10
|
+
Accepted keyword arguments (in addition to those inherited):
|
|
11
|
+
|
|
12
|
+
* ``locked: bool`` — enable/disable mutex locking
|
|
13
|
+
* ``shared: bool`` — enable/disable shared memory
|
|
14
|
+
* ``freelist: bool`` — enable/disable free list
|
|
15
|
+
* ``autopage_capacity: int`` — propagated to both heap and SHM allocators
|
|
16
|
+
* ``autopage_capacity_max: int`` — propagated to both heap and SHM allocators
|
|
17
|
+
* ``autopage_alignment: int`` — propagated to both heap and SHM allocators
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Initialize the context with configuration changes.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
**kwargs: Configuration key-value pairs to set temporarily
|
|
26
|
+
"""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def __or__(self, other: AllocatorConfigContext) -> AllocatorConfigContext:
|
|
30
|
+
"""
|
|
31
|
+
Combine two AllocatorConfigContext instances.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
other: Another AllocatorConfigContext instance
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
A new AllocatorConfigContext with combined configurations
|
|
38
|
+
"""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def __invert__(self) -> AllocatorConfigContext:
|
|
42
|
+
"""
|
|
43
|
+
Invert the AllocatorConfigContext.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
A new AllocatorConfigContext that reverts the configurations.
|
|
47
|
+
"""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
AP_SHARED: AllocatorConfigContext
|
|
52
|
+
"""
|
|
53
|
+
AllocatorConfigContext instance to set flag for cbase to use SHM allocator.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
AP_LOCKED: AllocatorConfigContext
|
|
57
|
+
"""
|
|
58
|
+
AllocatorConfigContext instance to set flag for cbase to use thread safe mode.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
AP_LOCKFREE: AllocatorConfigContext
|
|
62
|
+
"""
|
|
63
|
+
AllocatorConfigContext instance to set flag for cbase to disable thread safe mode.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
AP_FREELIST: AllocatorConfigContext
|
|
67
|
+
"""
|
|
68
|
+
AllocatorConfigContext instance to set flag for cbase to use freelist. Have no effect when in AP_SHARED mode, which enforces its own free list.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class AllocatorProtocol:
|
|
73
|
+
"""Protocol for memory allocation with environment-based configuration.
|
|
74
|
+
|
|
75
|
+
Manages an underlying `allocator_protocol` C structure, handling memory
|
|
76
|
+
allocation and deallocation based on global environment settings.
|
|
77
|
+
|
|
78
|
+
Attributes:
|
|
79
|
+
protocol: **cython internal** Pointer to the underlying `allocator_protocol` C structure.
|
|
80
|
+
owner: **cython internal** Boolean indicating if this instance owns the protocol and is
|
|
81
|
+
responsible for its deallocation.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, size: int) -> None:
|
|
85
|
+
"""Initialize the AllocatorProtocol with a specified buffer size.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
size: The size of the buffer to allocate in bytes.
|
|
89
|
+
"""
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def buf(self) -> memoryview:
|
|
94
|
+
"""Memory buffer managed by this allocator protocol.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
A memoryview representing the allocated buffer.
|
|
98
|
+
"""
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def size(self) -> int:
|
|
103
|
+
"""Size of the allocated buffer.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
The size of the buffer in bytes.
|
|
107
|
+
"""
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def with_shm(self) -> bool:
|
|
112
|
+
"""Indicates if the allocator uses shared memory.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
True if shared memory is used, False otherwise.
|
|
116
|
+
"""
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def with_lock(self) -> bool:
|
|
121
|
+
"""Indicates if the allocator uses locking for thread safety.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
True if locking is enabled, False otherwise.
|
|
125
|
+
"""
|
|
126
|
+
...
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def with_freelist(self) -> bool:
|
|
130
|
+
"""Indicates if the allocator uses a free list.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
True if free list is enabled, False otherwise.
|
|
134
|
+
"""
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def addr(self) -> int:
|
|
139
|
+
"""Memory address of the underlying allocator protocol structure.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
The memory address as an integer.
|
|
143
|
+
"""
|
|
144
|
+
...
|