yeptris 0.6.18.2-arm-linux-eabihf
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.
- checksums.yaml +7 -0
- data/README.adoc +141 -0
- data/ext/build_windows_native.rb +41 -0
- data/ext/libyeptris/extconf.rb +57 -0
- data/ext/yeptris_native/cbor_ruby.c +193 -0
- data/ext/yeptris_native/extconf.rb +47 -0
- data/ext/yeptris_native/json_ruby.c +354 -0
- data/ext/yeptris_native/yeptris_native.c +497 -0
- data/lib/yeptris/cbor.rb +130 -0
- data/lib/yeptris/document.rb +255 -0
- data/lib/yeptris/ffi.rb +426 -0
- data/lib/yeptris/json/descriptor.rb +266 -0
- data/lib/yeptris/json.rb +394 -0
- data/lib/yeptris/materializer.rb +354 -0
- data/lib/yeptris/native-3.4.so +0 -0
- data/lib/yeptris/node.rb +453 -0
- data/lib/yeptris/psych/class_loader.rb +24 -0
- data/lib/yeptris/psych/coder_shim.rb +55 -0
- data/lib/yeptris/psych/drop_in.rb +63 -0
- data/lib/yeptris/psych/encodable.rb +14 -0
- data/lib/yeptris/psych/handler.rb +90 -0
- data/lib/yeptris/psych/parser.rb +105 -0
- data/lib/yeptris/psych/scalar_scanner.rb +149 -0
- data/lib/yeptris/psych/visitors.rb +545 -0
- data/lib/yeptris/psych.rb +622 -0
- data/lib/yeptris/schema.rb +253 -0
- data/lib/yeptris/valueml.rb +455 -0
- data/lib/yeptris/yaml/descriptor.rb +56 -0
- data/lib/yeptris/yaml.rb +422 -0
- data/lib/yeptris.rb +113 -0
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +254 -0
- data/vendor/libyeptris/cmake/yeptris-config.cmake.in +5 -0
- data/vendor/libyeptris/cmake/yeptris.pc.in +11 -0
- data/vendor/libyeptris/src/CMakeLists.txt +167 -0
- data/vendor/libyeptris/src/include/yeptris/api.h +32 -0
- data/vendor/libyeptris/src/include/yeptris/cbor.h +101 -0
- data/vendor/libyeptris/src/include/yeptris/dom.h +190 -0
- data/vendor/libyeptris/src/include/yeptris/emit.h +81 -0
- data/vendor/libyeptris/src/include/yeptris/error.h +41 -0
- data/vendor/libyeptris/src/include/yeptris/events.h +157 -0
- data/vendor/libyeptris/src/include/yeptris/json.h +45 -0
- data/vendor/libyeptris/src/include/yeptris/json.hpp +258 -0
- data/vendor/libyeptris/src/include/yeptris/jsonc_compat.h +115 -0
- data/vendor/libyeptris/src/include/yeptris/marshal.h +52 -0
- data/vendor/libyeptris/src/include/yeptris/parse.h +48 -0
- data/vendor/libyeptris/src/include/yeptris/plan.h +100 -0
- data/vendor/libyeptris/src/include/yeptris/resolve.h +71 -0
- data/vendor/libyeptris/src/include/yeptris/schema.h +121 -0
- data/vendor/libyeptris/src/include/yeptris/tape.h +123 -0
- data/vendor/libyeptris/src/include/yeptris/types.h +38 -0
- data/vendor/libyeptris/src/include/yeptris/values.h +102 -0
- data/vendor/libyeptris/src/include/yeptris/version.h.in +29 -0
- data/vendor/libyeptris/src/include/yeptris/visit.h +77 -0
- data/vendor/libyeptris/src/include/yeptris/yajl_compat.h +135 -0
- data/vendor/libyeptris/src/include/yeptris.h +23 -0
- data/vendor/libyeptris/src/yeptris/build.c +376 -0
- data/vendor/libyeptris/src/yeptris/cbor/cbor.h +25 -0
- data/vendor/libyeptris/src/yeptris/cbor/decode.c +981 -0
- data/vendor/libyeptris/src/yeptris/cbor/encode.c +835 -0
- data/vendor/libyeptris/src/yeptris/cbor/sink.h +58 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.c +41 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.h +77 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.c +81 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.h +40 -0
- data/vendor/libyeptris/src/yeptris/common/error.c +65 -0
- data/vendor/libyeptris/src/yeptris/common/error.h +79 -0
- data/vendor/libyeptris/src/yeptris/common/mutex.h +45 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.c +275 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.h +68 -0
- data/vendor/libyeptris/src/yeptris/common/port.h +74 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.c +49 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.h +295 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +534 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +662 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +298 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.c +34 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.h +93 -0
- data/vendor/libyeptris/src/yeptris/doc.h +56 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.c +1192 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.h +312 -0
- data/vendor/libyeptris/src/yeptris/dom/hpool.c +107 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.c +173 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.h +61 -0
- data/vendor/libyeptris/src/yeptris/dom/mutate.c +431 -0
- data/vendor/libyeptris/src/yeptris/emit/emit.c +434 -0
- data/vendor/libyeptris/src/yeptris/emit/float/api.h +38 -0
- data/vendor/libyeptris/src/yeptris/emit/float/dragon.c +405 -0
- data/vendor/libyeptris/src/yeptris/emit/float/floatint.h +231 -0
- data/vendor/libyeptris/src/yeptris/emit/float/print.c +396 -0
- data/vendor/libyeptris/src/yeptris/emit/style.c +81 -0
- data/vendor/libyeptris/src/yeptris/emit/style.h +24 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.c +816 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.h +76 -0
- data/vendor/libyeptris/src/yeptris/encoding/bom.c +31 -0
- data/vendor/libyeptris/src/yeptris/encoding/encoding.h +63 -0
- data/vendor/libyeptris/src/yeptris/encoding/transcode.c +148 -0
- data/vendor/libyeptris/src/yeptris/encoding/utf8_validate.c +178 -0
- data/vendor/libyeptris/src/yeptris/events/capture.c +150 -0
- data/vendor/libyeptris/src/yeptris/events/capture.h +39 -0
- data/vendor/libyeptris/src/yeptris/events/iterparse.c +208 -0
- data/vendor/libyeptris/src/yeptris/events/pull.c +97 -0
- data/vendor/libyeptris/src/yeptris/events/push.c +104 -0
- data/vendor/libyeptris/src/yeptris/events/recorder.c +107 -0
- data/vendor/libyeptris/src/yeptris/events/values.c +527 -0
- data/vendor/libyeptris/src/yeptris/events/values_priv.h +51 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.c +86 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.h +90 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/jsonc_compat.c +687 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/yajl_compat.c +728 -0
- data/vendor/libyeptris/src/yeptris/marshal.c +782 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.c +20 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.h +43 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.c +134 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.h +52 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.c +122 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.h +36 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.c +3698 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.h +65 -0
- data/vendor/libyeptris/src/yeptris/parse/events.h +124 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.c +349 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.h +33 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.c +416 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.h +75 -0
- data/vendor/libyeptris/src/yeptris/parse.c +737 -0
- data/vendor/libyeptris/src/yeptris/plan.c +824 -0
- data/vendor/libyeptris/src/yeptris/resolve/compat11.c +334 -0
- data/vendor/libyeptris/src/yeptris/resolve/core12.c +143 -0
- data/vendor/libyeptris/src/yeptris/resolve/resolver.h +56 -0
- data/vendor/libyeptris/src/yeptris/resolve/tags.c +58 -0
- data/vendor/libyeptris/src/yeptris/scan/json.c +792 -0
- data/vendor/libyeptris/src/yeptris/scan/json.h +109 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.c +463 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.h +150 -0
- data/vendor/libyeptris/src/yeptris/schema.c +308 -0
- data/vendor/libyeptris/src/yeptris/tape.c +1308 -0
- data/vendor/libyeptris/src/yeptris/tape_in.h +19 -0
- data/vendor/libyeptris/src/yeptris/version.c +7 -0
- data/vendor/libyeptris/src/yeptris/visit/dom_visit.c +115 -0
- data/vendor/libyeptris/src/yeptris/visit/json_visit.c +293 -0
- data/vendor/libyeptris/src/yeptris/visit/yaml_visit.c +127 -0
- metadata +199 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* allocator.c — the system default. */
|
|
2
|
+
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
|
|
5
|
+
#include "allocator.h"
|
|
6
|
+
|
|
7
|
+
static void* yep_sys_alloc(void* ctx, size_t size) {
|
|
8
|
+
(void)ctx;
|
|
9
|
+
return malloc(size);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static void yep_sys_free(void* ctx, void* ptr) {
|
|
13
|
+
(void)ctx;
|
|
14
|
+
free(ptr);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const yep_allocator* yep_system_allocator(void) {
|
|
18
|
+
static const yep_allocator sys = {yep_sys_alloc, yep_sys_free, NULL};
|
|
19
|
+
return &sys;
|
|
20
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* allocator.h — the single indirection point for system memory.
|
|
2
|
+
*
|
|
3
|
+
* Every consumer (pool, arena, document) takes a yep_allocator explicitly;
|
|
4
|
+
* yep_system_allocator() is the default. No process-global override —
|
|
5
|
+
* injection is just passing a different allocator (TODO.impl/19 tests
|
|
6
|
+
* count and fail allocations this way).
|
|
7
|
+
*
|
|
8
|
+
* Memory law: nothing outside memory/ calls malloc/free directly.
|
|
9
|
+
*/
|
|
10
|
+
#ifndef YEP_ALLOCATOR_H
|
|
11
|
+
#define YEP_ALLOCATOR_H
|
|
12
|
+
|
|
13
|
+
#include <stddef.h>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
typedef void* (*yep_alloc_fn)(void* ctx, size_t size);
|
|
20
|
+
typedef void (*yep_free_fn)(void* ctx, void* ptr);
|
|
21
|
+
|
|
22
|
+
typedef struct yep_allocator {
|
|
23
|
+
yep_alloc_fn alloc; /* returns NULL on failure; size > 0 */
|
|
24
|
+
yep_free_fn free; /* accepts NULL */
|
|
25
|
+
void* ctx;
|
|
26
|
+
} yep_allocator;
|
|
27
|
+
|
|
28
|
+
/* The system allocator (malloc/free). Valid forever. */
|
|
29
|
+
const yep_allocator* yep_system_allocator(void);
|
|
30
|
+
|
|
31
|
+
static inline void* yep_alloc(const yep_allocator* a, size_t size) {
|
|
32
|
+
return a->alloc(a->ctx, size);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static inline void yep_free(const yep_allocator* a, void* ptr) {
|
|
36
|
+
a->free(a->ctx, ptr);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#ifdef __cplusplus
|
|
40
|
+
}
|
|
41
|
+
#endif
|
|
42
|
+
|
|
43
|
+
#endif /* YEP_ALLOCATOR_H */
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/* arena.c — hint-sized contiguous arena with doubling growth. */
|
|
2
|
+
|
|
3
|
+
#include <stdint.h>
|
|
4
|
+
|
|
5
|
+
#include "arena.h"
|
|
6
|
+
|
|
7
|
+
#define YEP_ARENA_DEFAULT_BLOCK (16u * 1024u)
|
|
8
|
+
|
|
9
|
+
typedef struct yep_arena_block {
|
|
10
|
+
struct yep_arena_block* next;
|
|
11
|
+
size_t size;
|
|
12
|
+
size_t used;
|
|
13
|
+
} yep_arena_block;
|
|
14
|
+
|
|
15
|
+
struct yep_arena {
|
|
16
|
+
const yep_allocator* sys;
|
|
17
|
+
yep_arena_block* head; /* newest block; next pointers run newest → oldest */
|
|
18
|
+
size_t last_block_size;
|
|
19
|
+
yep_arena_stats stats;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
static size_t yep_round_up(size_t n, size_t align) {
|
|
23
|
+
return (n + align - 1) & ~(align - 1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static int yep_align_ok(size_t align) {
|
|
27
|
+
return align != 0 && (align & (align - 1)) == 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static size_t yep_initial_capacity(const yep_sizing_hints* hints) {
|
|
31
|
+
size_t cap = YEP_ARENA_DEFAULT_BLOCK;
|
|
32
|
+
if (hints != NULL) {
|
|
33
|
+
size_t derived = hints->min_capacity + hints->newline_count * 48 +
|
|
34
|
+
(hints->colon_count + hints->quote_count) * 8;
|
|
35
|
+
if (derived > cap) {
|
|
36
|
+
cap = derived;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return cap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static yep_arena_block* yep_arena_block_new(const yep_allocator* sys, size_t payload,
|
|
43
|
+
size_t* sys_allocs) {
|
|
44
|
+
yep_arena_block* b = yep_alloc(sys, sizeof(yep_arena_block) + payload);
|
|
45
|
+
if (b == NULL) {
|
|
46
|
+
return NULL;
|
|
47
|
+
}
|
|
48
|
+
b->next = NULL;
|
|
49
|
+
b->size = payload;
|
|
50
|
+
b->used = 0;
|
|
51
|
+
(*sys_allocs)++;
|
|
52
|
+
return b;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
yep_arena* yep_arena_create(const yep_allocator* sys, const yep_sizing_hints* hints) {
|
|
56
|
+
if (sys == NULL) {
|
|
57
|
+
return NULL;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
yep_arena* a = yep_alloc(sys, sizeof(yep_arena));
|
|
61
|
+
if (a == NULL) {
|
|
62
|
+
return NULL;
|
|
63
|
+
}
|
|
64
|
+
a->sys = sys;
|
|
65
|
+
a->head = NULL;
|
|
66
|
+
a->last_block_size = 0;
|
|
67
|
+
a->stats.blocks = 0;
|
|
68
|
+
a->stats.capacity = 0;
|
|
69
|
+
a->stats.used = 0;
|
|
70
|
+
a->stats.sys_allocs = 1; /* this struct */
|
|
71
|
+
|
|
72
|
+
size_t cap = yep_initial_capacity(hints);
|
|
73
|
+
a->head = yep_arena_block_new(sys, cap, &a->stats.sys_allocs);
|
|
74
|
+
if (a->head == NULL) {
|
|
75
|
+
yep_free(sys, a);
|
|
76
|
+
return NULL;
|
|
77
|
+
}
|
|
78
|
+
a->last_block_size = cap;
|
|
79
|
+
a->stats.blocks = 1;
|
|
80
|
+
a->stats.capacity = cap;
|
|
81
|
+
return a;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void* yep_arena_alloc(yep_arena* arena, size_t size, size_t align) {
|
|
85
|
+
if (arena == NULL || size == 0 || !yep_align_ok(align)) {
|
|
86
|
+
return NULL;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
yep_arena_block* b = arena->head;
|
|
90
|
+
uintptr_t base = (uintptr_t)b + sizeof(yep_arena_block);
|
|
91
|
+
uintptr_t start = yep_round_up(base + b->used, align);
|
|
92
|
+
|
|
93
|
+
if (start + size > base + b->size) {
|
|
94
|
+
/* Amortized doubling: each new block is at least twice the last,
|
|
95
|
+
* unless the request itself is larger. */
|
|
96
|
+
size_t payload = arena->last_block_size * 2;
|
|
97
|
+
if (payload < size + align + sizeof(yep_arena_block)) {
|
|
98
|
+
payload = size + align + sizeof(yep_arena_block);
|
|
99
|
+
}
|
|
100
|
+
b = yep_arena_block_new(arena->sys, payload, &arena->stats.sys_allocs);
|
|
101
|
+
if (b == NULL) {
|
|
102
|
+
return NULL;
|
|
103
|
+
}
|
|
104
|
+
b->next = arena->head; /* newest at head; tail keeps destroy order */
|
|
105
|
+
arena->head = b;
|
|
106
|
+
arena->last_block_size = payload;
|
|
107
|
+
arena->stats.blocks++;
|
|
108
|
+
arena->stats.capacity += payload;
|
|
109
|
+
base = (uintptr_t)b + sizeof(yep_arena_block);
|
|
110
|
+
start = yep_round_up(base, align);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
b->used = start + size - base;
|
|
114
|
+
arena->stats.used += size;
|
|
115
|
+
return (void*)start;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
void yep_arena_destroy(yep_arena* arena) {
|
|
119
|
+
if (arena == NULL) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
yep_arena_block* b = arena->head;
|
|
123
|
+
while (b != NULL) {
|
|
124
|
+
yep_arena_block* next = b->next;
|
|
125
|
+
yep_free(arena->sys, b);
|
|
126
|
+
b = next;
|
|
127
|
+
}
|
|
128
|
+
yep_free(arena->sys, arena);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
yep_arena_stats yep_arena_get_stats(const yep_arena* arena) {
|
|
132
|
+
yep_arena_stats zero = {0, 0, 0, 0};
|
|
133
|
+
return arena ? arena->stats : zero;
|
|
134
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* arena.h — the contiguous per-document arena (libleptris TODO 183
|
|
2
|
+
* pattern): an initial block sized from scan-derived hints so a typical
|
|
3
|
+
* document needs no further system allocations, plus amortized-doubling
|
|
4
|
+
* growth for underestimated inputs. All document-reachable memory lives
|
|
5
|
+
* here or in a pool; yeptris_document_free frees the arena and the world.
|
|
6
|
+
*/
|
|
7
|
+
#ifndef YEP_ARENA_H
|
|
8
|
+
#define YEP_ARENA_H
|
|
9
|
+
|
|
10
|
+
#include <stddef.h>
|
|
11
|
+
|
|
12
|
+
#include "allocator.h"
|
|
13
|
+
|
|
14
|
+
#ifdef __cplusplus
|
|
15
|
+
extern "C" {
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
/* Content-derived sizing hints. Counts come from the scan layer's fused
|
|
19
|
+
* SIMD counters (TODO.impl/06). The multipliers are heuristic placeholders
|
|
20
|
+
* until 06 wires measured densities; they only affect the initial block
|
|
21
|
+
* size, never correctness. */
|
|
22
|
+
typedef struct yep_sizing_hints {
|
|
23
|
+
size_t min_capacity; /* explicit floor */
|
|
24
|
+
size_t newline_count; /* '\n' occurrences in the input */
|
|
25
|
+
size_t colon_count; /* ':' occurrences */
|
|
26
|
+
size_t quote_count; /* '"' occurrences */
|
|
27
|
+
} yep_sizing_hints;
|
|
28
|
+
|
|
29
|
+
typedef struct yep_arena_stats {
|
|
30
|
+
size_t blocks;
|
|
31
|
+
size_t capacity; /* total payload bytes across blocks */
|
|
32
|
+
size_t used; /* bytes handed out (excludes alignment loss) */
|
|
33
|
+
size_t sys_allocs; /* system allocation count (the 0-after-reserve gate) */
|
|
34
|
+
} yep_arena_stats;
|
|
35
|
+
|
|
36
|
+
typedef struct yep_arena yep_arena;
|
|
37
|
+
|
|
38
|
+
/* hints may be NULL (16 KiB default). */
|
|
39
|
+
yep_arena* yep_arena_create(const yep_allocator* sys, const yep_sizing_hints* hints);
|
|
40
|
+
void yep_arena_destroy(yep_arena* arena);
|
|
41
|
+
|
|
42
|
+
/* Allocates size bytes with power-of-two alignment. Returns NULL on
|
|
43
|
+
* allocation failure or absurd align. */
|
|
44
|
+
void* yep_arena_alloc(yep_arena* arena, size_t size, size_t align);
|
|
45
|
+
|
|
46
|
+
yep_arena_stats yep_arena_get_stats(const yep_arena* arena);
|
|
47
|
+
|
|
48
|
+
#ifdef __cplusplus
|
|
49
|
+
}
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
#endif /* YEP_ARENA_H */
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/* pool.c — bump pool implementation. */
|
|
2
|
+
|
|
3
|
+
#include <stdint.h>
|
|
4
|
+
|
|
5
|
+
#include "pool.h"
|
|
6
|
+
|
|
7
|
+
#define YEP_POOL_DEFAULT_BLOCK (4u * 1024u)
|
|
8
|
+
#define YEP_POOL_MIN_BLOCK 256u
|
|
9
|
+
|
|
10
|
+
typedef struct yep_block {
|
|
11
|
+
struct yep_block* next;
|
|
12
|
+
size_t size; /* payload bytes (excludes the header) */
|
|
13
|
+
size_t used;
|
|
14
|
+
} yep_block;
|
|
15
|
+
|
|
16
|
+
struct yep_pool {
|
|
17
|
+
const yep_allocator* sys;
|
|
18
|
+
yep_block* head;
|
|
19
|
+
size_t block_size;
|
|
20
|
+
size_t blocks;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
static size_t yep_round_up(size_t n, size_t align) {
|
|
24
|
+
return (n + align - 1) & ~(align - 1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static int yep_align_ok(size_t align) {
|
|
28
|
+
return align != 0 && (align & (align - 1)) == 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static yep_block* yep_block_new(const yep_allocator* sys, size_t payload) {
|
|
32
|
+
yep_block* b = yep_alloc(sys, sizeof(yep_block) + payload);
|
|
33
|
+
if (b == NULL) {
|
|
34
|
+
return NULL;
|
|
35
|
+
}
|
|
36
|
+
b->next = NULL;
|
|
37
|
+
b->size = payload;
|
|
38
|
+
b->used = 0;
|
|
39
|
+
return b;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void* yep_pool_alloc(yep_pool* pool, size_t size, size_t align) {
|
|
43
|
+
if (pool == NULL || size == 0 || !yep_align_ok(align)) {
|
|
44
|
+
return NULL;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
yep_block* b = pool->head;
|
|
48
|
+
if (b == NULL) { /* the lazy first block (#157) */
|
|
49
|
+
b = yep_block_new(pool->sys, pool->block_size);
|
|
50
|
+
if (b == NULL) {
|
|
51
|
+
return NULL;
|
|
52
|
+
}
|
|
53
|
+
b->next = NULL;
|
|
54
|
+
pool->head = b;
|
|
55
|
+
pool->blocks = 1;
|
|
56
|
+
}
|
|
57
|
+
uintptr_t base = (uintptr_t)b + sizeof(yep_block);
|
|
58
|
+
uintptr_t start = yep_round_up(base + b->used, align);
|
|
59
|
+
|
|
60
|
+
if (start + size > base + b->size) {
|
|
61
|
+
/* Dedicated-or-default new block, sized so the aligned request
|
|
62
|
+
* always fits (malloc returns at least 16-byte-aligned memory, so
|
|
63
|
+
* the correction is < align). */
|
|
64
|
+
size_t payload = pool->block_size;
|
|
65
|
+
if (payload < size + align + sizeof(yep_block)) {
|
|
66
|
+
payload = size + align + sizeof(yep_block);
|
|
67
|
+
}
|
|
68
|
+
b = yep_block_new(pool->sys, payload);
|
|
69
|
+
if (b == NULL) {
|
|
70
|
+
return NULL;
|
|
71
|
+
}
|
|
72
|
+
b->next = pool->head;
|
|
73
|
+
pool->head = b;
|
|
74
|
+
pool->blocks++;
|
|
75
|
+
base = (uintptr_t)b + sizeof(yep_block);
|
|
76
|
+
start = yep_round_up(base, align);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
b->used = start + size - base;
|
|
80
|
+
return (void*)start;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
yep_pool* yep_pool_create(const yep_allocator* sys, size_t block_size) {
|
|
84
|
+
if (sys == NULL) {
|
|
85
|
+
return NULL;
|
|
86
|
+
}
|
|
87
|
+
if (block_size == 0) {
|
|
88
|
+
block_size = YEP_POOL_DEFAULT_BLOCK;
|
|
89
|
+
}
|
|
90
|
+
if (block_size < YEP_POOL_MIN_BLOCK) {
|
|
91
|
+
block_size = YEP_POOL_MIN_BLOCK;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
yep_pool* p = yep_alloc(sys, sizeof(yep_pool));
|
|
95
|
+
if (p == NULL) {
|
|
96
|
+
return NULL;
|
|
97
|
+
}
|
|
98
|
+
p->sys = sys;
|
|
99
|
+
p->block_size = block_size;
|
|
100
|
+
/* #157: the first block is lazy — one fewer eager allocation per
|
|
101
|
+
* document; pool_alloc materializes it on first use */
|
|
102
|
+
p->head = NULL;
|
|
103
|
+
p->blocks = 0;
|
|
104
|
+
return p;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void yep_pool_destroy(yep_pool* pool) {
|
|
108
|
+
if (pool == NULL) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
yep_block* b = pool->head;
|
|
112
|
+
while (b != NULL) {
|
|
113
|
+
yep_block* next = b->next;
|
|
114
|
+
yep_free(pool->sys, b);
|
|
115
|
+
b = next;
|
|
116
|
+
}
|
|
117
|
+
yep_free(pool->sys, pool);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
size_t yep_pool_block_count(const yep_pool* pool) {
|
|
121
|
+
return pool ? pool->blocks : 0;
|
|
122
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* pool.h — O(1) bump pool for small, same-lifetime objects.
|
|
2
|
+
*
|
|
3
|
+
* Allocation is pointer-bump within the current block; oversized requests
|
|
4
|
+
* get a dedicated block. Destruction frees every block in one walk. The
|
|
5
|
+
* pool never frees individual objects (arena-of-record semantics for
|
|
6
|
+
* transient same-lifetime work, e.g. per-parse scratch).
|
|
7
|
+
*/
|
|
8
|
+
#ifndef YEP_POOL_H
|
|
9
|
+
#define YEP_POOL_H
|
|
10
|
+
|
|
11
|
+
#include <stddef.h>
|
|
12
|
+
|
|
13
|
+
#include "allocator.h"
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
typedef struct yep_pool yep_pool;
|
|
20
|
+
|
|
21
|
+
/* block_size 0 selects the 4 KiB default; rounded up to at least 256 B. */
|
|
22
|
+
yep_pool* yep_pool_create(const yep_allocator* sys, size_t block_size);
|
|
23
|
+
void yep_pool_destroy(yep_pool* pool);
|
|
24
|
+
|
|
25
|
+
/* Bump-allocates size bytes with power-of-two alignment. Returns NULL on
|
|
26
|
+
* allocation failure or absurd align. */
|
|
27
|
+
void* yep_pool_alloc(yep_pool* pool, size_t size, size_t align);
|
|
28
|
+
|
|
29
|
+
/* Number of blocks allocated so far (observability for tests + ledger). */
|
|
30
|
+
size_t yep_pool_block_count(const yep_pool* pool);
|
|
31
|
+
|
|
32
|
+
#ifdef __cplusplus
|
|
33
|
+
}
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#endif /* YEP_POOL_H */
|