tigerbeetle-node 0.9.0 → 0.10.0
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.
- package/README.md +3 -2
- package/dist/index.d.ts +66 -61
- package/dist/index.js +66 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +5 -0
- package/src/node.zig +17 -18
- package/src/tigerbeetle/scripts/benchmark.bat +4 -3
- package/src/tigerbeetle/scripts/benchmark.sh +25 -10
- package/src/tigerbeetle/scripts/install.sh +2 -1
- package/src/tigerbeetle/scripts/install_zig.sh +14 -18
- package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +12 -3
- package/src/tigerbeetle/scripts/vopr.sh +5 -5
- package/src/tigerbeetle/src/benchmark.zig +17 -9
- package/src/tigerbeetle/src/benchmark_array_search.zig +317 -0
- package/src/tigerbeetle/src/benchmarks/perf.zig +299 -0
- package/src/tigerbeetle/src/c/tb_client/context.zig +103 -0
- package/src/tigerbeetle/src/c/tb_client/packet.zig +80 -0
- package/src/tigerbeetle/src/c/tb_client/signal.zig +288 -0
- package/src/tigerbeetle/src/c/tb_client/thread.zig +329 -0
- package/src/tigerbeetle/src/c/tb_client.h +201 -0
- package/src/tigerbeetle/src/c/tb_client.zig +101 -0
- package/src/tigerbeetle/src/c/test.zig +1 -0
- package/src/tigerbeetle/src/cli.zig +142 -83
- package/src/tigerbeetle/src/config.zig +119 -10
- package/src/tigerbeetle/src/demo.zig +12 -8
- package/src/tigerbeetle/src/demo_05_post_pending_transfers.zig +2 -2
- package/src/tigerbeetle/src/ewah.zig +318 -0
- package/src/tigerbeetle/src/ewah_benchmark.zig +121 -0
- package/src/tigerbeetle/src/eytzinger_benchmark.zig +317 -0
- package/src/tigerbeetle/src/fifo.zig +17 -1
- package/src/tigerbeetle/src/io/darwin.zig +12 -10
- package/src/tigerbeetle/src/io/linux.zig +25 -9
- package/src/tigerbeetle/src/io/windows.zig +13 -9
- package/src/tigerbeetle/src/iops.zig +101 -0
- package/src/tigerbeetle/src/lsm/binary_search.zig +214 -0
- package/src/tigerbeetle/src/lsm/bloom_filter.zig +82 -0
- package/src/tigerbeetle/src/lsm/compaction.zig +603 -0
- package/src/tigerbeetle/src/lsm/composite_key.zig +75 -0
- package/src/tigerbeetle/src/lsm/direction.zig +11 -0
- package/src/tigerbeetle/src/lsm/eytzinger.zig +587 -0
- package/src/tigerbeetle/src/lsm/forest.zig +630 -0
- package/src/tigerbeetle/src/lsm/grid.zig +473 -0
- package/src/tigerbeetle/src/lsm/groove.zig +939 -0
- package/src/tigerbeetle/src/lsm/k_way_merge.zig +452 -0
- package/src/tigerbeetle/src/lsm/level_iterator.zig +296 -0
- package/src/tigerbeetle/src/lsm/manifest.zig +680 -0
- package/src/tigerbeetle/src/lsm/manifest_level.zig +1169 -0
- package/src/tigerbeetle/src/lsm/manifest_log.zig +904 -0
- package/src/tigerbeetle/src/lsm/node_pool.zig +231 -0
- package/src/tigerbeetle/src/lsm/posted_groove.zig +399 -0
- package/src/tigerbeetle/src/lsm/segmented_array.zig +998 -0
- package/src/tigerbeetle/src/lsm/set_associative_cache.zig +844 -0
- package/src/tigerbeetle/src/lsm/table.zig +932 -0
- package/src/tigerbeetle/src/lsm/table_immutable.zig +196 -0
- package/src/tigerbeetle/src/lsm/table_iterator.zig +295 -0
- package/src/tigerbeetle/src/lsm/table_mutable.zig +123 -0
- package/src/tigerbeetle/src/lsm/test.zig +429 -0
- package/src/tigerbeetle/src/lsm/tree.zig +1085 -0
- package/src/tigerbeetle/src/main.zig +119 -109
- package/src/tigerbeetle/src/message_bus.zig +49 -48
- package/src/tigerbeetle/src/message_pool.zig +15 -2
- package/src/tigerbeetle/src/ring_buffer.zig +126 -30
- package/src/tigerbeetle/src/simulator.zig +76 -44
- package/src/tigerbeetle/src/state_machine.zig +1022 -585
- package/src/tigerbeetle/src/storage.zig +46 -16
- package/src/tigerbeetle/src/test/cluster.zig +109 -63
- package/src/tigerbeetle/src/test/message_bus.zig +15 -24
- package/src/tigerbeetle/src/test/network.zig +26 -17
- package/src/tigerbeetle/src/test/state_checker.zig +7 -5
- package/src/tigerbeetle/src/test/state_machine.zig +159 -69
- package/src/tigerbeetle/src/test/storage.zig +57 -28
- package/src/tigerbeetle/src/tigerbeetle.zig +5 -0
- package/src/tigerbeetle/src/unit_tests.zig +8 -0
- package/src/tigerbeetle/src/util.zig +51 -0
- package/src/tigerbeetle/src/vsr/client.zig +21 -7
- package/src/tigerbeetle/src/vsr/journal.zig +154 -167
- package/src/tigerbeetle/src/vsr/replica.zig +744 -226
- package/src/tigerbeetle/src/vsr/superblock.zig +1743 -0
- package/src/tigerbeetle/src/vsr/superblock_client_table.zig +258 -0
- package/src/tigerbeetle/src/vsr/superblock_free_set.zig +644 -0
- package/src/tigerbeetle/src/vsr/superblock_manifest.zig +546 -0
- package/src/tigerbeetle/src/vsr.zig +43 -115
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// Copyright (c) 2015-2021, Zig contributors
|
|
2
|
+
// Backported from https://github.com/ziglang/zig/blob/master/lib/std/os/linux.zig
|
|
3
|
+
// TODO Remove this file once we upgrade to Zig 0.9.0.
|
|
4
|
+
const std = @import("std");
|
|
5
|
+
const pid_t = std.os.linux.pid_t;
|
|
6
|
+
const fd_t = std.os.linux.fd_t;
|
|
7
|
+
|
|
8
|
+
pub fn perf_event_open(
|
|
9
|
+
attr: *perf_event_attr,
|
|
10
|
+
pid: pid_t,
|
|
11
|
+
cpu: i32,
|
|
12
|
+
group_fd: fd_t,
|
|
13
|
+
flags: usize,
|
|
14
|
+
) !fd_t {
|
|
15
|
+
const rc = perf_event_open_internal(attr, pid, cpu, group_fd, flags);
|
|
16
|
+
const errno = std.os.errno(rc);
|
|
17
|
+
if (errno != 0) {
|
|
18
|
+
std.log.err("perf_event_open_internal errno={}", .{errno});
|
|
19
|
+
return error.Unexpected;
|
|
20
|
+
}
|
|
21
|
+
return @intCast(fd_t, rc);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn perf_event_open_internal(
|
|
25
|
+
attr: *perf_event_attr,
|
|
26
|
+
pid: pid_t,
|
|
27
|
+
cpu: i32,
|
|
28
|
+
group_fd: fd_t,
|
|
29
|
+
flags: usize,
|
|
30
|
+
) usize {
|
|
31
|
+
return std.os.linux.syscall5(
|
|
32
|
+
.perf_event_open,
|
|
33
|
+
@ptrToInt(attr),
|
|
34
|
+
@bitCast(usize, @as(isize, pid)),
|
|
35
|
+
@bitCast(usize, @as(isize, cpu)),
|
|
36
|
+
@bitCast(usize, @as(isize, group_fd)),
|
|
37
|
+
flags,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
pub const perf_event_attr = extern struct {
|
|
42
|
+
/// Major type: hardware/software/tracepoint/etc.
|
|
43
|
+
type: PERF.TYPE = undefined,
|
|
44
|
+
/// Size of the attr structure, for fwd/bwd compat.
|
|
45
|
+
size: u32 = @sizeOf(perf_event_attr),
|
|
46
|
+
/// Type specific configuration information.
|
|
47
|
+
config: u64 = 0,
|
|
48
|
+
|
|
49
|
+
sample_period_or_freq: u64 = 0,
|
|
50
|
+
sample_type: u64 = 0,
|
|
51
|
+
read_format: u64 = 0,
|
|
52
|
+
|
|
53
|
+
flags: packed struct {
|
|
54
|
+
/// off by default
|
|
55
|
+
disabled: bool = false,
|
|
56
|
+
/// children inherit it
|
|
57
|
+
inherit: bool = false,
|
|
58
|
+
/// must always be on PMU
|
|
59
|
+
pinned: bool = false,
|
|
60
|
+
/// only group on PMU
|
|
61
|
+
exclusive: bool = false,
|
|
62
|
+
/// don't count user
|
|
63
|
+
exclude_user: bool = false,
|
|
64
|
+
/// ditto kernel
|
|
65
|
+
exclude_kernel: bool = false,
|
|
66
|
+
/// ditto hypervisor
|
|
67
|
+
exclude_hv: bool = false,
|
|
68
|
+
/// don't count when idle
|
|
69
|
+
exclude_idle: bool = false,
|
|
70
|
+
/// include mmap data
|
|
71
|
+
mmap: bool = false,
|
|
72
|
+
/// include comm data
|
|
73
|
+
comm: bool = false,
|
|
74
|
+
/// use freq, not period
|
|
75
|
+
freq: bool = false,
|
|
76
|
+
/// per task counts
|
|
77
|
+
inherit_stat: bool = false,
|
|
78
|
+
/// next exec enables
|
|
79
|
+
enable_on_exec: bool = false,
|
|
80
|
+
/// trace fork/exit
|
|
81
|
+
task: bool = false,
|
|
82
|
+
/// wakeup_watermark
|
|
83
|
+
watermark: bool = false,
|
|
84
|
+
/// precise_ip:
|
|
85
|
+
///
|
|
86
|
+
/// 0 - SAMPLE_IP can have arbitrary skid
|
|
87
|
+
/// 1 - SAMPLE_IP must have constant skid
|
|
88
|
+
/// 2 - SAMPLE_IP requested to have 0 skid
|
|
89
|
+
/// 3 - SAMPLE_IP must have 0 skid
|
|
90
|
+
///
|
|
91
|
+
/// See also PERF_RECORD_MISC_EXACT_IP
|
|
92
|
+
/// skid constraint
|
|
93
|
+
precise_ip: u2 = 0,
|
|
94
|
+
/// non-exec mmap data
|
|
95
|
+
mmap_data: bool = false,
|
|
96
|
+
/// sample_type all events
|
|
97
|
+
sample_id_all: bool = false,
|
|
98
|
+
|
|
99
|
+
/// don't count in host
|
|
100
|
+
exclude_host: bool = false,
|
|
101
|
+
/// don't count in guest
|
|
102
|
+
exclude_guest: bool = false,
|
|
103
|
+
|
|
104
|
+
/// exclude kernel callchains
|
|
105
|
+
exclude_callchain_kernel: bool = false,
|
|
106
|
+
/// exclude user callchains
|
|
107
|
+
exclude_callchain_user: bool = false,
|
|
108
|
+
/// include mmap with inode data
|
|
109
|
+
mmap2: bool = false,
|
|
110
|
+
/// flag comm events that are due to an exec
|
|
111
|
+
comm_exec: bool = false,
|
|
112
|
+
/// use @clockid for time fields
|
|
113
|
+
use_clockid: bool = false,
|
|
114
|
+
/// context switch data
|
|
115
|
+
context_switch: bool = false,
|
|
116
|
+
/// Write ring buffer from end to beginning
|
|
117
|
+
write_backward: bool = false,
|
|
118
|
+
/// include namespaces data
|
|
119
|
+
namespaces: bool = false,
|
|
120
|
+
|
|
121
|
+
__reserved_1: u35 = 0,
|
|
122
|
+
} = .{},
|
|
123
|
+
/// wakeup every n events, or
|
|
124
|
+
/// bytes before wakeup
|
|
125
|
+
wakeup_events_or_watermark: u32 = 0,
|
|
126
|
+
|
|
127
|
+
bp_type: u32 = 0,
|
|
128
|
+
|
|
129
|
+
/// This field is also used for:
|
|
130
|
+
/// bp_addr
|
|
131
|
+
/// kprobe_func for perf_kprobe
|
|
132
|
+
/// uprobe_path for perf_uprobe
|
|
133
|
+
config1: u64 = 0,
|
|
134
|
+
/// This field is also used for:
|
|
135
|
+
/// bp_len
|
|
136
|
+
/// kprobe_addr when kprobe_func == null
|
|
137
|
+
/// probe_offset for perf_[k,u]probe
|
|
138
|
+
config2: u64 = 0,
|
|
139
|
+
|
|
140
|
+
/// enum perf_branch_sample_type
|
|
141
|
+
branch_sample_type: u64 = 0,
|
|
142
|
+
|
|
143
|
+
/// Defines set of user regs to dump on samples.
|
|
144
|
+
/// See asm/perf_regs.h for details.
|
|
145
|
+
sample_regs_user: u64 = 0,
|
|
146
|
+
|
|
147
|
+
/// Defines size of the user stack to dump on samples.
|
|
148
|
+
sample_stack_user: u32 = 0,
|
|
149
|
+
|
|
150
|
+
clockid: i32 = 0,
|
|
151
|
+
/// Defines set of regs to dump for each sample
|
|
152
|
+
/// state captured on:
|
|
153
|
+
/// - precise = 0: PMU interrupt
|
|
154
|
+
/// - precise > 0: sampled instruction
|
|
155
|
+
///
|
|
156
|
+
/// See asm/perf_regs.h for details.
|
|
157
|
+
sample_regs_intr: u64 = 0,
|
|
158
|
+
|
|
159
|
+
/// Wakeup watermark for AUX area
|
|
160
|
+
aux_watermark: u32 = 0,
|
|
161
|
+
sample_max_stack: u16 = 0,
|
|
162
|
+
/// Align to u64
|
|
163
|
+
__reserved_2: u16 = 0,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
pub const PERF = struct {
|
|
167
|
+
pub const TYPE = enum(u32) {
|
|
168
|
+
HARDWARE,
|
|
169
|
+
SOFTWARE,
|
|
170
|
+
TRACEPOINT,
|
|
171
|
+
HW_CACHE,
|
|
172
|
+
RAW,
|
|
173
|
+
BREAKPOINT,
|
|
174
|
+
MAX,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
pub const COUNT = struct {
|
|
178
|
+
pub const HW = enum(u32) {
|
|
179
|
+
CPU_CYCLES,
|
|
180
|
+
INSTRUCTIONS,
|
|
181
|
+
CACHE_REFERENCES,
|
|
182
|
+
CACHE_MISSES,
|
|
183
|
+
BRANCH_INSTRUCTIONS,
|
|
184
|
+
BRANCH_MISSES,
|
|
185
|
+
BUS_CYCLES,
|
|
186
|
+
STALLED_CYCLES_FRONTEND,
|
|
187
|
+
STALLED_CYCLES_BACKEND,
|
|
188
|
+
REF_CPU_CYCLES,
|
|
189
|
+
MAX,
|
|
190
|
+
|
|
191
|
+
pub const CACHE = enum(u32) {
|
|
192
|
+
L1D,
|
|
193
|
+
L1I,
|
|
194
|
+
LL,
|
|
195
|
+
DTLB,
|
|
196
|
+
ITLB,
|
|
197
|
+
BPU,
|
|
198
|
+
NODE,
|
|
199
|
+
MAX,
|
|
200
|
+
|
|
201
|
+
pub const OP = enum(u32) {
|
|
202
|
+
READ,
|
|
203
|
+
WRITE,
|
|
204
|
+
PREFETCH,
|
|
205
|
+
MAX,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
pub const RESULT = enum(u32) {
|
|
209
|
+
ACCESS,
|
|
210
|
+
MISS,
|
|
211
|
+
MAX,
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
pub const SW = enum(u32) {
|
|
217
|
+
CPU_CLOCK,
|
|
218
|
+
TASK_CLOCK,
|
|
219
|
+
PAGE_FAULTS,
|
|
220
|
+
CONTEXT_SWITCHES,
|
|
221
|
+
CPU_MIGRATIONS,
|
|
222
|
+
PAGE_FAULTS_MIN,
|
|
223
|
+
PAGE_FAULTS_MAJ,
|
|
224
|
+
ALIGNMENT_FAULTS,
|
|
225
|
+
EMULATION_FAULTS,
|
|
226
|
+
DUMMY,
|
|
227
|
+
BPF_OUTPUT,
|
|
228
|
+
MAX,
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
pub const SAMPLE = struct {
|
|
233
|
+
pub const IP = 1;
|
|
234
|
+
pub const TID = 2;
|
|
235
|
+
pub const TIME = 4;
|
|
236
|
+
pub const ADDR = 8;
|
|
237
|
+
pub const READ = 16;
|
|
238
|
+
pub const CALLCHAIN = 32;
|
|
239
|
+
pub const ID = 64;
|
|
240
|
+
pub const CPU = 128;
|
|
241
|
+
pub const PERIOD = 256;
|
|
242
|
+
pub const STREAM_ID = 512;
|
|
243
|
+
pub const RAW = 1024;
|
|
244
|
+
pub const BRANCH_STACK = 2048;
|
|
245
|
+
pub const REGS_USER = 4096;
|
|
246
|
+
pub const STACK_USER = 8192;
|
|
247
|
+
pub const WEIGHT = 16384;
|
|
248
|
+
pub const DATA_SRC = 32768;
|
|
249
|
+
pub const IDENTIFIER = 65536;
|
|
250
|
+
pub const TRANSACTION = 131072;
|
|
251
|
+
pub const REGS_INTR = 262144;
|
|
252
|
+
pub const PHYS_ADDR = 524288;
|
|
253
|
+
pub const MAX = 1048576;
|
|
254
|
+
|
|
255
|
+
pub const BRANCH = struct {
|
|
256
|
+
pub const USER = 1 << 0;
|
|
257
|
+
pub const KERNEL = 1 << 1;
|
|
258
|
+
pub const HV = 1 << 2;
|
|
259
|
+
pub const ANY = 1 << 3;
|
|
260
|
+
pub const ANY_CALL = 1 << 4;
|
|
261
|
+
pub const ANY_RETURN = 1 << 5;
|
|
262
|
+
pub const IND_CALL = 1 << 6;
|
|
263
|
+
pub const ABORT_TX = 1 << 7;
|
|
264
|
+
pub const IN_TX = 1 << 8;
|
|
265
|
+
pub const NO_TX = 1 << 9;
|
|
266
|
+
pub const COND = 1 << 10;
|
|
267
|
+
pub const CALL_STACK = 1 << 11;
|
|
268
|
+
pub const IND_JUMP = 1 << 12;
|
|
269
|
+
pub const CALL = 1 << 13;
|
|
270
|
+
pub const NO_FLAGS = 1 << 14;
|
|
271
|
+
pub const NO_CYCLES = 1 << 15;
|
|
272
|
+
pub const TYPE_SAVE = 1 << 16;
|
|
273
|
+
pub const MAX = 1 << 17;
|
|
274
|
+
};
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
pub const FLAG = struct {
|
|
278
|
+
pub const FD_NO_GROUP = 1 << 0;
|
|
279
|
+
pub const FD_OUTPUT = 1 << 1;
|
|
280
|
+
pub const PID_CGROUP = 1 << 2;
|
|
281
|
+
pub const FD_CLOEXEC = 1 << 3;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
pub const EVENT_IOC = struct {
|
|
285
|
+
pub const ENABLE = 9216;
|
|
286
|
+
pub const DISABLE = 9217;
|
|
287
|
+
pub const REFRESH = 9218;
|
|
288
|
+
pub const RESET = 9219;
|
|
289
|
+
pub const PERIOD = 1074275332;
|
|
290
|
+
pub const SET_OUTPUT = 9221;
|
|
291
|
+
pub const SET_FILTER = 1074275334;
|
|
292
|
+
pub const SET_BPF = 1074013192;
|
|
293
|
+
pub const PAUSE_OUTPUT = 1074013193;
|
|
294
|
+
pub const QUERY_BPF = 3221758986;
|
|
295
|
+
pub const MODIFY_ATTRIBUTES = 1074275339;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
pub const IOC_FLAG_GROUP = 1;
|
|
299
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const ThreadType = @import("thread.zig").ThreadType;
|
|
3
|
+
|
|
4
|
+
const api = @import("../tb_client.zig");
|
|
5
|
+
const tb_status_t = api.tb_status_t;
|
|
6
|
+
const tb_client_t = api.tb_client_t;
|
|
7
|
+
const tb_completion_t = api.tb_completion_t;
|
|
8
|
+
const tb_packet_t = api.tb_packet_t;
|
|
9
|
+
const tb_packet_list_t = api.tb_packet_list_t;
|
|
10
|
+
|
|
11
|
+
pub const ContextImplementation = struct {
|
|
12
|
+
submit_fn: fn (*ContextImplementation, *tb_packet_list_t) void,
|
|
13
|
+
deinit_fn: fn (*ContextImplementation) void,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
pub fn ContextType(
|
|
17
|
+
comptime StateMachine: type,
|
|
18
|
+
comptime MessageBus: type,
|
|
19
|
+
) type {
|
|
20
|
+
return struct {
|
|
21
|
+
const Context = @This();
|
|
22
|
+
const Thread = ThreadType(StateMachine, MessageBus);
|
|
23
|
+
|
|
24
|
+
allocator: std.mem.Allocator,
|
|
25
|
+
on_completion_ctx: usize,
|
|
26
|
+
on_completion_fn: tb_completion_t,
|
|
27
|
+
implementation: ContextImplementation,
|
|
28
|
+
thread: Thread,
|
|
29
|
+
|
|
30
|
+
pub fn init(
|
|
31
|
+
allocator: std.mem.Allocator,
|
|
32
|
+
out_tb_client: *tb_client_t,
|
|
33
|
+
out_packets: *tb_packet_list_t,
|
|
34
|
+
cluster_id: u32,
|
|
35
|
+
addresses_ptr: [*:0]const u8,
|
|
36
|
+
addresses_len: u32,
|
|
37
|
+
num_packets: u32,
|
|
38
|
+
on_completion_ctx: usize,
|
|
39
|
+
on_completion_fn: tb_completion_t,
|
|
40
|
+
) tb_status_t {
|
|
41
|
+
const context = allocator.create(Context) catch return .out_of_memory;
|
|
42
|
+
context.allocator = allocator;
|
|
43
|
+
context.on_completion_ctx = on_completion_ctx;
|
|
44
|
+
context.on_completion_fn = on_completion_fn;
|
|
45
|
+
|
|
46
|
+
out_tb_client.* = api.context_to_client(&context.implementation);
|
|
47
|
+
context.implementation = .{
|
|
48
|
+
.submit_fn = Context.on_submit,
|
|
49
|
+
.deinit_fn = Context.on_deinit,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const addresses = @ptrCast([*]const u8, addresses_ptr)[0..addresses_len];
|
|
53
|
+
context.thread.init(
|
|
54
|
+
allocator,
|
|
55
|
+
cluster_id,
|
|
56
|
+
addresses,
|
|
57
|
+
num_packets,
|
|
58
|
+
Context.on_completion,
|
|
59
|
+
) catch |err| {
|
|
60
|
+
allocator.destroy(context);
|
|
61
|
+
return switch (err) {
|
|
62
|
+
error.Unexpected => .unexpected,
|
|
63
|
+
error.OutOfMemory => .out_of_memory,
|
|
64
|
+
error.InvalidAddress => .invalid_address,
|
|
65
|
+
error.SystemResources => .system_resources,
|
|
66
|
+
error.NetworkSubsystemFailed => .network_subsystem,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
var list = tb_packet_list_t{};
|
|
71
|
+
for (context.thread.packets) |*packet| {
|
|
72
|
+
list.push(tb_packet_list_t.from(packet));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
out_packets.* = list;
|
|
76
|
+
return .success;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fn on_submit(implementation: *ContextImplementation, packets: *tb_packet_list_t) void {
|
|
80
|
+
const context = @fieldParentPtr(Context, "implementation", implementation);
|
|
81
|
+
context.thread.submit(packets.*);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fn on_deinit(implementation: *ContextImplementation) void {
|
|
85
|
+
const context = @fieldParentPtr(Context, "implementation", implementation);
|
|
86
|
+
context.thread.deinit();
|
|
87
|
+
context.allocator.destroy(context);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
fn on_completion(thread: *Thread, packet: *tb_packet_t, result: ?[]const u8) void {
|
|
91
|
+
const context = @fieldParentPtr(Context, "thread", thread);
|
|
92
|
+
const tb_client = api.context_to_client(&context.implementation);
|
|
93
|
+
|
|
94
|
+
context.on_completion_fn(
|
|
95
|
+
context.on_completion_ctx,
|
|
96
|
+
tb_client,
|
|
97
|
+
packet,
|
|
98
|
+
if (result) |r| r.ptr else null,
|
|
99
|
+
if (result) |r| @intCast(u32, r.len) else 0,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const assert = std.debug.assert;
|
|
3
|
+
const Atomic = std.atomic.Atomic;
|
|
4
|
+
|
|
5
|
+
pub const Packet = extern struct {
|
|
6
|
+
next: ?*Packet,
|
|
7
|
+
user_data: usize,
|
|
8
|
+
operation: u8,
|
|
9
|
+
status: Status,
|
|
10
|
+
data_size: u32,
|
|
11
|
+
data: [*]const u8,
|
|
12
|
+
|
|
13
|
+
pub const Status = enum(u8) {
|
|
14
|
+
ok,
|
|
15
|
+
too_much_data,
|
|
16
|
+
invalid_operation,
|
|
17
|
+
invalid_data_size,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
pub const List = extern struct {
|
|
21
|
+
head: ?*Packet = null,
|
|
22
|
+
tail: ?*Packet = null,
|
|
23
|
+
|
|
24
|
+
pub fn from(packet: *Packet) List {
|
|
25
|
+
packet.next = null;
|
|
26
|
+
return List{
|
|
27
|
+
.head = packet,
|
|
28
|
+
.tail = packet,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn push(self: *List, list: List) void {
|
|
33
|
+
const prev = if (self.tail) |tail| &tail.next else &self.head;
|
|
34
|
+
prev.* = list.head orelse return;
|
|
35
|
+
self.tail = list.tail orelse unreachable;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pub fn peek(self: List) ?*Packet {
|
|
39
|
+
return self.head orelse {
|
|
40
|
+
assert(self.tail == null);
|
|
41
|
+
return null;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pub fn pop(self: *List) ?*Packet {
|
|
46
|
+
const packet = self.head orelse return null;
|
|
47
|
+
self.head = packet.next;
|
|
48
|
+
if (self.head == null) self.tail = null;
|
|
49
|
+
return packet;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
pub const Stack = struct {
|
|
54
|
+
pushed: Atomic(?*Packet) = Atomic(?*Packet).init(null),
|
|
55
|
+
popped: ?*Packet = null,
|
|
56
|
+
|
|
57
|
+
pub fn push(self: *Stack, list: List) void {
|
|
58
|
+
const head = list.head orelse return;
|
|
59
|
+
const tail = list.tail orelse unreachable;
|
|
60
|
+
|
|
61
|
+
var pushed = self.pushed.load(.Monotonic);
|
|
62
|
+
while (true) {
|
|
63
|
+
tail.next = pushed;
|
|
64
|
+
pushed = self.pushed.tryCompareAndSwap(
|
|
65
|
+
pushed,
|
|
66
|
+
head,
|
|
67
|
+
.Release,
|
|
68
|
+
.Monotonic,
|
|
69
|
+
) orelse break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
pub fn pop(self: *Stack) ?*Packet {
|
|
74
|
+
if (self.popped == null) self.popped = self.pushed.swap(null, .Acquire);
|
|
75
|
+
const packet = self.popped orelse return null;
|
|
76
|
+
self.popped = packet.next;
|
|
77
|
+
return packet;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
};
|