From 76a40ec20cd3240af81cea7cc79bb921e3802c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20Vikstr=C3=B6m?= Date: Tue, 13 Oct 2026 16:02:45 +0200 Subject: [PATCH] feat: bound CON response storage --- CHANGELOG.md | 4 + README.md | 109 +- bench/client.zig | 157 +- bench/con-buffers-control.patch | 68 + bench/con-buffers.py | 109 ++ docs/CON_BUFFERS.md | 155 ++ docs/CON_BUFFERS_ALLOCATIONS.json | 24 + docs/CON_BUFFERS_INITIAL_RESULTS.json | 2401 ++++++++++++++++++++++++ docs/CON_BUFFERS_PLAIN_RESULTS.json | 1212 ++++++++++++ docs/CON_BUFFERS_RESULTS.json | 2401 ++++++++++++++++++++++++ docs/CON_BUFFERS_SMP_LONG_RESULTS.json | 816 ++++++++ examples/client_example.zig | 7 +- src/Client.zig | 1153 ++++++------ src/dtls/integration_test.zig | 35 +- src/packet_view.zig | 103 + src/root.zig | 16 +- src/uri.zig | 3 +- 17 files changed, 8100 insertions(+), 673 deletions(-) create mode 100644 bench/con-buffers-control.patch create mode 100644 bench/con-buffers.py create mode 100644 docs/CON_BUFFERS.md create mode 100644 docs/CON_BUFFERS_ALLOCATIONS.json create mode 100644 docs/CON_BUFFERS_INITIAL_RESULTS.json create mode 100644 docs/CON_BUFFERS_PLAIN_RESULTS.json create mode 100644 docs/CON_BUFFERS_RESULTS.json create mode 100644 docs/CON_BUFFERS_SMP_LONG_RESULTS.json create mode 100644 src/packet_view.zig diff --git a/CHANGELOG.md b/CHANGELOG.md index bedb600..1fc9f70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog ## Unreleased +- Breaking: CON response APIs take caller-owned buffers; remove result allocation/deinit and sentinel flags +- Bound Block2 reassembly; correlate capacity failures and support local request cancellation +- Preserve Block2 tokens/handles, sort continuation options, and handle empty ACK/RST and separate replies +- Synchronize DTLS benchmark workers and report common-wall successful-response throughput; add allocator selection - Require Zig 0.16.0; replace public peer addresses with `std.Io.net.IpAddress` - Retain the Linux io_uring backend with native-address conversion at syscall boundaries - Use monotonic clocks for protocol deadlines and timing diff --git a/README.md b/README.md index 974ee63..200579d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ High-performance CoAP server and client library for Zig, built on Linux io_uring ### Highlights - **Simple handler interface** — `fn(Request) ?Response`, with context handlers and error wrappers -- **Zero allocations in the hot path** — pre-allocated pools, arena resets per batch +- **Bounded CON response storage** — caller-owned datagram, option, and Block2 buffers; no response heap allocation - **Multi-threaded** — SO_REUSEPORT, no shared state between threads - **DTLS 1.2 PSK** — pure Zig AES-128-CCM-8, stateless cookies, anti-replay - **IPv4 and IPv6** with dual-stack support @@ -113,8 +113,8 @@ pub fn main() !void { try client.cast(.get, &.{}, "ping"); // Blocking CON request/response with retransmission. - const result = try client.get(allocator, "/temperature"); - defer result.deinit(allocator); + var storage: coap.Client.ResponseStorage(4096) = .{}; + const result = try client.get(storage.buffers(), "/temperature"); std.debug.print("response: {s}\n", .{result.payload}); } @@ -144,8 +144,8 @@ defer client.deinit(); try client.handshake(); -const result = try client.get(allocator, "/temperature"); -defer result.deinit(allocator); +var storage: coap.Client.ResponseStorage(4096) = .{}; +const result = try client.get(storage.buffers(), "/temperature"); ``` All send/recv methods automatically encrypt/decrypt after `handshake()`. @@ -367,22 +367,49 @@ var client = try coap.Client.init(allocator, .{ defer client.deinit(); ``` +### Caller-owned CON response buffers + +`submit`, `call`, `get`, `post`, `put`, `delete`, and `upload` accept +`Client.ResponseBuffers`, not a response allocator. `ResponseStorage(N)` is a +convenience type with a 1280-byte wire buffer, 32 option descriptors, and `N` +bytes for multi-block Block2 reassembly. For other bounds, supply your own +`packet: []u8`, `options: []coapz.Option`, and `payload: []u8` slices. + +Allocate storage at startup. The three regions must be disjoint, and each +pending request needs independent storage. All returned bytes, tokens, option +values/descriptors, and reassembled payloads remain valid until **you reuse +that storage**, including across later receives or client destruction. Results +are borrowed: **never deinit a result or its packet**. Use separate storage +when retaining several results; a single reusable buffer suits sequential calls. + +Insufficient storage completes the affected handle with +`ResponseBufferTooSmall`, `ResponseOptionsTooSmall`, or +`ResponsePayloadTooSmall`. Its client state is released; retry with larger +storage. No heap fallback or runtime growth occurs. Partial contents after an +error are unspecified. At most 16 request options are accepted (15 before +`upload` adds Block1); excess is rejected rather than silently truncated. + +This is a breaking API change; no allocating CON compatibility wrappers remain. +Raw receives and Observe notifications still have explicit allocator APIs. +CON polling that also routes Observe notifications can therefore allocate for +those notifications; the CON response itself does not allocate. + ### get / post / put / delete — path convenience CON request/response by URI string with automatic retransmission. Paths and query strings are parsed automatically: ```zig -const result = try client.get(allocator, "/sensor/temperature"); -defer result.deinit(allocator); -// result.code, result.payload, result.options +var storage: coap.Client.ResponseStorage(4096) = .{}; +const result = try client.get(storage.buffers(), "/sensor/temperature"); +std.debug.print("{s}\n", .{result.payload}); // Consume before reusing storage. // Query strings work too: -const r2 = try client.get(allocator, "/sensors?type=temp&floor=2"); -defer r2.deinit(allocator); +const r2 = try client.get(storage.buffers(), "/sensors?type=temp&floor=2"); +std.debug.print("{s}\n", .{r2.payload}); -const r3 = try client.post(allocator, "/log", "event happened"); -defer r3.deinit(allocator); +const r3 = try client.post(storage.buffers(), "/log", "event happened"); +std.debug.print("{s}\n", .{r3.payload}); ``` Returns `error.Timeout` after max retransmissions, `error.Reset` if the @@ -399,7 +426,8 @@ const uri = coap.uri; // Parse a full URI into CoAP options: var buf: [uri.max_options]coapz.Option = undefined; const opts = uri.fromUri("/sensors/temp?unit=celsius&fmt=json", &buf); -const result = try client.call(allocator, .get, opts, &.{}); +var storage: coap.Client.ResponseStorage(4096) = .{}; +const result = try client.call(storage.buffers(), .get, opts, &.{}); // Or build path and query separately: var path_buf: [8]coapz.Option = undefined; @@ -425,8 +453,8 @@ for simpler path-based requests. ```zig var buf: [coap.uri.max_options]coapz.Option = undefined; -const result = try client.call(allocator, .get, coap.uri.fromUri("/sensor", &buf), &.{}); -defer result.deinit(allocator); +var storage: coap.Client.ResponseStorage(4096) = .{}; +const result = try client.call(storage.buffers(), .get, coap.uri.fromUri("/sensor", &buf), &.{}); ``` ### submit / poll — pipelined async @@ -441,33 +469,43 @@ var client = try coap.Client.init(allocator, .{ }); defer client.deinit(); -// Submit multiple requests — returns immediately. -const h1 = try client.submit(.get, &.{ +var storage: [2]coap.Client.ResponseStorage(4096) = .{ .{}, .{} }; +// Confirm the peer first (NSTART), then pipeline independent buffers. +_ = try client.get(storage[0].buffers(), "/temperature"); +const h1 = try client.submit(storage[0].buffers(), .get, &.{ .{ .kind = .uri_path, .value = "temperature" }, }, &.{}); -const h2 = try client.submit(.get, &.{ +const h2 = try client.submit(storage[1].buffers(), .get, &.{ .{ .kind = .uri_path, .value = "humidity" }, }, &.{}); -// Poll for completions (handles retransmission, Block2 reassembly). -while (try client.poll(allocator, 100)) |completion| { - defer completion.result.deinit(allocator); +// A null poll means no completion yet, not that all requests are done. +var pending: usize = 2; +while (pending > 0) { + const completion = try client.poll(100) orelse continue; + pending -= 1; + const result = completion.result catch |err| { + std.debug.print("handle {d}: {}\n", .{ completion.handle, err }); + continue; + }; if (completion.handle == h1) { - std.debug.print("temp: {s}\n", .{completion.result.payload}); + std.debug.print("temp: {s}\n", .{result.payload}); } else if (completion.handle == h2) { - std.debug.print("humidity: {s}\n", .{completion.result.payload}); + std.debug.print("humidity: {s}\n", .{result.payload}); } } ``` -`poll` returns `null` when the timeout expires with no completion. Check -`completion.result._timeout` or `._reset` for error conditions. Option -`value` memory passed to `submit` must remain valid until the corresponding -completion. +`poll` returns `null` when there is no completion. `completion.result` is an +error union, including `Timeout`, `Reset`, and capacity errors, always correlated +by handle. Request option values must remain valid through completion for +Block2 continuations. Storage is exclusively borrowed until completion, +`client.cancel(handle)`, or client destruction. Cancellation releases only +local state; it does not retract a datagram or stop remote application work. +Handles are reused: cancel only a currently pending handle. -The blocking `call`/`get`/`post`/`put`/`delete` methods are implemented as -`submit` + `poll` internally — both APIs share the same slot infrastructure -and can be mixed freely. +Blocking calls use `submit` + `poll` internally, but reject existing pending +requests with `RequestsInFlight` rather than discarding unrelated completions. ### sendRaw / recvRaw — low-level @@ -575,10 +613,11 @@ Observers are removed when: Upload large payloads using Block1 segmentation: ```zig -const result = try client.upload(allocator, .put, &.{ +var storage: coap.Client.ResponseStorage(4096) = .{}; +const result = try client.upload(storage.buffers(), .put, &.{ .{ .kind = .uri_path, .value = "firmware" }, }, large_payload); -defer result.deinit(allocator); +// The final response, including Block2, borrows storage. ``` The server's preferred block size is honored if it responds with a @@ -895,7 +934,11 @@ Filter flags: `--plain-only`, `--dtls-only`, `--con-only`, `--non-only`, `--single-only`, `--multi-only`, `--payload-only <0|100|1000>`, `--ipv6`. Use `--help` for all options. For performance comparisons, run one scenario per invocation to avoid outstanding NON traffic affecting the next scenario's -server-side counters. See [the Zig 0.16 migration measurements](docs/ZIG_016_PERFORMANCE.md). +server-side counters. `--allocator debug|smp` selects the client allocator +(default: DebugAllocator); this is separate from the Zig build mode. DTLS +workers synchronize after handshake/warmup and use one common wall interval +for successful CON response throughput. See [bounded response storage and +matched benchmarks](docs/CON_BUFFERS.md) and [the Zig 0.16 migration measurements](docs/ZIG_016_PERFORMANCE.md). ## Requirements diff --git a/bench/client.zig b/bench/client.zig index cdd51b5..ce94bd5 100644 --- a/bench/client.zig +++ b/bench/client.zig @@ -22,6 +22,7 @@ const SuiteConfig = struct { port: u16 = 5683, warmup_count: u32 = 1_000, window_size: u16 = 256, + allocator_kind: enum { debug, smp } = .debug, embedded_server: bool = true, thread_count: u16 = 0, // 0 = nproc count_override: ?u32 = null, @@ -86,11 +87,13 @@ const scenario_templates = [_]Scenario{ // ── Main ─────────────────────────────────────────────────────────────── pub fn main(init: std.process.Init.Minimal) !void { + const config = parse_args(init.args); var gpa = std.heap.DebugAllocator(.{}){}; defer _ = gpa.deinit(); - const allocator = gpa.allocator(); - - const config = parse_args(init.args); + const allocator = switch (config.allocator_kind) { + .debug => gpa.allocator(), + .smp => std.heap.smp_allocator, + }; const cpu_count: u16 = if (config.thread_count > 0) config.thread_count else @@ -120,6 +123,9 @@ pub fn main(init: std.process.Init.Minimal) !void { } std.debug.print("\x1b[1m── benchmark suite ──\x1b[0m\n\n", .{}); + std.debug.print(" build {s}; client allocator {s}; DTLS common-wall interval\n", .{ + @tagName(@import("builtin").mode), @tagName(config.allocator_kind), + }); { var count_buf: [26]u8 = undefined; @@ -463,6 +469,31 @@ fn aggregate_plain(allocator: std.mem.Allocator, worker_results: []PlainWorkerRe // ── DTLS scenario ────────────────────────────────────────────────────── +// All workers finish handshake, warmup, and allocation before measurement. +const MeasurementGate = struct { + remaining: std.atomic.Value(u16), + ready: std.atomic.Value(bool) = .init(false), + aborted: std.atomic.Value(bool) = .init(false), + start_ns: i128 = 0, + + fn wait(self: *MeasurementGate) bool { + if (self.aborted.load(.acquire)) return false; + if (self.remaining.fetchSub(1, .acq_rel) == 1) { + self.start_ns = platform.nanoTimestamp(); + self.ready.store(true, .release); + } else { + // Only startup waits here; yielding is outside the measured loop. + while (!self.ready.load(.acquire)) std.Thread.yield() catch {}; + } + return !self.aborted.load(.acquire); + } + + fn abort(self: *MeasurementGate) void { + self.aborted.store(true, .release); + self.ready.store(true, .release); + } +}; + fn run_scenario_dtls( allocator: std.mem.Allocator, config: SuiteConfig, @@ -487,15 +518,21 @@ fn run_scenario_dtls( allocator.free(worker_results); } + @memset(worker_results, .{}); + var gate: MeasurementGate = .{ .remaining = .init(tc) }; + var spawned: usize = 0; + errdefer { + gate.abort(); + for (threads[0..spawned]) |thread| thread.join(); + } for (0..extra) |j| { - worker_results[j] = .{}; threads[j] = try std.Thread.spawn(.{}, dtls_worker, .{ allocator, config.host, port, window, s.payload_size, - s.use_confirmable, per_thread, config.warmup_count, &worker_results[j], + s.use_confirmable, per_thread, config.warmup_count, &worker_results[j], &gate, }); + spawned += 1; } - worker_results[extra] = .{}; dtls_worker( allocator, config.host, @@ -506,15 +543,20 @@ fn run_scenario_dtls( per_thread + remainder, config.warmup_count, &worker_results[extra], + &gate, ); for (threads) |t| t.join(); - return aggregate_dtls(allocator, worker_results); + return aggregate_dtls(allocator, worker_results, gate.start_ns, s.use_confirmable); } +const ResponseStorage = coap.Client.ResponseStorage(0); + const DtlsWorkerResult = struct { sent: u64 = 0, + received: u64 = 0, + finished_ns: i128 = 0, errors: u64 = 0, latencies: ?[]i64 = null, latency_count: u32 = 0, @@ -531,7 +573,14 @@ fn dtls_worker( count: u32, warmup_count: u32, out: *DtlsWorkerResult, + gate: *MeasurementGate, ) void { + var entered = false; + defer if (!entered) { + out.errors = count; + _ = gate.wait(); + out.finished_ns = platform.nanoTimestamp(); + }; var client = coap.Client.init(allocator, .{ .host = host, .port = port, @@ -546,11 +595,11 @@ fn dtls_worker( defer allocator.free(payload); @memset(payload, 'x'); - // Warmup (not timed). + // Warmup (not timed); one reusable caller-owned response buffer. + var warmup_storage: ResponseStorage = .{}; if (use_confirmable) { for (0..warmup_count) |_| { - const r = client.call(allocator, .get, &.{}, payload) catch continue; - r.deinit(allocator); + _ = client.call(warmup_storage.buffers(), .get, &.{}, payload) catch continue; } } else { for (0..warmup_count) |_| { @@ -559,9 +608,9 @@ fn dtls_worker( } if (use_confirmable) { - dtls_worker_con(&client, allocator, window, payload, count, out); + dtls_worker_con(&client, allocator, window, payload, count, out, gate, &entered); } else { - dtls_worker_non(&client, payload, count, out); + dtls_worker_non(&client, payload, count, out, gate, &entered); } } @@ -572,12 +621,22 @@ fn dtls_worker_con( payload: []const u8, count: u32, out: *DtlsWorkerResult, + gate: *MeasurementGate, + entered: *bool, ) void { const timestamps = allocator.alloc(i128, window) catch return; defer allocator.free(timestamps); @memset(timestamps, 0); - + const responses = allocator.alloc(ResponseStorage, window) catch return; + defer allocator.free(responses); + const buffer_for_handle = allocator.alloc(u16, window) catch return; + defer allocator.free(buffer_for_handle); + var free_buffers = std.ArrayList(u16).initCapacity(allocator, window) catch return; + defer free_buffers.deinit(allocator); + for (0..window) |i| free_buffers.appendAssumeCapacity(@intCast(i)); + defer for (0..window) |i| client.cancel(@intCast(i)); const latencies = allocator.alloc(i64, count) catch return; + out.latencies = latencies; var sent: u64 = 0; var received: u64 = 0; @@ -586,55 +645,50 @@ fn dtls_worker_con( var total_sent: u32 = 0; var in_flight: u16 = 0; - const bench_start = platform.nanoTimestamp(); - + entered.* = true; + if (!gate.wait()) return; + const bench_start = gate.start_ns; while (received + errors < count) { while (in_flight < window and total_sent < count) { - const handle = client.submit(.get, &.{}, payload) catch { + const buffer_index = free_buffers.pop().?; + const handle = client.submit(responses[buffer_index].buffers(), .get, &.{}, payload) catch { + free_buffers.appendAssumeCapacity(buffer_index); errors += 1; total_sent += 1; continue; }; + buffer_for_handle[handle] = buffer_index; timestamps[handle] = platform.nanoTimestamp(); total_sent += 1; in_flight += 1; sent += 1; } - if (in_flight == 0) break; - - const c = client.poll(allocator, 50) catch { + const completion = (client.poll(50) catch { + errors = count - received; + break; + }) orelse continue; + in_flight -= 1; + free_buffers.appendAssumeCapacity(buffer_for_handle[completion.handle]); + const response = completion.result catch { errors += 1; - if (in_flight > 0) in_flight -= 1; continue; }; - const completion = c orelse continue; - - in_flight -|= 1; - - if (completion.result._timeout or completion.result._reset) { + if (response.code != .content or !std.mem.eql(u8, response.payload, payload)) { errors += 1; continue; } - defer completion.result.deinit(allocator); - received += 1; - - const ts = timestamps[completion.handle]; - if (ts > 0) { - const latency = platform.nanoTimestamp() - ts; - if (latency_count < count) { - latencies[latency_count] = @intCast(@min(latency, std.math.maxInt(i64))); - latency_count += 1; - } - timestamps[completion.handle] = 0; - } + const latency = platform.nanoTimestamp() - timestamps[completion.handle]; + latencies[latency_count] = @intCast(@min(latency, std.math.maxInt(i64))); + latency_count += 1; + timestamps[completion.handle] = 0; } - - out.bench_elapsed_ns = platform.nanoTimestamp() - bench_start; + out.finished_ns = platform.nanoTimestamp(); + out.bench_elapsed_ns = out.finished_ns - bench_start; out.sent = sent; + out.received = received; out.errors = errors; - out.latencies = latencies; out.latency_count = latency_count; } @@ -643,11 +697,14 @@ fn dtls_worker_non( payload: []const u8, count: u32, out: *DtlsWorkerResult, + gate: *MeasurementGate, + entered: *bool, ) void { var sent: u64 = 0; var errors: u64 = 0; - - const bench_start = platform.nanoTimestamp(); + entered.* = true; + if (!gate.wait()) return; + const bench_start = gate.start_ns; for (0..count) |_| { client.cast(.get, &.{}, payload) catch { @@ -657,20 +714,21 @@ fn dtls_worker_non( sent += 1; } - out.bench_elapsed_ns = platform.nanoTimestamp() - bench_start; + out.finished_ns = platform.nanoTimestamp(); + out.bench_elapsed_ns = out.finished_ns - bench_start; out.sent = sent; out.errors = errors; } -fn aggregate_dtls(allocator: std.mem.Allocator, worker_results: []DtlsWorkerResult) !ScenarioResult { +fn aggregate_dtls(allocator: std.mem.Allocator, worker_results: []DtlsWorkerResult, start_ns: i128, confirmable: bool) !ScenarioResult { var total_sent: u64 = 0; var total_errors: u64 = 0; var total_lat_count: u64 = 0; var max_elapsed_ns: i128 = 0; for (worker_results) |wr| { - total_sent += wr.sent; - if (wr.bench_elapsed_ns > max_elapsed_ns) max_elapsed_ns = wr.bench_elapsed_ns; + total_sent += if (confirmable) wr.received else wr.sent; + max_elapsed_ns = @max(max_elapsed_ns, wr.finished_ns - start_ns); total_errors += wr.errors; total_lat_count += wr.latency_count; } @@ -1172,6 +1230,7 @@ fn print_usage() void { " --count Override request count per scenario\n" ++ " --warmup Warmup requests (default: 1000)\n" ++ " --window Client sliding window size (default: 256)\n" ++ + " --allocator Client allocator: debug (default) or smp\n" ++ " --threads Thread count, 0 = nproc (default: 0)\n" ++ " --no-server Don't fork embedded echo server\n" ++ " --ipv6 Use IPv6 loopback (::1) instead of IPv4\n" ++ @@ -1222,6 +1281,12 @@ fn parse_args(process_args: std.process.Args) SuiteConfig { } else if (std.mem.eql(u8, arg, "--window")) { const val = args.next() orelse "256"; config.window_size = std.fmt.parseInt(u16, val, 10) catch 256; + } else if (std.mem.eql(u8, arg, "--allocator")) { + const val = args.next() orelse ""; + config.allocator_kind = std.meta.stringToEnum(@TypeOf(config.allocator_kind), val) orelse { + std.debug.print("error: --allocator requires debug or smp\n", .{}); + std.process.exit(1); + }; } else if (std.mem.eql(u8, arg, "--threads")) { const val = args.next() orelse "0"; config.thread_count = std.fmt.parseInt(u16, val, 10) catch 0; diff --git a/bench/con-buffers-control.patch b/bench/con-buffers-control.patch new file mode 100644 index 0000000..787ad54 --- /dev/null +++ b/bench/con-buffers-control.patch @@ -0,0 +1,68 @@ +--- a/bench/client.zig ++++ b/bench/client.zig +@@ -551,7 +551,12 @@ + return aggregate_dtls(allocator, worker_results, gate.start_ns, s.use_confirmable); + } + +-const ResponseStorage = coap.Client.ResponseStorage(0); ++// Matched startup reservation; the original API still allocates every result. ++const ResponseStorage = struct { ++ packet: [1280]u8 = undefined, ++ options: [32]coapz.Option = undefined, ++ payload: [0]u8 = undefined, ++}; + + const DtlsWorkerResult = struct { + sent: u64 = 0, +@@ -596,10 +601,10 @@ + @memset(payload, 'x'); + + // Warmup (not timed); one reusable caller-owned response buffer. +- var warmup_storage: ResponseStorage = .{}; + if (use_confirmable) { + for (0..warmup_count) |_| { +- _ = client.call(warmup_storage.buffers(), .get, &.{}, payload) catch continue; ++ const result = client.call(allocator, .get, &.{}, payload) catch continue; ++ result.deinit(allocator); + } + } else { + for (0..warmup_count) |_| { +@@ -634,7 +639,6 @@ + var free_buffers = std.ArrayList(u16).initCapacity(allocator, window) catch return; + defer free_buffers.deinit(allocator); + for (0..window) |i| free_buffers.appendAssumeCapacity(@intCast(i)); +- defer for (0..window) |i| client.cancel(@intCast(i)); + const latencies = allocator.alloc(i64, count) catch return; + out.latencies = latencies; + +@@ -651,7 +655,7 @@ + while (received + errors < count) { + while (in_flight < window and total_sent < count) { + const buffer_index = free_buffers.pop().?; +- const handle = client.submit(responses[buffer_index].buffers(), .get, &.{}, payload) catch { ++ const handle = client.submit(.get, &.{}, payload) catch { + free_buffers.appendAssumeCapacity(buffer_index); + errors += 1; + total_sent += 1; +@@ -664,16 +668,18 @@ + sent += 1; + } + if (in_flight == 0) break; +- const completion = (client.poll(50) catch { ++ const completion = (client.poll(allocator, 50) catch { + errors = count - received; + break; + }) orelse continue; + in_flight -= 1; + free_buffers.appendAssumeCapacity(buffer_for_handle[completion.handle]); +- const response = completion.result catch { ++ const response = completion.result; ++ if (!response.valid()) { + errors += 1; + continue; +- }; ++ } ++ defer response.deinit(allocator); + if (response.code != .content or !std.mem.eql(u8, response.payload, payload)) { + errors += 1; + continue; diff --git a/bench/con-buffers.py b/bench/con-buffers.py new file mode 100644 index 0000000..adc4126 --- /dev/null +++ b/bench/con-buffers.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +"""Compare response storage using matched common-wall benchmark generators. + +The control uses the unmodified base library and con-buffers-control.patch on +this revision's benchmark source. Both binaries must be ReleaseFast builds. +""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import platform +import re +import signal +import statistics +import subprocess + +ANSI = re.compile(r"\x1b\[[0-9;]*[A-Za-z]") +ROW = re.compile(r"\b([14])T\s+(0|100|1000)B\s+([\d,]+)\s+([\d.]+|-)\s+([\d.]+|-)\s+([\d.]+|-)\s+([\d,]+)") + + +def run(command): + with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + text=True, start_new_session=True) as process: + try: + stdout, stderr = process.communicate(timeout=120) + except BaseException: + try: + os.killpg(process.pid, signal.SIGTERM) + process.communicate(timeout=5) + except subprocess.TimeoutExpired: + os.killpg(process.pid, signal.SIGKILL) + process.communicate() + except ProcessLookupError: + pass + raise + if process.returncode: + raise RuntimeError(stdout + stderr) + return ANSI.sub("", stdout + stderr) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("baseline", type=Path) + parser.add_argument("candidate", type=Path) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--count", type=int, default=300000) + parser.add_argument("--repetitions", type=int, default=3) + parser.add_argument("--allocators", nargs="+", choices=("debug", "smp"), default=["debug", "smp"]) + parser.add_argument("--plain", action="store_true", help="Raw UDP CON control, not the public Client path") + args = parser.parse_args() + if min(args.count, args.repetitions) <= 0: + parser.error("counts must be positive") + binaries = {key: path.resolve() for key, path in (("baseline", args.baseline), ("candidate", args.candidate))} + patch = Path(__file__).with_name("con-buffers-control.patch") + data = { + "machine": platform.platform(), + "zig": subprocess.check_output(["zig", "version"], text=True).strip(), + "build_mode": "ReleaseFast", "allocators": args.allocators, + "base_library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": {key: hashlib.sha256(path.read_bytes()).hexdigest() for key, path in binaries.items()}, + "control_patch_sha256": hashlib.sha256(patch.read_bytes()).hexdigest(), + "count": args.count, "warmup_per_worker": 1000, "single_window": 32, + "multi_window_per_worker": 64, "transport": "plain" if args.plain else "dtls", + "measurement": "common wall interval; validated successful CON responses", + "plain_control_uses_raw_generator": args.plain, + "repetitions": args.repetitions, "samples": [], + } + args.output.parent.mkdir(parents=True, exist_ok=True) + for allocator in args.allocators: + for threads in (1, 4): + for payload in (0, 100, 1000): + for repeat in range(args.repetitions): + order = ("baseline", "candidate") if repeat % 2 == 0 else ("candidate", "baseline") + for backend in order: + command = [str(binaries[backend]), "--plain-only" if args.plain else "--dtls-only", "--con-only", + "--single-only" if threads == 1 else "--multi-only", "--threads", "4", + "--window", "32", "--payload-only", str(payload), "--count", str(args.count), + "--warmup", "1000", "--allocator", allocator, "--port", "29680"] + output = run(command) + if f"build ReleaseFast; client allocator {allocator};" not in output: + raise RuntimeError("Build/allocator mismatch: " + output) + matches = list(ROW.finditer(output)) + if len(matches) != 1: + raise RuntimeError(output) + values = matches[0].groups() + rps, errors = int(values[2].replace(",", "")), int(values[6].replace(",", "")) + if (int(values[0]), int(values[1])) != (threads, payload) or not rps or errors: + raise RuntimeError("Invalid or failed benchmark: " + output) + sample = dict(backend=backend, allocator=allocator, threads=threads, payload=payload, + repeat=repeat, rps=rps, p50_us=float(values[3].replace("-", "0")), + p99_us=float(values[4].replace("-", "0")), p999_us=float(values[5].replace("-", "0")), + errors=errors, command=command, output=output) + data["samples"].append(sample) + args.output.write_text(json.dumps(data, indent=2) + "\n") + print(f"{allocator:5} {backend:9} {threads}T {payload:4}B run {repeat + 1}: {rps:,} req/s", flush=True) + print("\nArithmetic means:") + for allocator in args.allocators: + for threads in (1, 4): + for payload in (0, 100, 1000): + means = {key: statistics.mean(s["rps"] for s in data["samples"] + if (s["backend"], s["allocator"], s["threads"], s["payload"]) == + (key, allocator, threads, payload)) for key in binaries} + print(f"{allocator:5} {threads}T {payload:4}B: {means['baseline']:,.0f} -> {means['candidate']:,.0f} " + f"({means['candidate']/means['baseline']:.3f}x)") + + +if __name__ == "__main__": + main() diff --git a/docs/CON_BUFFERS.md b/docs/CON_BUFFERS.md new file mode 100644 index 0000000..b95c311 --- /dev/null +++ b/docs/CON_BUFFERS.md @@ -0,0 +1,155 @@ +# Bounded caller-owned CON responses + +CON responses do not require heap allocation. The previous Client parsed each +response with `coapz.Packet.read(allocator, ...)`, and Block2 grew an ArrayList. +Its blanket zero-allocation interpretation was therefore incorrect. + +## Contract and implementation + +- `submit`, `call`, `get`, `post`, `put`, `delete`, and `upload` take + `Client.ResponseBuffers`; response allocator arguments are removed. +- Caller storage has a wire-datagram byte slice, option-descriptor slice, and + a separate bounded byte slice for multi-block Block2 payloads. These can be + disjoint regions of one startup allocation. `ResponseStorage(N)` supplies + 1280 wire bytes, 32 descriptors, and N reassembly bytes without allocation. +- Each pending request exclusively borrows independent storage. A completed + result retains its bytes, token, option values/descriptors, and payload until + the caller reuses that storage, including after other receives or client + destruction. Results and their packet views must never be deinited. +- `Completion.result` is an error union, correlated by handle. Capacity failures + are `ResponseBufferTooSmall`, `ResponseOptionsTooSmall`, and + `ResponsePayloadTooSmall`; the affected request's state is released and the + caller can retry. There is no allocator fallback, growth, or resizing. +- `cancel(handle)` releases a pending local borrow, not remote application work. + Handles are reused, so only cancel a currently pending handle. +- Blocking calls reject other pending requests with `RequestsInFlight` rather + than consuming and silently discarding their completions. +- Request option values must remain valid through completion. The existing + bounded request-option store holds 16 descriptors; excess is now rejected + instead of silently truncated. Upload reserves one descriptor for Block1. +- The internal decoder performs bounds-checked, allocation-free parsing into + the caller's option array, with views of the caller's copied wire bytes. +- Block2 stays in one request slot with one token/handle, appends into bounded + storage, checks offsets and ETags, tolerates duplicate separate blocks, and + keeps final option values alive. Continuation options are stably sorted. +- Empty ACK/RST is matched by MID; ACK stops request retransmission but leaves a + bounded deadline for a separate response. Separate CON responses are ACKed. + +There are no allocating CON compatibility wrappers. Raw receive and Observe +notification APIs retain their explicit allocator behavior. An active Observe +stream may allocate notifications while CON polling routes them; this is not a +blanket zero-allocation guarantee for every Client API. + +## Verification + +Debug and ReleaseSafe each pass **194/194 tests**. Default Debug and ReleaseFast +builds include the library, examples, and benchmark. New regressions cover: + +- Client allocator replaced by the always-failing allocator after initialization + (and DTLS handshake), including plain/DTLS Block1 plus Block2 responses. +- Independent retained replies and metadata across slot reuse, further receives, + another reassembly, and client destruction. +- Correlated packet/option/payload exhaustion, including first, intermediate, + and final Block2 fragments, followed by successful retry. +- Cancellation, timeout, serialization failure, ACK/RST matching, separate + response lifetime, token continuity, SZX reduction, duplicate blocks, + option ordering, ETag mismatch, malformed options, and invalid offsets. + +A separate strace probe (30,000 requests plus 1,000 warmup, 100-byte DTLS CON, +window 32, ReleaseFast/DebugAllocator) included client and embedded-server +startup/teardown. Mapping calls fell from **30,752 mmap / 60,712 munmap** to +**327 / 306**. These are whole-process totals, not claims of zero syscalls or +zero server allocation. Traced throughput is not used for performance results. + +## Benchmarks + +Machine: AMD Ryzen AI MAX+ 395, 16 cores / 32 logical CPUs, Linux 7.1.11, +Zig 0.16.0. Every comparison uses ReleaseFast and the same allocator on both +sides. `debug` means **DebugAllocator**, not a Debug build; `smp` uses the Zig +SMP allocator without libc linkage. The production allocator is not changed. + +The control library is unmodified main at +`51d6d76dcfc1be0c345602f4eef95991065c8730`. Both sides use the candidate benchmark +with identical warmup, buffer-index bookkeeping, payload validation, and +measurement synchronization; the control patch only adapts response ownership +back to the old API. Allocation and handshake/warmup happen before a shared +start gate. DTLS CON throughput is validated successful replies divided by the +common interval from that gate to the last worker's finish, not a sum of +independently timed workers. + +Main matrix: 300,000 total requests, 1,000 warmup per worker, window 32 with one +worker and 64 per worker with four; three repetitions, alternating backend +order. All 72 DTLS runs have zero errors. Arithmetic means: + +| Allocator | Workers | Payload | Original req/s | Caller buffers req/s | Ratio | +|---|---:|---:|---:|---:|---:| +| DebugAllocator | 1 | 0 | 190,941 | 645,073 | 3.378x | +| DebugAllocator | 1 | 100 | 183,217 | 577,659 | 3.153x | +| DebugAllocator | 1 | 1000 | 152,162 | 338,886 | 2.227x | +| DebugAllocator | 4 | 0 | 158,173 | 1,130,526 | 7.147x | +| DebugAllocator | 4 | 100 | 151,922 | 946,852 | 6.232x | +| DebugAllocator | 4 | 1000 | 184,507 | 577,727 | 3.131x | +| SMP | 1 | 0 | 639,040 | 656,789 | 1.028x | +| SMP | 1 | 100 | 578,247 | 583,135 | 1.008x | +| SMP | 1 | 1000 | 332,409 | 336,018 | 1.011x | +| SMP | 4 | 0 | 1,266,015 | 1,480,875 | 1.170x | +| SMP | 4 | 100 | 1,215,340 | 1,431,524 | 1.178x | +| SMP | 4 | 1000 | 629,188 | 707,269 | 1.124x | + +Four-worker placement/scheduling is not controlled and results vary widely. +A further **24 SMP runs**, with 3,000,000 total requests and two repetitions, +also have zero errors. Single-worker ratios are **1.007x / 0.996x / 1.002x**; +four-worker ratios are **1.944x / 0.722x / 1.402x** at 0/100/1000 bytes. Longer +runs do not remove the four-worker variability or negative cells. Do not claim +a universal SMP speedup or a reliable four-worker regression magnitude. + +A **36-run plain CON control** uses the unchanged raw UDP generator, not the +public Client response path. All runs have zero errors; ratios are +1.034x/1.032x/1.015x with one worker and 1.470x/1.084x/0.606x with four. These +are control variability, not evidence of a Client API speedup. NON is excluded: +its server-counter/warmup/drain accounting differs, and zero client errors +alone do not demonstrate full delivery. + +The robust outcome is bounded ownership and elimination of response heap +allocation. Default DebugAllocator performance improves substantially; when +allocation is already cheap, single-worker throughput is roughly unchanged. + +Raw data, binary hashes, full commands, and outputs: + +- `CON_BUFFERS_RESULTS.json`: final 72-run DTLS matrix. +- `CON_BUFFERS_SMP_LONG_RESULTS.json`: 24 longer SMP comparisons. +- `CON_BUFFERS_PLAIN_RESULTS.json`: 36 raw UDP controls. +- `CON_BUFFERS_INITIAL_RESULTS.json`: earlier exploratory 72-run matrix, before + explicit safety-build-only overlap assertions and final protocol hardening; + retained to expose variability, not used in the final table. +- `CON_BUFFERS_ALLOCATIONS.json`: mapping-count probe and provenance. + +## Reproduction + +Build the candidate with `zig build -Doptimize=ReleaseFast`; `zig build bench` +**runs** the suite, whereas the default build only builds its executable. +The benchmark header identifies its build mode and client allocator. + +For the control, check out the fixed base commit in a separate worktree, copy +this revision's `bench/client.zig` to a control source file, and apply +`bench/con-buffers-control.patch` to that copy. Build it with `zig build-exe`, +using that base worktree's `src/root.zig` as module `coap` and the same fetched +coapz v0.3.0 source as module `coapz`. Set ReleaseFast on **every module**: + +```sh +zig build-exe -OReleaseFast --dep coapz --dep coap -Mroot="$CONTROL_SOURCE" \ + -OReleaseFast -Mcoapz="$COAPZ_SOURCE" \ + -OReleaseFast --dep coapz -Mcoap="$CONTROL_WORKTREE/src/root.zig" \ + -femit-bin=/tmp/coap-con-control + +python3 bench/con-buffers.py /tmp/coap-con-control zig-out/bin/bench \ + --output /tmp/con-results.json +python3 bench/con-buffers.py /tmp/coap-con-control zig-out/bin/bench \ + --allocators smp --count 3000000 --repetitions 2 --output /tmp/con-long.json +python3 bench/con-buffers.py /tmp/coap-con-control zig-out/bin/bench \ + --plain --allocators debug --output /tmp/con-plain.json +``` + +Only the control benchmark is adapted; do not change its library, dependency, +allocator defaults, crypto, or CQE-clearing behavior. Avoid simultaneous test, +build, or profiling load during timing runs. diff --git a/docs/CON_BUFFERS_ALLOCATIONS.json b/docs/CON_BUFFERS_ALLOCATIONS.json new file mode 100644 index 0000000..8ccda09 --- /dev/null +++ b/docs/CON_BUFFERS_ALLOCATIONS.json @@ -0,0 +1,24 @@ +{ + "build_mode": "ReleaseFast", + "client_allocator": "DebugAllocator", + "transport": "DTLS CON", + "count": 30000, + "warmup": 1000, + "payload": 100, + "workers": 1, + "window": 32, + "scope": "strace -f totals including embedded server, initialization, warmup, measurement, and teardown; traced rates excluded from timing results", + "baseline": { + "library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": "210f1807d39dc1912292355924c3f4c07e999126af184013642a87ca4a0cff77", + "mmap": 30752, + "munmap": 60712, + "command": "strace -f -c -e trace=mmap,munmap /tmp/coap-con-buffers-control --dtls-only --con-only --single-only --threads 4 --window 32 --payload-only 100 --count 30000 --warmup 1000 --allocator debug --port 29685" + }, + "candidate": { + "binary_sha256": "339966f4269d35cb1a46802d6d4fb7681f43d152154c82b1edf184493ea68d6e", + "mmap": 327, + "munmap": 306, + "command": "strace -f -c -e trace=mmap,munmap /tmp/coap-con-buffers-candidate --dtls-only --con-only --single-only --threads 4 --window 32 --payload-only 100 --count 30000 --warmup 1000 --allocator debug --port 29685" + } +} diff --git a/docs/CON_BUFFERS_INITIAL_RESULTS.json b/docs/CON_BUFFERS_INITIAL_RESULTS.json new file mode 100644 index 0000000..0bddb46 --- /dev/null +++ b/docs/CON_BUFFERS_INITIAL_RESULTS.json @@ -0,0 +1,2401 @@ +{ + "machine": "Linux-7.1.11-arch1-1-x86_64-with-glibc2.44", + "zig": "0.16.0", + "build_mode": "ReleaseFast", + "allocators": [ + "debug", + "smp" + ], + "base_library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": { + "baseline": "210f1807d39dc1912292355924c3f4c07e999126af184013642a87ca4a0cff77", + "candidate": "a4c7fbbc2ffbcc1f493730bb8c315d4cf8e6e52356f7c4fc009124cfeed4ea76" + }, + "control_patch_sha256": "22dc76ed03dc916eb5af42ce33b6aadf73ca584b4d5f31e523a90dcb78ee7a7e", + "count": 300000, + "warmup_per_worker": 1000, + "single_window": 32, + "multi_window_per_worker": 64, + "transport": "dtls", + "measurement": "common wall interval; validated successful CON responses", + "plain_control_uses_raw_generator": false, + "repetitions": 3, + "samples": [ + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 194153, + "p50_us": 150.5, + "p99_us": 525.5, + "p999_us": 1006.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 194,153 150.5 525.5 1006.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 648214, + "p50_us": 45.4, + "p99_us": 100.8, + "p999_us": 150.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 648,214 45.4 100.8 150.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 651106, + "p50_us": 45.4, + "p99_us": 80.8, + "p999_us": 141.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 651,106 45.4 80.8 141.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 190137, + "p50_us": 154.3, + "p99_us": 474.0, + "p999_us": 929.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 190,137 154.3 474.0 929.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 193094, + "p50_us": 151.5, + "p99_us": 464.2, + "p999_us": 899.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 193,094 151.5 464.2 899.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 654543, + "p50_us": 45.3, + "p99_us": 77.1, + "p999_us": 152.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 654,543 45.3 77.1 152.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 181031, + "p50_us": 160.9, + "p99_us": 455.5, + "p999_us": 905.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 181,031 160.9 455.5 905.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 579301, + "p50_us": 50.3, + "p99_us": 109.3, + "p999_us": 181.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 579,301 50.3 109.3 181.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 571933, + "p50_us": 51.0, + "p99_us": 121.7, + "p999_us": 192.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 571,933 51.0 121.7 192.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 183317, + "p50_us": 159.7, + "p99_us": 527.5, + "p999_us": 1018.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 183,317 159.7 527.5 1018.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 172233, + "p50_us": 168.8, + "p99_us": 619.6, + "p999_us": 1143.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 172,233 168.8 619.6 1143.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 580131, + "p50_us": 50.8, + "p99_us": 93.0, + "p999_us": 150.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 580,131 50.8 93.0 150.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 151510, + "p50_us": 193.5, + "p99_us": 590.6, + "p999_us": 982.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 151,510 193.5 590.6 982.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 334900, + "p50_us": 91.9, + "p99_us": 216.1, + "p999_us": 312.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 334,900 91.9 216.1 312.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 335193, + "p50_us": 92.9, + "p99_us": 162.5, + "p999_us": 297.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 335,193 92.9 162.5 297.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 150553, + "p50_us": 194.8, + "p99_us": 627.6, + "p999_us": 1109.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 150,553 194.8 627.6 1109.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 149097, + "p50_us": 198.3, + "p99_us": 558.9, + "p999_us": 981.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 149,097 198.3 558.9 981.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 336737, + "p50_us": 92.1, + "p99_us": 154.0, + "p999_us": 289.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 336,737 92.1 154.0 289.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 134487, + "p50_us": 1845.2, + "p99_us": 6650.3, + "p999_us": 11846.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 134,487 1845.2 6650.3 11846.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1131993, + "p50_us": 194.9, + "p99_us": 291.3, + "p999_us": 350.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,131,993 194.9 291.3 350.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 919319, + "p50_us": 265.4, + "p99_us": 349.2, + "p999_us": 478.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 919,319 265.4 349.2 478.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 155216, + "p50_us": 1657.0, + "p99_us": 2670.1, + "p999_us": 4822.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 155,216 1657.0 2670.1 4822.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 149854, + "p50_us": 1693.1, + "p99_us": 3111.2, + "p999_us": 5253.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 149,854 1693.1 3111.2 5253.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 1188992, + "p50_us": 202.6, + "p99_us": 286.4, + "p999_us": 322.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,188,992 202.6 286.4 322.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 155977, + "p50_us": 1679.1, + "p99_us": 2819.2, + "p999_us": 4071.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 155,977 1679.1 2819.2 4071.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1183432, + "p50_us": 163.5, + "p99_us": 296.1, + "p999_us": 350.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,183,432 163.5 296.1 350.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 948895, + "p50_us": 162.3, + "p99_us": 357.7, + "p999_us": 405.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 948,895 162.3 357.7 405.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 156303, + "p50_us": 1684.8, + "p99_us": 3094.3, + "p999_us": 4808.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 156,303 1684.8 3094.3 4808.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 136048, + "p50_us": 1864.5, + "p99_us": 5103.8, + "p999_us": 8912.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 136,048 1864.5 5103.8 8912.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1134578, + "p50_us": 165.5, + "p99_us": 279.2, + "p999_us": 439.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,134,578 165.5 279.2 439.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 186872, + "p50_us": 1337.9, + "p99_us": 2283.2, + "p999_us": 3410.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 186,872 1337.9 2283.2 3410.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 485732, + "p50_us": 493.0, + "p99_us": 664.0, + "p999_us": 717.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 485,732 493.0 664.0 717.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 708361, + "p50_us": 261.4, + "p99_us": 460.5, + "p999_us": 503.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 708,361 261.4 460.5 503.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 181688, + "p50_us": 1363.8, + "p99_us": 2475.4, + "p999_us": 3359.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 181,688 1363.8 2475.4 3359.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 184295, + "p50_us": 1355.3, + "p99_us": 2397.7, + "p999_us": 3650.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 184,295 1355.3 2397.7 3650.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 664999, + "p50_us": 289.3, + "p99_us": 494.0, + "p999_us": 581.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 664,999 289.3 494.0 581.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 655417, + "p50_us": 45.2, + "p99_us": 65.9, + "p999_us": 135.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 655,417 45.2 65.9 135.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 640196, + "p50_us": 45.8, + "p99_us": 75.7, + "p999_us": 149.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 640,196 45.8 75.7 149.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 649364, + "p50_us": 45.5, + "p99_us": 95.3, + "p999_us": 148.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 649,364 45.5 95.3 148.7 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 643060, + "p50_us": 45.5, + "p99_us": 109.8, + "p999_us": 154.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 643,060 45.5 109.8 154.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 653738, + "p50_us": 45.4, + "p99_us": 68.2, + "p999_us": 135.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 653,738 45.4 68.2 135.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 651630, + "p50_us": 45.5, + "p99_us": 69.8, + "p999_us": 136.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 651,630 45.5 69.8 136.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 568464, + "p50_us": 50.9, + "p99_us": 125.1, + "p999_us": 238.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 568,464 50.9 125.1 238.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 574071, + "p50_us": 51.2, + "p99_us": 120.2, + "p999_us": 167.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 574,071 51.2 120.2 167.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 577680, + "p50_us": 50.5, + "p99_us": 99.7, + "p999_us": 195.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 577,680 50.5 99.7 195.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 592897, + "p50_us": 50.2, + "p99_us": 73.2, + "p999_us": 159.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 592,897 50.2 73.2 159.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 588377, + "p50_us": 50.0, + "p99_us": 107.2, + "p999_us": 162.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 588,377 50.0 107.2 162.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 579719, + "p50_us": 50.4, + "p99_us": 121.7, + "p999_us": 169.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 579,719 50.4 121.7 169.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 337115, + "p50_us": 91.6, + "p99_us": 159.3, + "p999_us": 304.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 337,115 91.6 159.3 304.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 335308, + "p50_us": 92.1, + "p99_us": 150.6, + "p999_us": 299.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 335,308 92.1 150.6 299.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 337563, + "p50_us": 91.9, + "p99_us": 166.5, + "p999_us": 291.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 337,563 91.9 166.5 291.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 333277, + "p50_us": 92.2, + "p99_us": 162.4, + "p999_us": 275.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 333,277 92.2 162.4 275.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 331572, + "p50_us": 92.1, + "p99_us": 157.7, + "p999_us": 287.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 331,572 92.1 157.7 287.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 336465, + "p50_us": 91.9, + "p99_us": 149.0, + "p999_us": 265.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 336,465 91.9 149.0 265.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 2004047, + "p50_us": 110.0, + "p99_us": 147.3, + "p999_us": 827.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 2,004,047 110.0 147.3 827.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1259592, + "p50_us": 186.6, + "p99_us": 259.3, + "p999_us": 331.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,259,592 186.6 259.3 331.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 872487, + "p50_us": 272.3, + "p99_us": 365.2, + "p999_us": 415.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 872,487 272.3 365.2 415.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 2003642, + "p50_us": 113.4, + "p99_us": 150.1, + "p999_us": 222.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 2,003,642 113.4 150.1 222.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 894833, + "p50_us": 267.5, + "p99_us": 353.4, + "p999_us": 400.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 894,833 267.5 353.4 400.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 899976, + "p50_us": 269.2, + "p99_us": 352.6, + "p999_us": 416.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 899,976 269.2 352.6 416.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 817859, + "p50_us": 292.1, + "p99_us": 386.4, + "p999_us": 506.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 817,859 292.1 386.4 506.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 912948, + "p50_us": 240.0, + "p99_us": 319.1, + "p999_us": 351.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 912,948 240.0 319.1 351.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 1109177, + "p50_us": 163.2, + "p99_us": 281.5, + "p999_us": 334.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,109,177 163.2 281.5 334.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 1922804, + "p50_us": 119.0, + "p99_us": 168.8, + "p999_us": 373.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,922,804 119.0 168.8 373.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1264381, + "p50_us": 160.9, + "p99_us": 295.5, + "p999_us": 403.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,264,381 160.9 295.5 403.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1848477, + "p50_us": 118.8, + "p99_us": 177.0, + "p999_us": 374.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,848,477 118.8 177.0 374.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 658102, + "p50_us": 257.4, + "p99_us": 504.2, + "p999_us": 557.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 658,102 257.4 504.2 557.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 1135495, + "p50_us": 205.8, + "p99_us": 281.7, + "p999_us": 466.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,135,495 205.8 281.7 466.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 400569, + "p50_us": 596.0, + "p99_us": 751.3, + "p999_us": 788.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 400,569 596.0 751.3 788.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 1137168, + "p50_us": 198.9, + "p99_us": 258.3, + "p999_us": 306.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,137,168 198.9 258.3 306.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 712819, + "p50_us": 274.0, + "p99_us": 489.6, + "p999_us": 548.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 712,819 274.0 489.6 548.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 682196, + "p50_us": 259.3, + "p99_us": 493.7, + "p999_us": 545.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 682,196 259.3 493.7 545.1 0\n\n" + } + ] +} diff --git a/docs/CON_BUFFERS_PLAIN_RESULTS.json b/docs/CON_BUFFERS_PLAIN_RESULTS.json new file mode 100644 index 0000000..ab74df4 --- /dev/null +++ b/docs/CON_BUFFERS_PLAIN_RESULTS.json @@ -0,0 +1,1212 @@ +{ + "machine": "Linux-7.1.11-arch1-1-x86_64-with-glibc2.44", + "zig": "0.16.0", + "build_mode": "ReleaseFast", + "allocators": [ + "debug" + ], + "base_library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": { + "baseline": "210f1807d39dc1912292355924c3f4c07e999126af184013642a87ca4a0cff77", + "candidate": "339966f4269d35cb1a46802d6d4fb7681f43d152154c82b1edf184493ea68d6e" + }, + "control_patch_sha256": "22dc76ed03dc916eb5af42ce33b6aadf73ca584b4d5f31e523a90dcb78ee7a7e", + "count": 300000, + "warmup_per_worker": 1000, + "single_window": 32, + "multi_window_per_worker": 64, + "transport": "plain", + "measurement": "common wall interval; validated successful CON responses", + "plain_control_uses_raw_generator": true, + "repetitions": 3, + "samples": [ + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 741159, + "p50_us": 40.8, + "p99_us": 89.1, + "p999_us": 150.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 741,159 40.8 89.1 150.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 769735, + "p50_us": 39.9, + "p99_us": 56.3, + "p999_us": 92.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 769,735 39.9 56.3 92.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 754984, + "p50_us": 39.9, + "p99_us": 88.7, + "p999_us": 115.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 754,984 39.9 88.7 115.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 725861, + "p50_us": 40.4, + "p99_us": 90.8, + "p999_us": 174.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 725,861 40.4 90.8 174.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 734266, + "p50_us": 41.5, + "p99_us": 83.1, + "p999_us": 172.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 734,266 41.5 83.1 172.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 751659, + "p50_us": 40.3, + "p99_us": 66.5, + "p999_us": 111.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 751,659 40.3 66.5 111.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 706064, + "p50_us": 42.3, + "p99_us": 92.7, + "p999_us": 135.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 706,064 42.3 92.7 135.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 746146, + "p50_us": 40.5, + "p99_us": 67.4, + "p999_us": 138.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 746,146 40.5 67.4 138.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 708007, + "p50_us": 40.9, + "p99_us": 91.4, + "p999_us": 145.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 708,007 40.9 91.4 145.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 724463, + "p50_us": 41.6, + "p99_us": 90.7, + "p999_us": 163.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 724,463 41.6 90.7 163.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 718028, + "p50_us": 41.8, + "p99_us": 90.7, + "p999_us": 141.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 718,028 41.8 90.7 141.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 762798, + "p50_us": 39.6, + "p99_us": 88.9, + "p999_us": 149.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 762,798 39.6 88.9 149.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 695948, + "p50_us": 42.6, + "p99_us": 90.3, + "p999_us": 148.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 695,948 42.6 90.3 148.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 716432, + "p50_us": 41.8, + "p99_us": 94.3, + "p999_us": 156.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 716,432 41.8 94.3 156.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 729134, + "p50_us": 41.8, + "p99_us": 81.2, + "p999_us": 137.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 729,134 41.8 81.2 137.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 681318, + "p50_us": 43.1, + "p99_us": 95.3, + "p999_us": 153.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 681,318 43.1 95.3 153.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 698999, + "p50_us": 42.8, + "p99_us": 93.6, + "p999_us": 150.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 698,999 42.8 93.6 150.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 660902, + "p50_us": 42.8, + "p99_us": 102.5, + "p999_us": 167.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 660,902 42.8 102.5 167.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1094437, + "p50_us": 148.9, + "p99_us": 274.0, + "p999_us": 320.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,094,437 148.9 274.0 320.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1447832, + "p50_us": 146.1, + "p99_us": 224.7, + "p999_us": 252.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,447,832 146.1 224.7 252.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 2332008, + "p50_us": 86.3, + "p99_us": 178.9, + "p999_us": 304.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 2,332,008 86.3 178.9 304.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 995923, + "p50_us": 247.7, + "p99_us": 355.8, + "p999_us": 462.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 995,923 247.7 355.8 462.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 1502013, + "p50_us": 133.4, + "p99_us": 192.1, + "p999_us": 251.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,502,013 133.4 192.1 251.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 1499577, + "p50_us": 147.1, + "p99_us": 223.4, + "p999_us": 241.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,499,577 147.1 223.4 241.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1245820, + "p50_us": 181.5, + "p99_us": 252.5, + "p999_us": 352.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,245,820 181.5 252.5 352.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1162312, + "p50_us": 135.4, + "p99_us": 267.2, + "p999_us": 371.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,162,312 135.4 267.2 371.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 2111435, + "p50_us": 89.9, + "p99_us": 133.2, + "p999_us": 217.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 2,111,435 89.9 133.2 217.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 2191911, + "p50_us": 97.1, + "p99_us": 137.1, + "p999_us": 260.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 2,191,911 97.1 137.1 260.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 918087, + "p50_us": 257.9, + "p99_us": 387.1, + "p999_us": 452.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 918,087 257.9 387.1 452.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1447792, + "p50_us": 145.8, + "p99_us": 222.5, + "p999_us": 309.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,447,792 145.8 222.5 309.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 2146686, + "p50_us": 101.6, + "p99_us": 179.5, + "p999_us": 310.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 2,146,686 101.6 179.5 310.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 1353621, + "p50_us": 141.8, + "p99_us": 246.8, + "p999_us": 467.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,353,621 141.8 246.8 467.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 867042, + "p50_us": 268.0, + "p99_us": 465.0, + "p999_us": 530.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 867,042 268.0 465.0 530.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 1384381, + "p50_us": 155.3, + "p99_us": 261.5, + "p999_us": 410.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,384,381 155.3 261.5 410.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 2359345, + "p50_us": 95.3, + "p99_us": 152.6, + "p999_us": 288.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 2,359,345 95.3 152.6 288.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 1350678, + "p50_us": 152.6, + "p99_us": 237.7, + "p999_us": 276.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--plain-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] Plain CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 Plain\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,350,678 152.6 237.7 276.9 0\n\n" + } + ] +} diff --git a/docs/CON_BUFFERS_RESULTS.json b/docs/CON_BUFFERS_RESULTS.json new file mode 100644 index 0000000..d7217d8 --- /dev/null +++ b/docs/CON_BUFFERS_RESULTS.json @@ -0,0 +1,2401 @@ +{ + "machine": "Linux-7.1.11-arch1-1-x86_64-with-glibc2.44", + "zig": "0.16.0", + "build_mode": "ReleaseFast", + "allocators": [ + "debug", + "smp" + ], + "base_library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": { + "baseline": "210f1807d39dc1912292355924c3f4c07e999126af184013642a87ca4a0cff77", + "candidate": "339966f4269d35cb1a46802d6d4fb7681f43d152154c82b1edf184493ea68d6e" + }, + "control_patch_sha256": "22dc76ed03dc916eb5af42ce33b6aadf73ca584b4d5f31e523a90dcb78ee7a7e", + "count": 300000, + "warmup_per_worker": 1000, + "single_window": 32, + "multi_window_per_worker": 64, + "transport": "dtls", + "measurement": "common wall interval; validated successful CON responses", + "plain_control_uses_raw_generator": false, + "repetitions": 3, + "samples": [ + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 189064, + "p50_us": 152.4, + "p99_us": 480.8, + "p999_us": 978.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 189,064 152.4 480.8 978.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 638491, + "p50_us": 45.2, + "p99_us": 109.4, + "p999_us": 171.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 638,491 45.2 109.4 171.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 650082, + "p50_us": 45.3, + "p99_us": 88.9, + "p999_us": 145.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 650,082 45.3 88.9 145.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 190430, + "p50_us": 151.8, + "p99_us": 461.2, + "p999_us": 902.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 190,430 151.8 461.2 902.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 193329, + "p50_us": 151.1, + "p99_us": 469.3, + "p999_us": 914.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 193,329 151.1 469.3 914.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 646646, + "p50_us": 45.0, + "p99_us": 108.4, + "p999_us": 153.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 646,646 45.0 108.4 153.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 184610, + "p50_us": 157.4, + "p99_us": 499.4, + "p999_us": 889.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 184,610 157.4 499.4 889.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 586257, + "p50_us": 50.1, + "p99_us": 117.3, + "p999_us": 162.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 586,257 50.1 117.3 162.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 590344, + "p50_us": 50.2, + "p99_us": 71.6, + "p999_us": 139.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 590,344 50.2 71.6 139.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 185628, + "p50_us": 157.2, + "p99_us": 491.1, + "p999_us": 928.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 185,628 157.2 491.1 928.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 179412, + "p50_us": 160.5, + "p99_us": 519.6, + "p999_us": 1010.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 179,412 160.5 519.6 1010.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 556375, + "p50_us": 51.1, + "p99_us": 103.6, + "p999_us": 178.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 556,375 51.1 103.6 178.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 155350, + "p50_us": 190.1, + "p99_us": 515.6, + "p999_us": 895.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 155,350 190.1 515.6 895.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 340887, + "p50_us": 92.2, + "p99_us": 121.2, + "p999_us": 242.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 340,887 92.2 121.2 242.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 338318, + "p50_us": 91.7, + "p99_us": 142.5, + "p999_us": 325.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 338,318 91.7 142.5 325.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 150114, + "p50_us": 195.3, + "p99_us": 574.6, + "p999_us": 1033.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 150,114 195.3 574.6 1033.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 151022, + "p50_us": 194.1, + "p99_us": 616.1, + "p999_us": 959.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 151,022 194.1 616.1 959.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 337453, + "p50_us": 92.0, + "p99_us": 165.9, + "p999_us": 251.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 337,453 92.0 165.9 251.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 160460, + "p50_us": 1676.6, + "p99_us": 2661.6, + "p999_us": 4176.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 160,460 1676.6 2661.6 4176.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1297509, + "p50_us": 150.2, + "p99_us": 246.8, + "p999_us": 292.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,297,509 150.2 246.8 292.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 830714, + "p50_us": 280.1, + "p99_us": 494.9, + "p999_us": 535.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 830,714 280.1 494.9 535.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 154439, + "p50_us": 1676.5, + "p99_us": 3565.4, + "p999_us": 5445.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 154,439 1676.5 3565.4 5445.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 159620, + "p50_us": 1680.6, + "p99_us": 2676.9, + "p999_us": 4166.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 159,620 1680.6 2676.9 4166.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 1263356, + "p50_us": 150.2, + "p99_us": 274.5, + "p999_us": 304.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,263,356 150.2 274.5 304.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 153249, + "p50_us": 1683.4, + "p99_us": 2560.1, + "p999_us": 4079.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 153,249 1683.4 2560.1 4079.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1179344, + "p50_us": 160.1, + "p99_us": 292.3, + "p999_us": 341.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,179,344 160.1 292.3 341.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 741953, + "p50_us": 298.8, + "p99_us": 484.7, + "p999_us": 544.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 741,953 298.8 484.7 544.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 150850, + "p50_us": 1710.2, + "p99_us": 3256.5, + "p999_us": 4608.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 150,850 1710.2 3256.5 4608.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 151667, + "p50_us": 1694.6, + "p99_us": 3317.7, + "p999_us": 4576.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 151,667 1694.6 3317.7 4576.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 919258, + "p50_us": 184.8, + "p99_us": 320.0, + "p999_us": 406.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 919,258 184.8 320.0 406.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 189002, + "p50_us": 1337.3, + "p99_us": 2117.8, + "p999_us": 2884.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 189,002 1337.3 2117.8 2884.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 739336, + "p50_us": 273.8, + "p99_us": 425.5, + "p999_us": 570.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 739,336 273.8 425.5 570.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 493800, + "p50_us": 475.9, + "p99_us": 677.5, + "p999_us": 745.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 493,800 475.9 677.5 745.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 184481, + "p50_us": 1355.1, + "p99_us": 2283.1, + "p999_us": 3025.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 184,481 1355.1 2283.1 3025.7 0\n\n" + }, + { + "backend": "baseline", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 180037, + "p50_us": 1385.8, + "p99_us": 2445.4, + "p999_us": 3264.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 180,037 1385.8 2445.4 3264.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "debug", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 500045, + "p50_us": 471.8, + "p99_us": 655.9, + "p999_us": 701.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "debug", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator debug; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 500,045 471.8 655.9 701.4 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 641367, + "p50_us": 45.7, + "p99_us": 109.7, + "p999_us": 158.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 641,367 45.7 109.7 158.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 654461, + "p50_us": 44.8, + "p99_us": 107.0, + "p999_us": 159.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 654,461 44.8 107.0 159.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 654367, + "p50_us": 44.9, + "p99_us": 80.5, + "p999_us": 133.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 654,367 44.9 80.5 133.7 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 638262, + "p50_us": 45.4, + "p99_us": 82.2, + "p999_us": 175.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 638,262 45.4 82.2 175.7 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 637492, + "p50_us": 46.1, + "p99_us": 109.6, + "p999_us": 168.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 637,492 46.1 109.6 168.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 2, + "rps": 661540, + "p50_us": 45.0, + "p99_us": 71.2, + "p999_us": 132.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 661,540 45.0 71.2 132.7 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 572087, + "p50_us": 51.5, + "p99_us": 121.8, + "p999_us": 169.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 572,087 51.5 121.8 169.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 584333, + "p50_us": 50.2, + "p99_us": 115.8, + "p999_us": 164.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 584,333 50.2 115.8 164.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 584699, + "p50_us": 50.6, + "p99_us": 96.7, + "p999_us": 167.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 584,699 50.6 96.7 167.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 580972, + "p50_us": 50.6, + "p99_us": 121.1, + "p999_us": 203.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 580,972 50.6 121.1 203.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 581683, + "p50_us": 50.5, + "p99_us": 119.8, + "p999_us": 175.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 581,683 50.5 119.8 175.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 2, + "rps": 580374, + "p50_us": 50.6, + "p99_us": 119.3, + "p999_us": 161.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 580,374 50.6 119.3 161.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 335714, + "p50_us": 91.9, + "p99_us": 219.6, + "p999_us": 291.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 335,714 91.9 219.6 291.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 338360, + "p50_us": 91.9, + "p99_us": 163.6, + "p999_us": 247.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 338,360 91.9 163.6 247.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 337394, + "p50_us": 91.5, + "p99_us": 172.5, + "p999_us": 301.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 337,394 91.5 172.5 301.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 332687, + "p50_us": 92.2, + "p99_us": 221.4, + "p999_us": 315.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 332,687 92.2 221.4 315.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 328825, + "p50_us": 92.2, + "p99_us": 222.0, + "p999_us": 385.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 328,825 92.2 222.0 385.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 2, + "rps": 332301, + "p50_us": 92.0, + "p99_us": 224.6, + "p999_us": 321.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 332,301 92.0 224.6 321.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 1292229, + "p50_us": 153.0, + "p99_us": 284.7, + "p999_us": 326.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,292,229 153.0 284.7 326.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 2167063, + "p50_us": 105.7, + "p99_us": 148.0, + "p999_us": 299.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 2,167,063 105.7 148.0 299.3 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 1281876, + "p50_us": 153.4, + "p99_us": 285.5, + "p999_us": 309.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,281,876 153.4 285.5 309.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 1229154, + "p50_us": 152.1, + "p99_us": 271.8, + "p999_us": 328.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,229,154 152.1 271.8 328.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 1276662, + "p50_us": 153.6, + "p99_us": 250.3, + "p999_us": 279.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,276,662 153.6 250.3 279.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 2, + "rps": 993686, + "p50_us": 131.3, + "p99_us": 290.4, + "p999_us": 317.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 993,686 131.3 290.4 317.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1252715, + "p50_us": 167.4, + "p99_us": 265.1, + "p999_us": 357.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,252,715 167.4 265.1 357.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1846044, + "p50_us": 131.8, + "p99_us": 164.8, + "p999_us": 237.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,846,044 131.8 164.8 237.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 1180518, + "p50_us": 163.1, + "p99_us": 293.5, + "p999_us": 344.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,180,518 163.1 293.5 344.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 1270326, + "p50_us": 163.9, + "p99_us": 253.8, + "p999_us": 290.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,270,326 163.9 253.8 290.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1122979, + "p50_us": 160.4, + "p99_us": 299.8, + "p999_us": 321.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,122,979 160.4 299.8 321.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 2, + "rps": 1268009, + "p50_us": 164.0, + "p99_us": 250.4, + "p999_us": 374.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,268,009 164.0 250.4 374.6 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 440265, + "p50_us": 541.2, + "p99_us": 749.0, + "p999_us": 826.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 440,265 541.2 749.0 826.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 704946, + "p50_us": 260.5, + "p99_us": 507.1, + "p999_us": 550.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 704,946 260.5 507.1 550.5 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 707112, + "p50_us": 258.1, + "p99_us": 496.7, + "p999_us": 564.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 707,112 258.1 496.7 564.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 742571, + "p50_us": 264.3, + "p99_us": 419.8, + "p999_us": 540.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 742,571 264.3 419.8 540.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 704728, + "p50_us": 280.1, + "p99_us": 494.2, + "p999_us": 576.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 704,728 280.1 494.2 576.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 2, + "rps": 709748, + "p50_us": 254.7, + "p99_us": 457.2, + "p999_us": 534.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "300000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 300,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 709,748 254.7 457.2 534.1 0\n\n" + } + ] +} diff --git a/docs/CON_BUFFERS_SMP_LONG_RESULTS.json b/docs/CON_BUFFERS_SMP_LONG_RESULTS.json new file mode 100644 index 0000000..169dd9d --- /dev/null +++ b/docs/CON_BUFFERS_SMP_LONG_RESULTS.json @@ -0,0 +1,816 @@ +{ + "machine": "Linux-7.1.11-arch1-1-x86_64-with-glibc2.44", + "zig": "0.16.0", + "build_mode": "ReleaseFast", + "allocators": [ + "smp" + ], + "base_library_commit": "51d6d76dcfc1be0c345602f4eef95991065c8730", + "binary_sha256": { + "baseline": "210f1807d39dc1912292355924c3f4c07e999126af184013642a87ca4a0cff77", + "candidate": "339966f4269d35cb1a46802d6d4fb7681f43d152154c82b1edf184493ea68d6e" + }, + "control_patch_sha256": "22dc76ed03dc916eb5af42ce33b6aadf73ca584b4d5f31e523a90dcb78ee7a7e", + "count": 3000000, + "warmup_per_worker": 1000, + "single_window": 32, + "multi_window_per_worker": 64, + "transport": "dtls", + "measurement": "common wall interval; validated successful CON responses", + "plain_control_uses_raw_generator": false, + "repetitions": 2, + "samples": [ + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 642847, + "p50_us": 45.6, + "p99_us": 105.0, + "p999_us": 152.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 642,847 45.6 105.0 152.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 0, + "rps": 647639, + "p50_us": 45.3, + "p99_us": 102.5, + "p999_us": 154.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 647,639 45.3 102.5 154.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 648240, + "p50_us": 45.3, + "p99_us": 107.3, + "p999_us": 155.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 648,240 45.3 107.3 155.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 0, + "repeat": 1, + "rps": 644108, + "p50_us": 45.7, + "p99_us": 89.9, + "p999_us": 150.5, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 0B 644,108 45.7 89.9 150.5 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 578928, + "p50_us": 50.9, + "p99_us": 96.3, + "p999_us": 163.7, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 578,928 50.9 96.3 163.7 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 0, + "rps": 578237, + "p50_us": 50.4, + "p99_us": 120.3, + "p999_us": 169.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 578,237 50.4 120.3 169.1 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 579313, + "p50_us": 50.9, + "p99_us": 96.0, + "p999_us": 158.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 579,313 50.9 96.0 158.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 100, + "repeat": 1, + "rps": 583606, + "p50_us": 50.5, + "p99_us": 87.7, + "p999_us": 163.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 100B 583,606 50.5 87.7 163.2 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 334561, + "p50_us": 92.1, + "p99_us": 174.4, + "p999_us": 308.2, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 334,561 92.1 174.4 308.2 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 0, + "rps": 337803, + "p50_us": 91.7, + "p99_us": 152.1, + "p999_us": 285.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 337,803 91.7 152.1 285.0 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 332769, + "p50_us": 92.4, + "p99_us": 187.2, + "p999_us": 301.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 332,769 92.4 187.2 301.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 1, + "payload": 1000, + "repeat": 1, + "rps": 334823, + "p50_us": 92.3, + "p99_us": 176.1, + "p999_us": 294.3, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--single-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 1T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 1T 1000B 334,823 92.3 176.1 294.3 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 999169, + "p50_us": 192.5, + "p99_us": 287.8, + "p999_us": 325.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 999,169 192.5 287.8 325.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 0, + "rps": 2182500, + "p50_us": 106.4, + "p99_us": 154.6, + "p999_us": 287.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 2,182,500 106.4 154.6 287.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 1332053, + "p50_us": 152.6, + "p99_us": 263.0, + "p999_us": 338.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 1,332,053 152.6 263.0 338.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 0, + "repeat": 1, + "rps": 808658, + "p50_us": 275.9, + "p99_us": 423.9, + "p999_us": 474.1, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "0", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 0B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 0B 808,658 275.9 423.9 474.1 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 817368, + "p50_us": 288.7, + "p99_us": 453.1, + "p999_us": 580.4, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 817,368 288.7 453.1 580.4 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 0, + "rps": 1164286, + "p50_us": 160.0, + "p99_us": 310.4, + "p999_us": 398.6, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,164,286 160.0 310.4 398.6 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 799600, + "p50_us": 293.1, + "p99_us": 457.0, + "p999_us": 572.0, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 799,600 293.1 457.0 572.0 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 100, + "repeat": 1, + "rps": 1903135, + "p50_us": 119.9, + "p99_us": 160.4, + "p999_us": 239.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "100", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 100B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 100B 1,903,135 119.9 160.4 239.9 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 677423, + "p50_us": 266.8, + "p99_us": 506.8, + "p999_us": 585.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 677,423 266.8 506.8 585.8 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 0, + "rps": 1199407, + "p50_us": 197.4, + "p99_us": 309.0, + "p999_us": 549.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 1,199,407 197.4 309.0 549.9 0\n\n" + }, + { + "backend": "candidate", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 687508, + "p50_us": 366.2, + "p99_us": 500.1, + "p999_us": 570.8, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-candidate", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 687,508 366.2 500.1 570.8 0\n\n" + }, + { + "backend": "baseline", + "allocator": "smp", + "threads": 4, + "payload": 1000, + "repeat": 1, + "rps": 668252, + "p50_us": 268.0, + "p99_us": 511.6, + "p999_us": 591.9, + "errors": 0, + "command": [ + "/tmp/coap-con-buffers-control", + "--dtls-only", + "--con-only", + "--multi-only", + "--threads", + "4", + "--window", + "32", + "--payload-only", + "1000", + "--count", + "3000000", + "--warmup", + "1000", + "--allocator", + "smp", + "--port", + "29680" + ], + "output": "\u2500\u2500 benchmark suite \u2500\u2500\n\n build ReleaseFast; client allocator smp; DTLS common-wall interval\n host 127.0.0.1:29680\n threads 4 (single: 1, multi: 4)\n server bufs 512 \u00d7 1280B\n client window 32 (1T), 64 (multi)\n warmup 1,000\n requests 3,000,000\n\n\n [1/1] DTLS CON 4T 1000B ...\n\u2500\u2500 results (4 CPUs) \u2500\u2500\n\n Scenarios\n \u2514\u2500 DTLS\n \u2514\u2500 CON req/s p50 \u00b5s p99 \u00b5s p99.9 \u00b5s errs\n \u2514\u2500 4T 1000B 668,252 268.0 511.6 591.9 0\n\n" + } + ] +} diff --git a/examples/client_example.zig b/examples/client_example.zig index 3fef5a9..005866a 100644 --- a/examples/client_example.zig +++ b/examples/client_example.zig @@ -16,9 +16,10 @@ pub fn main() !void { try client.cast(.get, &.{}, "ping"); std.debug.print("cast: sent NON GET\n", .{}); - // Blocking CON request/response using path convenience. - const result = try client.get(allocator, "/hello"); - defer result.deinit(allocator); + // One reusable response buffer; increase payload capacity for Block2. + var storage: coap.Client.ResponseStorage(4096) = .{}; + const result = try client.get(storage.buffers(), "/hello"); + // Borrowed result: consume before reusing storage, never deinit it. std.debug.print("call: code={}, payload={s}\n", .{ result.code, diff --git a/src/Client.zig b/src/Client.zig index 549df7d..0ddd6ff 100644 --- a/src/Client.zig +++ b/src/Client.zig @@ -10,8 +10,9 @@ /// /// **Memory:** `init()` pre-allocates send/recv buffers and in-flight slot /// tables. These are owned by the client and freed in `deinit()`. -/// Response data from `call`/`get`/etc. is allocated by the caller-provided -/// allocator and must be freed via `Result.deinit()`. +/// CON response APIs decode into caller-owned ResponseBuffers, with bounded +/// Block2 reassembly and no heap allocation. Results borrow this storage. +/// Raw receives and Observe notifications retain explicit allocator APIs. /// /// ## Example /// @@ -19,8 +20,8 @@ /// var client = try Client.init(allocator, .{ .host = "10.0.0.1" }); /// defer client.deinit(); /// -/// const result = try client.get(allocator, "/sensor/temperature"); -/// defer result.deinit(allocator); +/// var storage: Client.ResponseStorage(4096) = .{}; +/// const result = try client.get(storage.buffers(), "/sensor/temperature"); /// std.debug.print("{s}\n", .{result.payload}); /// ``` const std = @import("std"); @@ -60,52 +61,66 @@ pub const Config = struct { /// Response from a CON request (`call`, `get`, `post`, `put`, `delete`, `upload`). /// -/// **Lifetime:** The result owns the parsed packet and (for Block2 reassembly) -/// a separate payload allocation. The caller must call `deinit()` with the -/// same allocator passed to the originating call. -/// -/// ```zig -/// const result = try client.get(allocator, "/path"); -/// defer result.deinit(allocator); -/// // use result.code, result.payload, result.options -/// ``` +/// **Lifetime:** Borrows the storage supplied with the request. All bytes and +/// option descriptors remain valid until that storage is reused, even after +/// another receive or client.deinit(). Never deinit this result or its packet. pub const Result = struct { /// Response code (e.g. `.content`, `.not_found`). code: coapz.Code, - /// Response options. Backed by `packet`; valid until `deinit()`. + /// Response options; descriptors and values borrow caller storage. options: []const coapz.Option, - /// Response body. Backed by `packet` or by a separate allocation - /// when Block2 reassembly occurred. Valid until `deinit()`. + /// Body borrows packet storage, or payload storage for Block2 reassembly. payload: []const u8, - /// The full parsed response packet, for advanced inspection. + /// Borrowed packet view, including the complete reassembled payload. packet: coapz.Packet, - _owns_payload: bool = false, - _owns_options: bool = false, - _timeout: bool = false, - _reset: bool = false, - _etag_mismatch: bool = false, - - /// True if response is a normal server reply (not timeout, reset, or error). - pub fn valid(self: Result) bool { - return !self._timeout and !self._reset and !self._etag_mismatch; - } +}; - /// Free all memory associated with this result. Must be called with - /// the same allocator that was passed to `call`/`get`/`post`/etc. - /// Safe to call on timeout/reset sentinel results (no-op). - pub fn deinit(self: Result, allocator: std.mem.Allocator) void { - if (self._timeout or self._reset or self._etag_mismatch) return; - if (self._owns_payload) { - allocator.free(@constCast(self.payload)); - } - if (self._owns_options) { - allocator.free(@constCast(self.options)); - } else { - self.packet.deinit(allocator); - } - } +/// Caller-owned storage, borrowed exclusively by one request until completion. +/// Result bytes/options remain valid until the caller reuses this storage. +/// packet holds one wire datagram; payload bounds multi-block reassembly. +/// All three regions and every pending request's storage must be disjoint. +/// Use distinct storage while retaining multiple completed results. +pub const ResponseBuffers = struct { + packet: []u8, + options: []coapz.Option, + payload: []u8 = &.{}, }; +/// Convenience storage; construct once, then reuse after consuming each result. +pub fn ResponseStorage(comptime payload_capacity: usize) type { + return struct { + packet: [constants.buffer_size_default]u8 = undefined, + options: [32]coapz.Option = undefined, + payload: [payload_capacity]u8 = undefined, + pub fn buffers(self: *@This()) ResponseBuffers { + return .{ .packet = &self.packet, .options = &self.options, .payload = &self.payload }; + } + }; +} + +const packet_view = @import("packet_view.zig"); + +fn byteRangesOverlap(a: []const u8, b: []const u8) bool { + if (a.len == 0 or b.len == 0) return false; + return @intFromPtr(a.ptr) < @intFromPtr(b.ptr) + b.len and + @intFromPtr(b.ptr) < @intFromPtr(a.ptr) + a.len; +} + +fn buffersDisjoint(buffers: ResponseBuffers) bool { + const options = std.mem.sliceAsBytes(buffers.options); + return !byteRangesOverlap(buffers.packet, buffers.payload) and + !byteRangesOverlap(buffers.packet, options) and !byteRangesOverlap(buffers.payload, options); +} + +fn buffersOverlap(a: ResponseBuffers, b: ResponseBuffers) bool { + const left = [_][]const u8{ a.packet, std.mem.sliceAsBytes(a.options), a.payload }; + const right = [_][]const u8{ b.packet, std.mem.sliceAsBytes(b.options), b.payload }; + for (left) |x| for (right) |y| { + if (byteRangesOverlap(x, y)) return true; + }; + return false; +} + /// Opaque handle identifying a submitted async request. /// Valid until the corresponding Completion is returned by poll(). pub const RequestHandle = u16; @@ -114,8 +129,8 @@ pub const RequestHandle = u16; pub const Completion = struct { /// Handle matching the one returned by submit(). handle: RequestHandle, - /// The response. Caller must call result.deinit(allocator). - result: Result, + /// Borrowed response or correlated request failure. No deinit is required. + result: anyerror!Result, }; // ─── In-flight slot ────────────────────────────────────────────── @@ -135,7 +150,10 @@ const InFlightSlot = struct { send_len: u16, next_free: u16, // Async Block2 reassembly state. - block2_payload: std.ArrayListUnmanaged(u8), + response_buffers: ResponseBuffers = .{ .packet = &.{}, .options = &.{} }, + block2_length: usize = 0, + block2_offset: usize = 0, + acknowledged: bool = false, doing_block2: bool, block2_etag: [8]u8, block2_etag_len: u4, @@ -436,7 +454,7 @@ pub fn init(allocator: std.mem.Allocator, config: Config) !Client { @intCast(i + 1) else empty_sentinel, - .block2_payload = .empty, + .block2_length = 0, .doing_block2 = false, .block2_etag = undefined, .block2_etag_len = 0, @@ -501,7 +519,7 @@ pub fn init(allocator: std.mem.Allocator, config: Config) !Client { } /// Release all client-owned memory and close the socket. -/// Outstanding `Result` values must be deinited separately by the caller. +/// Outstanding results remain valid in caller storage; pending borrows end. pub fn deinit(client: *Client) void { if (client.dtls_session) |*sess| sess.zeroKeys(); for (&client.observes) |*obs| { @@ -514,9 +532,6 @@ pub fn deinit(client: *Client) void { posix.close(client.fd); client.allocator.free(client.send_buf); client.allocator.free(client.recv_buf); - for (client.slots) |*slot| { - slot.block2_payload.deinit(client.allocator); - } client.allocator.free(client.slots); client.allocator.free(client.slot_table); } @@ -697,9 +712,8 @@ pub fn cast( /// Automatically retransmits per RFC 7252 §4.2 (up to 4 retries, ~93s). /// Transparently reassembles Block2 multi-block responses. /// -/// `allocator` is used to parse the response packet (and to accumulate -/// Block2 payload when reassembly is needed). The caller owns the -/// returned `Result` and must call `result.deinit(allocator)`. +/// The returned Result borrows buffers; consume it before reusing storage. +/// Returns RequestsInFlight rather than discarding unrelated completions. /// /// For simple path-based requests, prefer `get()`, `post()`, `put()`, /// `delete()` which build URI-Path options automatically. @@ -709,23 +723,18 @@ pub fn cast( /// Returns `error.TooManyInFlight` if `max_in_flight` slots are exhausted. pub fn call( client: *Client, - allocator: std.mem.Allocator, + buffers: ResponseBuffers, code: coapz.Code, options: []const coapz.Option, payload: []const u8, ) !Result { - const handle = try client.submit(code, options, payload); + if (client.count_active != 0) return error.RequestsInFlight; + const handle = try client.submit(buffers, code, options, payload); while (true) { - const completion = try client.poll(allocator, 50) orelse continue; - if (completion.handle == handle) { - if (completion.result._timeout) return error.Timeout; - if (completion.result._reset) return error.Reset; - return completion.result; - } - // Completion for a different handle — discard. - // (Only happens if caller mixed call() with submit/poll.) - completion.result.deinit(allocator); + const completion = try client.poll(50) orelse continue; + std.debug.assert(completion.handle == handle); + return completion.result; } } @@ -735,17 +744,36 @@ pub fn call( /// identifies this request in subsequent poll() completions. /// /// The request is serialized, encrypted (if DTLS), and sent immediately. -/// Use poll() to drive the event loop and receive completions. +/// Use poll() to drive the event loop and receive completions. Response buffers +/// are exclusively borrowed until completion, cancel(), or client.deinit(). +/// Option values must remain valid until completion for Block2 continuations. +/// At most 16 request options are supported; excess is rejected, not truncated. /// /// Returns error.TooManyInFlight if max_in_flight slots are exhausted. /// Returns error.NstartExceeded if peer is unconfirmed and NSTART /// outstanding CONs are already in flight (RFC 7252 §4.7). pub fn submit( client: *Client, + buffers: ResponseBuffers, code: coapz.Code, options: []const coapz.Option, payload: []const u8, ) !RequestHandle { + if (options.len > 16) return error.TooManyRequestOptions; + if (std.debug.runtime_safety) { + std.debug.assert(buffersDisjoint(buffers)); + for (client.slots) |slot| { + if (slot.state == .pending) std.debug.assert(!buffersOverlap(buffers, slot.response_buffers)); + } + } + var block2_offset: usize = 0; + for (options) |option| { + if (option.kind == .block2) { + const block = option.as_block() orelse return error.InvalidBlock2; + if (block.szx == 7) return error.InvalidBlock2; + block2_offset = @as(usize, block.num) * (@as(usize, 1) << (@as(u4, block.szx) + 4)); + } + } // NSTART enforcement (RFC 7252 §4.7): limit outstanding CONs // to nstart until the first successful response from this peer. if (!client.peer_confirmed and client.count_active >= constants.nstart) { @@ -792,7 +820,10 @@ pub fn submit( } slot.original_options_len = opt_count; slot.doing_block2 = false; - slot.block2_payload = .empty; + slot.response_buffers = buffers; + slot.acknowledged = false; + slot.block2_length = 0; + slot.block2_offset = block2_offset; slot.original_handle = slot_idx; const initial_timeout = client.randomizedTimeout(constants.ack_timeout_ms); @@ -815,260 +846,142 @@ pub fn submit( /// Returns a Completion if any submitted request finished, null if /// nothing completed within timeout_ms (0 = non-blocking). /// -/// Caller must call completion.result.deinit(allocator) when done. +/// completion.result is an error union, correlated by handle. Results borrow +/// the buffers attached to submit(); no deinit is required. /// /// Multiple calls to poll() are needed to drain all pending completions /// when multiple requests are in flight. -pub fn poll( - client: *Client, - allocator: std.mem.Allocator, - timeout_ms: i32, -) !?Completion { +/// Process responses into the storage attached to submit(). No heap allocation. +pub fn poll(client: *Client, timeout_ms: i32) !?Completion { if (client.count_active == 0) return null; - - // Check retransmissions for all active slots. const now = nanoTimestamp(); - var earliest_retransmit: i64 = now + 50 * std.time.ns_per_ms; + var earliest: i64 = now + 50 * std.time.ns_per_ms; for (client.slots, 0..) |*slot, i| { if (slot.state != .pending) continue; if (now >= slot.next_retransmit_ns) { - if (slot.retransmit_count >= constants.max_retransmit) { - const idx: u16 = @intCast(i); - const orig_handle = slot.original_handle; - client.freeSlotAndTable(idx); - return .{ .handle = orig_handle, .result = timeoutResult() }; - } - const wire = client.send_buf[slot.send_offset..][0..slot.send_len]; - client.sendCoap(wire) catch {}; + if (slot.acknowledged or slot.retransmit_count >= constants.max_retransmit) + return client.finish(@intCast(i), error.Timeout); + client.sendCoap(client.send_buf[slot.send_offset..][0..slot.send_len]) catch |err| + return client.finish(@intCast(i), err); slot.retransmit_count += 1; slot.timeout_ns *= 2; slot.next_retransmit_ns = now + @as(i64, @intCast(slot.timeout_ns)); } - if (slot.next_retransmit_ns < earliest_retransmit) { - earliest_retransmit = slot.next_retransmit_ns; - } - } - - // Compute effective timeout: min of caller's timeout and next retransmit. - const effective_timeout: i32 = blk: { - if (timeout_ms == 0) break :blk 0; - const retransmit_ms: i64 = @divTrunc(earliest_retransmit - now, std.time.ns_per_ms); - break :blk @intCast(@max(1, @min(timeout_ms, retransmit_ms))); - }; - - const raw_data = client.pollRecv(effective_timeout) orelse return null; - var pt_buf: [constants.buffer_size_default]u8 = undefined; - const data = client.decryptRecv(raw_data, &pt_buf) orelse return null; - - if (data.len < 4) return null; - - const tkl: u8 = data[0] & 0x0F; - if (data.len < 4 + tkl) return null; - const recv_token = data[4..][0..tkl]; - - // Route observe notifications. - if (client.routeObserve(recv_token, data)) return null; - - // Find matching slot via token hash table. - const key = client.tokenKey(recv_token); - const slot_idx = client.findSlot(key) orelse return null; - const slot = &client.slots[slot_idx]; - - // Verify token matches exactly. - if (slot.token_len != tkl) return null; - if (!std.mem.eql(u8, slot.token[0..slot.token_len], recv_token)) return null; - - client.peer_confirmed = true; - - const response = coapz.Packet.read(allocator, data) catch return null; - - if (response.kind == .reset) { - const orig_handle = slot.original_handle; - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - return .{ .handle = orig_handle, .result = resetResult() }; - } - - // Block2 handling. - var blk2_it = response.find_options(.block2); - if (blk2_it.next()) |blk2_opt| { - if (blk2_opt.as_block()) |blk2| { - // ETag consistency check (RFC 7959 §2.4). - if (!checkBlock2Etag(slot, response)) { - slot.block2_payload.deinit(allocator); - slot.block2_payload = .empty; - slot.doing_block2 = false; - const orig_handle = slot.original_handle; - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - return .{ .handle = orig_handle, .result = etagMismatchResult() }; - } - if (blk2.more) { - slot.block2_payload.appendSlice(allocator, response.payload) catch { - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - return null; - }; - slot.doing_block2 = true; - - // Save Block2 state before freeing old slot. - var saved_b2 = slot.block2_payload; - const saved_code = slot.original_code; - const saved_olen = slot.original_options_len; - const saved_handle = slot.original_handle; - var saved_opts: [16]coapz.Option = undefined; - @memcpy(saved_opts[0..saved_olen], slot.original_options_buf[0..saved_olen]); - - // Prevent freeSlot from deiniting the ArrayList we're migrating. - slot.block2_payload = .empty; - slot.doing_block2 = false; - - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - - // Send Block2 continuation, getting a new slot. - const new_idx = client.sendBlock2Request( - blk2.num + 1, - blk2.szx, - saved_code, - saved_opts[0..saved_olen], - ) catch { - saved_b2.deinit(allocator); - return null; - }; - - // Migrate Block2 state to new slot. - const new_slot = &client.slots[new_idx]; - new_slot.block2_payload = saved_b2; - new_slot.doing_block2 = true; - new_slot.block2_etag = slot.block2_etag; - new_slot.block2_etag_len = slot.block2_etag_len; - new_slot.original_code = saved_code; - @memcpy(new_slot.original_options_buf[0..saved_olen], saved_opts[0..saved_olen]); - new_slot.original_options_len = saved_olen; - new_slot.original_handle = saved_handle; - - return null; // Not complete yet. - } - } + earliest = @min(earliest, slot.next_retransmit_ns); } - - // Final response — may be last block of a Block2 sequence. - const was_block2 = slot.doing_block2; - var saved_b2 = slot.block2_payload; - const orig_handle = slot.original_handle; - // Prevent freeSlot from deiniting payload we're using. - slot.block2_payload = .empty; - slot.doing_block2 = false; - client.freeSlotAndTable(slot_idx); - - if (was_block2) { - saved_b2.appendSlice(allocator, response.payload) catch { - response.deinit(allocator); - saved_b2.deinit(allocator); - return null; - }; - - const final_code = response.code; - const final_options = allocator.dupe(coapz.Option, response.options) catch { - response.deinit(allocator); - saved_b2.deinit(allocator); - return null; - }; - response.deinit(allocator); - - const full_payload = allocator.alloc(u8, saved_b2.items.len) catch { - allocator.free(@constCast(final_options)); - saved_b2.deinit(allocator); + const wait_ms: i32 = if (timeout_ms == 0) 0 else @intCast(@max(1, @min(timeout_ms, @divTrunc(earliest - now, std.time.ns_per_ms)))); + const raw = client.pollRecv(wait_ms) orelse return null; + var plaintext: [constants.buffer_size_default]u8 = undefined; + const data = client.decryptRecv(raw, &plaintext) orelse return null; + if (data.len < 4 or data[0] >> 6 != 1) return null; + const tkl: usize = data[0] & 15; + if (tkl > 8 or data.len < 4 + tkl) return null; + const kind = coapz.Packet.peekKind(data); + const mid = coapz.Packet.peekMsgId(data).?; + if (kind == .reset or (kind == .acknowledgement and data[1] == 0)) { + if (data.len != 4 or data[1] != 0) return null; + for (client.slots, 0..) |*slot, i| { + if (slot.state != .pending or slot.msg_id != mid) continue; + if (kind == .reset) return client.finish(@intCast(i), error.Reset); + if (slot.acknowledged) return null; + slot.acknowledged = true; + slot.next_retransmit_ns = now + @as(i64, constants.max_transmit_wait_ms) * std.time.ns_per_ms; return null; - }; - @memcpy(full_payload, saved_b2.items); - saved_b2.deinit(allocator); - - return .{ - .handle = orig_handle, - .result = .{ - .code = final_code, - .options = final_options, - .payload = full_payload, - .packet = .{ - .kind = .acknowledgement, - .code = final_code, - .msg_id = 0, - .token = &.{}, - .options = final_options, - .payload = full_payload, - .data_buf = &.{}, - }, - ._owns_payload = true, - ._owns_options = true, - }, - }; + } + return null; } + const token = data[4..][0..tkl]; + if (client.routeObserve(token, data)) return null; + const idx = client.findSlot(client.tokenKey(token)) orelse return null; + const slot = &client.slots[idx]; + if (!std.mem.eql(u8, slot.token[0..slot.token_len], token)) return null; + if (kind == .acknowledgement and mid != slot.msg_id) return null; + if (data[1] >> 5 < 2) return null; + return client.processResponse(idx, data); +} - return .{ - .handle = orig_handle, - .result = .{ - .code = response.code, - .options = response.options, - .payload = response.payload, - .packet = response, - }, - }; +/// Abandon a currently pending handle and release its storage borrow. +/// Does not retract a transmitted request or cancel remote application work. +/// Handles are reusable; never cancel a handle after consuming its completion. +pub fn cancel(client: *Client, handle: RequestHandle) void { + if (handle >= client.slots.len or client.slots[handle].state != .pending) return; + client.freeSlotAndTable(handle); } -fn timeoutResult() Result { - return .{ - .code = .empty, - .options = &.{}, - .payload = &.{}, - .packet = .{ - .kind = .reset, - .code = .empty, - .msg_id = 0, - .token = &.{}, - .options = &.{}, - .payload = &.{}, - .data_buf = &.{}, - }, - ._timeout = true, - }; +fn finish(client: *Client, idx: u16, result: anyerror!Result) Completion { + const handle = client.slots[idx].original_handle; + client.freeSlotAndTable(idx); + return .{ .handle = handle, .result = result }; } -fn resetResult() Result { - return .{ - .code = .empty, - .options = &.{}, - .payload = &.{}, - .packet = .{ - .kind = .reset, - .code = .empty, - .msg_id = 0, - .token = &.{}, - .options = &.{}, - .payload = &.{}, - .data_buf = &.{}, - }, - ._reset = true, +fn processResponse(client: *Client, idx: u16, data: []const u8) !?Completion { + const slot = &client.slots[idx]; + const buffers = slot.response_buffers; + if (data.len > buffers.packet.len) return client.finish(idx, error.ResponseBufferTooSmall); + @memcpy(buffers.packet[0..data.len], data); + var packet = packet_view.read(buffers.packet[0..data.len], buffers.options) catch |err| { + if (err == error.ResponseOptionsTooSmall) return client.finish(idx, err); + return null; // Malformed datagrams do not complete a pending request. }; + client.peer_confirmed = true; + if (packet.kind == .confirmable) client.sendAck(packet.msg_id, &.{}) catch |err| return client.finish(idx, err); + if (@intFromEnum(packet.code) >> 5 != 2) + return client.finish(idx, .{ .code = packet.code, .options = packet.options, .payload = packet.payload, .packet = packet }); + if (packet.find_option(.block2)) |option| { + const block = option.as_block() orelse return client.finish(idx, error.InvalidBlock2); + if (block.szx == 7) return client.finish(idx, error.InvalidBlock2); + const block_size: usize = @as(usize, 1) << (@as(u4, block.szx) + 4); + const offset = @as(u64, block.num) * block_size; + // A retransmitted separate CON block must be ACKed but not appended. + if (slot.doing_block2 and offset < slot.block2_offset + slot.block2_length) return null; + if (offset != slot.block2_offset + slot.block2_length or packet.payload.len > block_size) + return client.finish(idx, error.InvalidBlock2); + if (!checkBlock2Etag(slot, packet)) return client.finish(idx, error.EtagMismatch); + if (block.more or slot.doing_block2) { + if (packet.payload.len > buffers.payload.len - slot.block2_length) + return client.finish(idx, error.ResponsePayloadTooSmall); + @memcpy(buffers.payload[slot.block2_length..][0..packet.payload.len], packet.payload); + slot.block2_length += packet.payload.len; + slot.doing_block2 = true; + if (block.more) { + if (packet.payload.len != block_size) return client.finish(idx, error.InvalidBlock2); + client.continueBlock2(idx, block.num + 1, block.szx) catch |err| return client.finish(idx, err); + return null; + } + packet.payload = buffers.payload[0..slot.block2_length]; + } + } else if (slot.doing_block2) return client.finish(idx, error.InvalidBlock2); + return client.finish(idx, .{ .code = packet.code, .options = packet.options, .payload = packet.payload, .packet = packet }); } -fn etagMismatchResult() Result { - return .{ - .code = .empty, - .options = &.{}, - .payload = &.{}, - .packet = .{ - .kind = .reset, - .code = .empty, - .msg_id = 0, - .token = &.{}, - .options = &.{}, - .payload = &.{}, - .data_buf = &.{}, - }, - ._etag_mismatch = true, +fn continueBlock2(client: *Client, idx: u16, num: u32, szx: u3) !void { + if (num > 0xfffff) return error.InvalidBlock2; + const slot = &client.slots[idx]; + var options: [17]coapz.Option = undefined; + var count: usize = 0; + for (slot.original_options_buf[0..slot.original_options_len]) |option| { + if (option.kind == .block2 or option.kind == .block1) continue; + options[count] = option; + count += 1; + } + var encoded_block: [3]u8 = undefined; + options[count] = (coapz.BlockValue{ .num = num, .more = false, .szx = szx }).option(.block2, &encoded_block); + count += 1; + const Order = struct { + fn less(_: void, a: coapz.Option, b: coapz.Option) bool { + return @intFromEnum(a.kind) < @intFromEnum(b.kind); + } }; + std.mem.sort(coapz.Option, options[0..count], {}, Order.less); + const packet: coapz.Packet = .{ .kind = .confirmable, .code = slot.original_code, .msg_id = client.nextMsgId(), .token = slot.token[0..slot.token_len], .options = options[0..count], .payload = &.{}, .data_buf = &.{} }; + const wire = try packet.writeBuf(client.send_buf[slot.send_offset..][0..client.config.buffer_size]); + slot.msg_id = packet.msg_id; + slot.send_len = @intCast(wire.len); + slot.retransmit_count = 0; + slot.acknowledged = false; + slot.timeout_ns = client.randomizedTimeout(constants.ack_timeout_ms); + slot.next_retransmit_ns = nanoTimestamp() + @as(i64, @intCast(slot.timeout_ns)); + try client.sendCoap(wire); } // ─── Path convenience methods ──────────────────────────────────── @@ -1076,33 +989,28 @@ fn etagMismatchResult() Result { const uri = @import("uri.zig"); /// CON GET by URI path. Splits `path` into URI-Path options and -/// calls `call()`. Caller must call `result.deinit(allocator)`. -/// -/// ```zig -/// const result = try client.get(allocator, "/sensor/temperature"); -/// defer result.deinit(allocator); -/// ``` -pub fn get(client: *Client, allocator: std.mem.Allocator, path: []const u8) !Result { +/// calls `call()`. The result borrows the supplied response buffers. +pub fn get(client: *Client, buffers: ResponseBuffers, path: []const u8) !Result { var buf: [uri.max_options]coapz.Option = undefined; - return client.call(allocator, .get, uri.fromUri(path, &buf), &.{}); + return client.call(buffers, .get, uri.fromUri(path, &buf), &.{}); } -/// CON POST by URI path (with optional query) and payload. Caller must call `result.deinit(allocator)`. -pub fn post(client: *Client, allocator: std.mem.Allocator, path: []const u8, payload: []const u8) !Result { +/// CON POST by URI path and payload. Result borrows buffers. +pub fn post(client: *Client, buffers: ResponseBuffers, path: []const u8, payload: []const u8) !Result { var buf: [uri.max_options]coapz.Option = undefined; - return client.call(allocator, .post, uri.fromUri(path, &buf), payload); + return client.call(buffers, .post, uri.fromUri(path, &buf), payload); } -/// CON PUT by URI path (with optional query) and payload. Caller must call `result.deinit(allocator)`. -pub fn put(client: *Client, allocator: std.mem.Allocator, path: []const u8, payload: []const u8) !Result { +/// CON PUT by URI path and payload. Result borrows buffers. +pub fn put(client: *Client, buffers: ResponseBuffers, path: []const u8, payload: []const u8) !Result { var buf: [uri.max_options]coapz.Option = undefined; - return client.call(allocator, .put, uri.fromUri(path, &buf), payload); + return client.call(buffers, .put, uri.fromUri(path, &buf), payload); } -/// CON DELETE by URI path (with optional query). Caller must call `result.deinit(allocator)`. -pub fn delete(client: *Client, allocator: std.mem.Allocator, path: []const u8) !Result { +/// CON DELETE by URI path. Result borrows buffers. +pub fn delete(client: *Client, buffers: ResponseBuffers, path: []const u8) !Result { var buf: [uri.max_options]coapz.Option = undefined; - return client.call(allocator, .delete, uri.fromUri(path, &buf), &.{}); + return client.call(buffers, .delete, uri.fromUri(path, &buf), &.{}); } // ─── sendRaw / recvRaw ─────────────────────────────────────────── @@ -1244,27 +1152,30 @@ pub fn observe( /// each as a separate CON request. Honors the server's preferred block /// size if it responds with a smaller SZX value. /// -/// Returns the server's response to the final block. Caller must call -/// `result.deinit(allocator)`. +/// Returns the final borrowed response. Intermediate replies reuse the same +/// buffers; final Block2 reassembly is bounded too. Consume before reuse. /// /// ```zig -/// const result = try client.upload(allocator, .put, &.{ +/// var storage: Client.ResponseStorage(4096) = .{}; +/// const result = try client.upload(storage.buffers(), .put, &.{ /// .{ .kind = .uri_path, .value = "firmware" }, /// }, large_payload); -/// defer result.deinit(allocator); /// ``` pub fn upload( client: *Client, - allocator: std.mem.Allocator, + buffers: ResponseBuffers, code: coapz.Code, options: []const coapz.Option, payload: []const u8, ) !Result { + if (options.len > 15) return error.TooManyRequestOptions; + if (payload.len > std.math.maxInt(u32)) return error.UploadTooLarge; var szx = client.config.default_szx; var block_size: usize = @as(usize, 1) << (@as(u4, szx) + 4); var block_num: u32 = 0; while (true) { + if (block_num > 0xfffff) return error.UploadTooLarge; const start = block_num * block_size; const end = @min(start + block_size, payload.len); const is_last = (end >= payload.len); @@ -1279,14 +1190,19 @@ pub fn upload( const block_opt = block_val.option(.block1, &block_buf); var combined: [32]coapz.Option = undefined; - const opt_count = @min(options.len, 31); + const opt_count = options.len; for (0..opt_count) |i| { combined[i] = options[i]; } combined[opt_count] = block_opt; + std.mem.sort(coapz.Option, combined[0 .. opt_count + 1], {}, struct { + fn less(_: void, a: coapz.Option, b: coapz.Option) bool { + return @intFromEnum(a.kind) < @intFromEnum(b.kind); + } + }.less); const result = try client.call( - allocator, + buffers, code, combined[0 .. opt_count + 1], block_payload, @@ -1302,22 +1218,16 @@ pub fn upload( var resp_blk_it = result.packet.find_options(.block1); if (resp_blk_it.next()) |resp_blk_opt| { if (resp_blk_opt.as_block()) |resp_blk| { - if (resp_code != .@"continue") { - result.deinit(allocator); - return error.UploadRejected; - } + if (resp_code != .@"continue") return error.UploadRejected; if (resp_blk.szx < szx) { szx = resp_blk.szx; block_size = @as(usize, 1) << (@as(u4, szx) + 4); block_num = @intCast(end / block_size); - result.deinit(allocator); continue; } } } - result.deinit(allocator); - if (resp_code != .@"continue") { return error.UploadRejected; } @@ -1340,6 +1250,7 @@ fn sendCoap(client: *Client, wire: []const u8) !void { if (client.dtls_session) |*sess| { if (sess.state != .established) return error.DtlsNotEstablished; var enc_buf: [constants.buffer_size_default + dtls.types.record_overhead]u8 = undefined; + if (wire.len > constants.buffer_size_default) return error.BufferTooSmall; const encrypted = dtls.Record.encodeEncrypted( .application_data, wire, @@ -1366,7 +1277,7 @@ fn sendAck(client: *Client, msg_id: u16, token: []const u8) !void { }; var buf: [64]u8 = undefined; const wire = ack.writeBuf(&buf) catch return; - client.sendCoap(wire) catch {}; + try client.sendCoap(wire); } /// Non-blocking recv. Returns data slice or null if nothing available. @@ -1482,201 +1393,6 @@ fn routeObserve(client: *Client, token: []const u8, data: []const u8) bool { return false; } -/// Wait for a response to a specific in-flight slot. -/// Handles retransmission, Block2 reassembly (iterative), and observe routing. -fn waitForResponse( - client: *Client, - allocator: std.mem.Allocator, - cur_slot_idx: u16, - original_code: coapz.Code, - original_options: []const coapz.Option, -) !Result { - var slot_idx = cur_slot_idx; - var assembled_payload: std.ArrayListUnmanaged(u8) = .empty; - defer assembled_payload.deinit(allocator); - var doing_block2 = false; - - while (true) { - const slot = &client.slots[slot_idx]; - const now = nanoTimestamp(); - - // Check retransmission timeout. - if (slot.state == .pending and now >= slot.next_retransmit_ns) { - if (slot.retransmit_count >= constants.max_retransmit) { - client.freeSlotAndTable(slot_idx); - return error.Timeout; - } - const wire = client.send_buf[slot.send_offset..][0..slot.send_len]; - client.sendCoap(wire) catch {}; - slot.retransmit_count += 1; - slot.timeout_ns *= 2; - slot.next_retransmit_ns = now + @as(i64, @intCast(slot.timeout_ns)); - } - - // Wait until next retransmit deadline or a short poll interval. - const retransmit_remaining_ns = slot.next_retransmit_ns - now; - const timeout_ms: i32 = @intCast(@max(1, @divTrunc(@min(retransmit_remaining_ns, 50 * std.time.ns_per_ms), std.time.ns_per_ms))); - const raw_data = client.pollRecv(timeout_ms) orelse continue; - var pt_buf: [constants.buffer_size_default]u8 = undefined; - const data = client.decryptRecv(raw_data, &pt_buf) orelse continue; - - if (data.len < 4) continue; - - const tkl: u8 = data[0] & 0x0F; - if (data.len < 4 + tkl) continue; - const recv_token = data[4..][0..tkl]; - - // Route observe notifications. - if (client.routeObserve(recv_token, data)) continue; - - // Check if token matches our slot. - if (slot.token_len != tkl) continue; - if (!std.mem.eql(u8, slot.token[0..slot.token_len], recv_token)) continue; - - client.peer_confirmed = true; - - const response = coapz.Packet.read(allocator, data) catch continue; - - if (response.kind == .reset) { - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - return error.Reset; - } - - // Check for Block2 with more=true. - var blk2_it = response.find_options(.block2); - if (blk2_it.next()) |blk2_opt| { - if (blk2_opt.as_block()) |blk2| { - // ETag consistency check (RFC 7959 §2.4). - slot.doing_block2 = doing_block2; - if (!checkBlock2Etag(slot, response)) { - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - return error.EtagMismatch; - } - if (blk2.more) { - try assembled_payload.appendSlice(allocator, response.payload); - doing_block2 = true; - response.deinit(allocator); - client.freeSlotAndTable(slot_idx); - - slot_idx = try client.sendBlock2Request( - blk2.num + 1, - blk2.szx, - original_code, - original_options, - ); - continue; - } - } - } - - // Final response. - client.freeSlotAndTable(slot_idx); - - if (doing_block2) { - try assembled_payload.appendSlice(allocator, response.payload); - - const final_code = response.code; - const final_options = try allocator.dupe(coapz.Option, response.options); - response.deinit(allocator); - - const full_payload = try allocator.alloc(u8, assembled_payload.items.len); - @memcpy(full_payload, assembled_payload.items); - - return .{ - .code = final_code, - .options = final_options, - .payload = full_payload, - .packet = .{ - .kind = .acknowledgement, - .code = final_code, - .msg_id = 0, - .token = &.{}, - .options = final_options, - .payload = full_payload, - .data_buf = &.{}, - }, - ._owns_payload = true, - ._owns_options = true, - }; - } - - return .{ - .code = response.code, - .options = response.options, - .payload = response.payload, - .packet = response, - }; - } -} - -/// Send a Block2 continuation GET and set up a new in-flight slot. -fn sendBlock2Request( - client: *Client, - block_num: u32, - szx: u3, - code: coapz.Code, - options: []const coapz.Option, -) !u16 { - var token_buf: [8]u8 = undefined; - const token = client.makeToken(&token_buf); - const msg_id = client.nextMsgId(); - - var block_buf: [3]u8 = undefined; - const blk = coapz.BlockValue{ - .num = block_num, - .more = false, - .szx = szx, - }; - const block_opt = blk.option(.block2, &block_buf); - - var combined: [32]coapz.Option = undefined; - const opt_count = @min(options.len, 31); - for (0..opt_count) |i| { - combined[i] = options[i]; - } - combined[opt_count] = block_opt; - - const packet = coapz.Packet{ - .kind = .confirmable, - .code = code, - .msg_id = msg_id, - .token = token, - .options = combined[0 .. opt_count + 1], - .payload = &.{}, - .data_buf = &.{}, - }; - - const new_slot_idx = try client.allocSlot(); - const new_slot = &client.slots[new_slot_idx]; - const offset: u32 = @as(u32, new_slot_idx) * client.config.buffer_size; - const slot_buf = client.send_buf[offset..][0..client.config.buffer_size]; - const wire = packet.writeBuf(slot_buf) catch |err| { - client.freeSlot(new_slot_idx); - return err; - }; - - @memcpy(new_slot.token[0..token.len], token); - new_slot.token_len = @intCast(token.len); - new_slot.msg_id = msg_id; - new_slot.retransmit_count = 0; - new_slot.send_offset = offset; - new_slot.send_len = @intCast(wire.len); - new_slot.state = .pending; - - const initial_timeout = client.randomizedTimeout(constants.ack_timeout_ms); - new_slot.timeout_ns = initial_timeout; - new_slot.next_retransmit_ns = nanoTimestamp() + @as(i64, @intCast(initial_timeout)); - - client.insertTable(new_slot_idx, client.tokenKey(token)); - errdefer client.freeSlotAndTable(new_slot_idx); - - try client.sendCoap(wire); - - return new_slot_idx; -} - /// Wait for ACK to a specific in-flight slot (for observe registration). fn waitForAck(client: *Client, slot_idx: u16) !void { const slot = &client.slots[slot_idx]; @@ -1747,8 +1463,7 @@ fn allocSlot(client: *Client) !u16 { } fn freeSlot(client: *Client, idx: u16) void { - client.slots[idx].block2_payload.deinit(client.allocator); - client.slots[idx].block2_payload = .empty; + client.slots[idx].block2_length = 0; client.slots[idx].doing_block2 = false; client.slots[idx].state = .free; client.slots[idx].next_free = client.free_head; @@ -1942,6 +1657,321 @@ fn nullHandler(_: coap_handler.Request) ?coap_handler.Response { return null; } +fn metadataEchoHandler(request: coap_handler.Request) ?coap_handler.Response { + return .{ .payload = request.packet.payload, .options = &.{ + .{ .kind = .etag, .value = "tag-data" }, + .{ .kind = .content_format, .value = &.{0} }, + } }; +} + +fn awaitTestCompletion(client: *Client) !Completion { + for (0..100) |_| if (try client.poll(50)) |completion| return completion; + return error.NoCompletion; +} + +test "CON responses use caller storage, retain metadata, and perform no allocation" { + const port: u16 = 29730; + var server = try startTestServer(port, metadataEchoHandler); + defer server.deinit(); + var runner = ServerRunner{ .server = &server }; + const thread = try std.Thread.spawn(.{}, ServerRunner.run, .{&runner}); + defer runner.stop(thread); + var client = try Client.init(testing.allocator, .{ .port = port, .max_in_flight = 4 }); + defer client.deinit(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + var storage: [4]ResponseStorage(0) = .{ .{}, .{}, .{}, .{} }; + const first = try client.call(storage[0].buffers(), .get, &.{}, "retained"); + const one = try client.submit(storage[1].buffers(), .get, &.{}, "one"); + const two = try client.submit(storage[2].buffers(), .get, &.{}, "two"); + // Synchronous calls must not silently discard someone else's completion. + try testing.expectError(error.RequestsInFlight, client.call(storage[3].buffers(), .get, &.{}, "bad")); + var results: [2]Result = undefined; + for (0..2) |_| { + const completion = try awaitTestCompletion(&client); + const i: usize = if (completion.handle == one) 0 else 1; + try testing.expect(completion.handle == one or completion.handle == two); + results[i] = try completion.result; + } + _ = try client.call(storage[3].buffers(), .get, &.{}, "overwrite-receive-buffer"); + try testing.expectEqualSlices(u8, "retained", first.payload); + try testing.expectEqualSlices(u8, "one", results[0].payload); + try testing.expectEqualSlices(u8, "two", results[1].payload); + for ([_]Result{ first, results[0], results[1] }) |result| { + try testing.expectEqualSlices(u8, "tag-data", result.packet.find_option(.etag).?.value); + try testing.expectEqualSlices(u8, result.payload, result.packet.payload); + try testing.expectEqual(@as(usize, 2), result.packet.token.len); + } +} + +test "CON packet and option capacity failures are correlated and permit retry" { + const port: u16 = 29731; + var server = try startTestServer(port, metadataEchoHandler); + defer server.deinit(); + var runner = ServerRunner{ .server = &server }; + const thread = try std.Thread.spawn(.{}, ServerRunner.run, .{&runner}); + defer runner.stop(thread); + var client = try Client.init(testing.allocator, .{ .port = port }); + defer client.deinit(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + const handle = try client.submit(.{ .packet = &.{}, .options = &.{} }, .get, &.{}, "payload"); + const completion = try awaitTestCompletion(&client); + try testing.expectEqual(handle, completion.handle); + try testing.expectError(error.ResponseBufferTooSmall, completion.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + var storage: ResponseStorage(0) = .{}; + const retry = try client.call(storage.buffers(), .get, &.{}, "retry"); + try testing.expectEqualSlices(u8, "retry", retry.payload); + const h2 = try client.submit(.{ .packet = &storage.packet, .options = &.{} }, .get, &.{}, "options"); + const c2 = try awaitTestCompletion(&client); + try testing.expectEqual(h2, c2.handle); + try testing.expectError(error.ResponseOptionsTooSmall, c2.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + _ = try client.call(storage.buffers(), .get, &.{}, "retry-again"); +} + +const bounded_test_body = blk: { + @setEvalBranchQuota(4000); + var bytes: [3000]u8 = undefined; + for (&bytes, 0..) |*byte, i| byte.* = @intCast(i % 251); + break :blk bytes; +}; + +fn boundedBodyHandler(_: coap_handler.Request) ?coap_handler.Response { + return .{ .payload = &bounded_test_body }; +} + +test "plain and DTLS Block1/Block2 responses are bounded and allocation-free" { + const credentials: dtls.types.Psk = .{ .identity = "bounded", .key = "0123456789abcdef" }; + for ([_]bool{ false, true }, 0..) |encrypted, i| { + const port: u16 = @intCast(29732 + i); + var server = try coap_server.init(testing.allocator, .{ + .port = port, + .buffer_count = 16, + .buffer_size = 1280, + .exchange_count = 16, + .rate_limit_ip_count = 0, + .max_block_transfers = 8, + .max_block_payload = 8192, + .psk = if (encrypted) credentials else null, + }, boundedBodyHandler); + defer server.deinit(); + try server.listen(); + var runner = ServerRunner{ .server = &server }; + const thread = try std.Thread.spawn(.{}, ServerRunner.run, .{&runner}); + defer runner.stop(thread); + var client = try Client.init(testing.allocator, .{ .port = port, .psk = if (encrypted) credentials else null }); + defer client.deinit(); + if (encrypted) try client.handshake(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + var small: ResponseStorage(3000) = .{}; + for ([_]usize{ 0, 1800, 2999 }) |capacity| { + var buffers = small.buffers(); + buffers.payload = buffers.payload[0..capacity]; + const handle = try client.submit(buffers, .get, &.{}, &.{}); + const failed = try awaitTestCompletion(&client); + try testing.expectEqual(handle, failed.handle); + try testing.expectError(error.ResponsePayloadTooSmall, failed.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + } + var full: ResponseStorage(3000) = .{}; + const result = try client.get(full.buffers(), "/large"); + try testing.expectEqualSlices(u8, &bounded_test_body, result.payload); + try testing.expectEqual(@as(u32, 3000), result.packet.find_option(.size2).?.as_uint().?); + var upload_storage: ResponseStorage(3000) = .{}; + const uploaded = try client.upload(upload_storage.buffers(), .put, &.{ + .{ .kind = .uri_path, .value = "large" }, + .{ .kind = .size1, .value = &.{ 8, 0 } }, + }, &([_]u8{7} ** 2048)); + try testing.expectEqualSlices(u8, &bounded_test_body, uploaded.payload); + // The second reassembly must not overwrite the first result or metadata. + try testing.expectEqualSlices(u8, &bounded_test_body, result.packet.payload); + try testing.expectEqual(@as(u32, 3000), result.packet.find_option(.size2).?.as_uint().?); + } +} + +test "cancel, timeout, and serialization failure release caller buffer borrows" { + const port: u16 = 29734; + var server = try startTestServer(port, nullHandler); + defer server.deinit(); + var client = try Client.init(testing.allocator, .{ .port = port, .max_in_flight = 1 }); + defer client.deinit(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + var storage: ResponseStorage(0) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{}, "cancel"); + client.cancel(h); + try testing.expectEqual(@as(u16, 0), client.count_active); + const again = try client.submit(storage.buffers(), .get, &.{}, "timeout"); + client.slots[again].retransmit_count = constants.max_retransmit; + client.slots[again].next_retransmit_ns = nanoTimestamp() - 1; + const completion = (try client.poll(0)).?; + try testing.expectEqual(again, completion.handle); + try testing.expectError(error.Timeout, completion.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + try testing.expectError(error.BufferTooSmall, client.submit(storage.buffers(), .get, &.{}, &([_]u8{0} ** 2000))); + try testing.expectEqual(@as(u16, 0), client.count_active); + const valid = try client.submit(storage.buffers(), .get, &.{}, "reused"); + client.cancel(valid); + var block_buf: [3]u8 = undefined; + const invalid = (coapz.BlockValue{ .num = 0, .more = false, .szx = 7 }).option(.block2, &block_buf); + try testing.expectError(error.InvalidBlock2, client.submit(storage.buffers(), .get, &.{invalid}, &.{})); + try testing.expectEqual(@as(u16, 0), client.count_active); +} + +fn injectTestBlock(client: *Client, handle: RequestHandle, num: u32, szx: u3, more: bool, bytes: []const u8, tag: []const u8, kind: coapz.MessageKind) !?Completion { + const slot = &client.slots[handle]; + var block_buf: [3]u8 = undefined; + const block = (coapz.BlockValue{ .num = num, .szx = szx, .more = more }).option(.block2, &block_buf); + const packet: coapz.Packet = .{ .kind = kind, .code = .content, .msg_id = slot.msg_id, .token = slot.token[0..slot.token_len], .payload = bytes, .data_buf = &.{}, .options = &.{ .{ .kind = .etag, .value = tag }, block } }; + var wire: [1280]u8 = undefined; + return client.processResponse(handle, try packet.writeBuf(&wire)); +} + +test "Block2 handles reduced SZX, duplicate separate blocks, and retained option values" { + const port: u16 = 29735; + var server = try startTestServer(port, nullHandler); + defer server.deinit(); + var client = try Client.init(testing.allocator, .{ .port = port }); + defer client.deinit(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + var storage: ResponseStorage(55) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{ + .{ .kind = .uri_path, .value = "a" }, + .{ .kind = .uri_path, .value = "b" }, + .{ .kind = .size1, .value = &.{55} }, + }, &.{}); + const token = client.slots[h].token; + try testing.expect((try injectTestBlock(&client, h, 0, 1, true, &([_]u8{1} ** 32), "tag", .acknowledgement)) == null); + try testing.expectEqualSlices(u8, token[0..client.config.token_len], client.slots[h].token[0..client.config.token_len]); + var decoded_options: [17]coapz.Option = undefined; + const pending = &client.slots[h]; + const continuation = try packet_view.read(client.send_buf[pending.send_offset..][0..pending.send_len], &decoded_options); + try testing.expectEqualSlices(u8, "a", continuation.options[0].value); + try testing.expectEqualSlices(u8, "b", continuation.options[1].value); + try testing.expectEqual(.block2, continuation.options[2].kind); + try testing.expectEqual(.size1, continuation.options[3].kind); + // Retransmitted separate block: ACK it without duplicate assembly. + try testing.expect((try injectTestBlock(&client, h, 0, 1, true, &([_]u8{1} ** 32), "tag", .confirmable)) == null); + try testing.expectEqual(@as(usize, 32), client.slots[h].block2_length); + try testing.expect((try injectTestBlock(&client, h, 2, 0, true, &([_]u8{2} ** 16), "tag", .acknowledgement)) == null); + const completion = (try injectTestBlock(&client, h, 3, 0, false, "1234567", "tag", .acknowledgement)).?; + try testing.expectEqual(h, completion.handle); + const result = try completion.result; + try testing.expectEqualSlices(u8, &([_]u8{1} ** 32 ++ [_]u8{2} ** 16 ++ "1234567".*), result.payload); + const next = try client.submit(.{ .packet = &.{}, .options = &.{} }, .get, &.{}, &.{}); + client.cancel(next); + try testing.expectEqualSlices(u8, "tag", result.packet.find_option(.etag).?.value); + try testing.expectEqualSlices(u8, result.payload, result.packet.payload); +} + +test "Block2 ETag mismatch and invalid offsets complete with correlated errors" { + const port: u16 = 29736; + var server = try startTestServer(port, nullHandler); + defer server.deinit(); + var client = try Client.init(testing.allocator, .{ .port = port }); + defer client.deinit(); + var storage: ResponseStorage(64) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{}, &.{}); + try testing.expect((try injectTestBlock(&client, h, 0, 0, true, &([_]u8{1} ** 16), "a", .acknowledgement)) == null); + const mismatch = (try injectTestBlock(&client, h, 1, 0, false, "end", "b", .acknowledgement)).?; + try testing.expectEqual(h, mismatch.handle); + try testing.expectError(error.EtagMismatch, mismatch.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + const h2 = try client.submit(storage.buffers(), .get, &.{}, &.{}); + const invalid = (try injectTestBlock(&client, h2, 1, 0, true, &([_]u8{1} ** 16), "a", .acknowledgement)).?; + try testing.expectEqual(h2, invalid.handle); + try testing.expectError(error.InvalidBlock2, invalid.result); + try testing.expectEqual(@as(u16, 0), client.count_active); + var block_buf: [3]u8 = undefined; + const last = (coapz.BlockValue{ .num = 0xfffff, .szx = 0, .more = false }).option(.block2, &block_buf); + const h3 = try client.submit(storage.buffers(), .get, &.{last}, &.{}); + const exhausted = (try injectTestBlock(&client, h3, 0xfffff, 0, true, &([_]u8{1} ** 16), "a", .acknowledgement)).?; + try testing.expectEqual(h3, exhausted.handle); + try testing.expectError(error.InvalidBlock2, exhausted.result); + try testing.expectEqual(@as(u16, 0), client.count_active); +} + +fn sendTestReply(server: *coap_server, client: *Client, kind: coapz.MessageKind, code: coapz.Code, mid: u16, token: []const u8, payload: []const u8) !void { + var address: posix.SocketAddress = undefined; + var len: linux.socklen_t = @sizeOf(posix.SocketAddress); + try testing.expectEqual(linux.E.SUCCESS, linux.errno(linux.getsockname(client.fd, &address.any, &len))); + var wire: [1280]u8 = undefined; + const packet: coapz.Packet = .{ .kind = kind, .code = code, .msg_id = mid, .token = token, .options = &.{}, .payload = payload, .data_buf = &.{} }; + _ = try posix.sendto(server.io.fd_socket.?, try packet.writeBuf(&wire), 0, try address.address()); +} + +test "poll matches empty ACK/RST by MID and bounds ACKed request lifetime" { + const port: u16 = 29737; + var server = try startTestServer(port, nullHandler); + defer server.deinit(); + var client = try Client.init(testing.allocator, .{ .port = port }); + defer client.deinit(); + const allocator = client.allocator; + defer client.allocator = allocator; + client.allocator = testing.failing_allocator; + var storage: ResponseStorage(0) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{}, "ack"); + const mid = client.slots[h].msg_id; + try sendTestReply(&server, &client, .acknowledgement, .empty, mid +% 1, &.{}, &.{}); + try testing.expect((try client.poll(100)) == null); + try testing.expect(!client.slots[h].acknowledged); + try sendTestReply(&server, &client, .acknowledgement, .empty, mid, &.{}, &.{}); + try testing.expect((try client.poll(100)) == null); + try testing.expect(client.slots[h].acknowledged); + const deadline = client.slots[h].next_retransmit_ns; + try sendTestReply(&server, &client, .acknowledgement, .empty, mid, &.{}, &.{}); + try testing.expect((try client.poll(100)) == null); + try testing.expectEqual(deadline, client.slots[h].next_retransmit_ns); + client.slots[h].next_retransmit_ns = nanoTimestamp() - 1; + const timeout = (try client.poll(0)).?; + try testing.expectEqual(h, timeout.handle); + try testing.expectError(error.Timeout, timeout.result); + const h2 = try client.submit(storage.buffers(), .get, &.{}, "reset"); + const mid2 = client.slots[h2].msg_id; + try sendTestReply(&server, &client, .reset, .empty, mid2 +% 1, &.{}, &.{}); + try testing.expect((try client.poll(100)) == null); + try sendTestReply(&server, &client, .reset, .empty, mid2, &.{}, &.{}); + const reset = (try client.poll(100)).?; + try testing.expectEqual(h2, reset.handle); + try testing.expectError(error.Reset, reset.result); + const h3 = try client.submit(storage.buffers(), .get, &.{}, "separate"); + const slot = &client.slots[h3]; + try sendTestReply(&server, &client, .acknowledgement, .empty, slot.msg_id, &.{}, &.{}); + try testing.expect((try client.poll(100)) == null); + try sendTestReply(&server, &client, .confirmable, .content, slot.msg_id +% 1, slot.token[0..slot.token_len], "separate"); + const completion = (try client.poll(100)).?; + try testing.expectEqual(h3, completion.handle); + try testing.expectEqualSlices(u8, "separate", (try completion.result).payload); + try testing.expectEqual(@as(u16, 0), client.count_active); +} + +test "caller-owned response remains valid after client destruction" { + const port: u16 = 29738; + var server = try startTestServer(port, nullHandler); + defer server.deinit(); + var client = try Client.init(testing.allocator, .{ .port = port }); + var alive = true; + defer if (alive) client.deinit(); + var storage: ResponseStorage(0) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{}, &.{}); + const completion = (try injectTestBlock(&client, h, 0, 0, false, "owned-by-caller", "tag", .acknowledgement)).?; + const result = try completion.result; + client.deinit(); + alive = false; + try testing.expectEqualSlices(u8, "owned-by-caller", result.payload); + try testing.expectEqualSlices(u8, "tag", result.packet.find_option(.etag).?.value); + try testing.expectEqual(@as(usize, 2), result.packet.token.len); +} + test "init and deinit" { var client = try Client.init(testing.allocator, .{ .port = 15683, @@ -2023,13 +2053,8 @@ test "call CON round-trip" { }); defer client.deinit(); - const result = try client.call( - testing.allocator, - .get, - &.{}, - "hello-con", - ); - defer result.deinit(testing.allocator); + var storage: ResponseStorage(0) = .{}; + const result = try client.call(storage.buffers(), .get, &.{}, "hello-con"); try testing.expectEqual(.content, result.code); try testing.expectEqualSlices(u8, "hello-con", result.payload); @@ -2081,8 +2106,8 @@ test "get convenience calls call with path options" { }); defer client.deinit(); - const result = try client.get(testing.allocator, "/hello"); - defer result.deinit(testing.allocator); + var storage: ResponseStorage(0) = .{}; + const result = try client.get(storage.buffers(), "/hello"); try testing.expectEqual(coapz.Code.content, result.code); } @@ -2097,8 +2122,9 @@ test "submit returns handle without blocking" { }); defer client.deinit(); + var storage: ResponseStorage(0) = .{}; const start = nanoTimestamp(); - const handle = try client.submit(.get, &.{}, "hello"); + const handle = try client.submit(storage.buffers(), .get, &.{}, "hello"); const elapsed_us = @divTrunc(nanoTimestamp() - start, std.time.ns_per_us); try testing.expect(elapsed_us < 5000); @@ -2120,20 +2146,20 @@ test "submit and poll round-trip" { }); defer client.deinit(); - const h = try client.submit(.get, &.{}, "async-hello"); + var storage: ResponseStorage(0) = .{}; + const h = try client.submit(storage.buffers(), .get, &.{}, "async-hello"); var completion: ?Completion = null; for (0..100) |_| { - completion = try client.poll(testing.allocator, 50); + completion = try client.poll(50); if (completion != null) break; } const c = completion orelse return error.NoCompletion; - defer c.result.deinit(testing.allocator); - + const result = try c.result; try testing.expectEqual(h, c.handle); - try testing.expectEqual(.content, c.result.code); - try testing.expectEqualSlices(u8, "async-hello", c.result.payload); + try testing.expectEqual(.content, result.code); + try testing.expectEqualSlices(u8, "async-hello", result.payload); } test "multiple concurrent submits" { @@ -2151,20 +2177,19 @@ test "multiple concurrent submits" { }); defer client.deinit(); + var storage: [4]ResponseStorage(0) = .{ .{}, .{}, .{}, .{} }; // Confirm peer first (NSTART enforcement). - const warmup = try client.call(testing.allocator, .get, &.{}, "warmup"); - warmup.deinit(testing.allocator); - - _ = try client.submit(.get, &.{}, "req-0"); - _ = try client.submit(.get, &.{}, "req-1"); - _ = try client.submit(.get, &.{}, "req-2"); - _ = try client.submit(.get, &.{}, "req-3"); + _ = try client.call(storage[0].buffers(), .get, &.{}, "warmup"); + _ = try client.submit(storage[0].buffers(), .get, &.{}, "req-0"); + _ = try client.submit(storage[1].buffers(), .get, &.{}, "req-1"); + _ = try client.submit(storage[2].buffers(), .get, &.{}, "req-2"); + _ = try client.submit(storage[3].buffers(), .get, &.{}, "req-3"); var completed: u8 = 0; for (0..200) |_| { - const c = try client.poll(testing.allocator, 50) orelse continue; - defer c.result.deinit(testing.allocator); - try testing.expectEqual(.content, c.result.code); + const c = try client.poll(50) orelse continue; + const result = try c.result; + try testing.expectEqual(.content, result.code); completed += 1; if (completed == 4) break; } @@ -2182,13 +2207,14 @@ test "NSTART: second submit rejected before first response" { }); defer client.deinit(); + var storage: [2]ResponseStorage(0) = .{ .{}, .{} }; // First submit should succeed (count_active=0 < nstart=1). - _ = try client.submit(.get, &.{}, "first"); + _ = try client.submit(storage[0].buffers(), .get, &.{}, "first"); // Second submit should fail — peer not confirmed, count_active=1 >= nstart. try testing.expectError( error.NstartExceeded, - client.submit(.get, &.{}, "second"), + client.submit(storage[1].buffers(), .get, &.{}, "second"), ); } @@ -2207,14 +2233,15 @@ test "NSTART: submit allowed after peer confirmed via poll" { }); defer client.deinit(); + var storage: [2]ResponseStorage(0) = .{ .{}, .{} }; // First submit — should work. - _ = try client.submit(.get, &.{}, "first"); + _ = try client.submit(storage[0].buffers(), .get, &.{}, "first"); // Poll until first response arrives — confirms peer. var confirmed = false; for (0..100) |_| { - const c = try client.poll(testing.allocator, 50) orelse continue; - c.result.deinit(testing.allocator); + const c = try client.poll(50) orelse continue; + _ = try c.result; confirmed = true; break; } @@ -2222,8 +2249,8 @@ test "NSTART: submit allowed after peer confirmed via poll" { try testing.expect(client.peer_confirmed); // Now submit should succeed — peer is confirmed. - _ = try client.submit(.get, &.{}, "second"); - _ = try client.submit(.get, &.{}, "third"); + _ = try client.submit(storage[0].buffers(), .get, &.{}, "second"); + _ = try client.submit(storage[1].buffers(), .get, &.{}, "third"); } test "NSTART: call confirms peer, subsequent submits work" { @@ -2244,15 +2271,15 @@ test "NSTART: call confirms peer, subsequent submits work" { try testing.expect(!client.peer_confirmed); // call() does submit+poll internally — should confirm peer. - const result = try client.call(testing.allocator, .get, &.{}, "hello"); - defer result.deinit(testing.allocator); + var storage: [4]ResponseStorage(0) = .{ .{}, .{}, .{}, .{} }; + _ = try client.call(storage[0].buffers(), .get, &.{}, "hello"); try testing.expect(client.peer_confirmed); // Multiple concurrent submits now work. - _ = try client.submit(.get, &.{}, "a"); - _ = try client.submit(.get, &.{}, "b"); - _ = try client.submit(.get, &.{}, "c"); + _ = try client.submit(storage[1].buffers(), .get, &.{}, "a"); + _ = try client.submit(storage[2].buffers(), .get, &.{}, "b"); + _ = try client.submit(storage[3].buffers(), .get, &.{}, "c"); } test "checkBlock2Etag captures and compares" { @@ -2267,7 +2294,7 @@ test "checkBlock2Etag captures and compares" { .send_offset = 0, .send_len = 0, .next_free = 0xFFFF, - .block2_payload = .empty, + .block2_length = 0, .doing_block2 = false, .block2_etag = undefined, .block2_etag_len = 0, diff --git a/src/dtls/integration_test.zig b/src/dtls/integration_test.zig index 3467c1a..57623da 100644 --- a/src/dtls/integration_test.zig +++ b/src/dtls/integration_test.zig @@ -77,8 +77,8 @@ test "DTLS: full handshake and CoAP echo over localhost" { try testing.expectEqual(.established, client.dtls_session.?.state); // CON GET — echo handler returns empty payload for GET. - const result = try client.get(testing.allocator, "/test"); - defer result.deinit(testing.allocator); + var storage: Client.ResponseStorage(0) = .{}; + const result = try client.get(storage.buffers(), "/test"); try testing.expectEqual(.content, result.code); } @@ -111,8 +111,8 @@ test "DTLS: CON POST echo with payload" { try testing.expectEqual(.established, client.dtls_session.?.state); // POST with payload — echo handler returns the payload back. - const result = try client.post(testing.allocator, "/echo", "hello-dtls"); - defer result.deinit(testing.allocator); + var storage: Client.ResponseStorage(0) = .{}; + const result = try client.post(storage.buffers(), "/echo", "hello-dtls"); try testing.expectEqual(.content, result.code); try testing.expectEqualSlices(u8, "hello-dtls", result.payload); } @@ -144,13 +144,13 @@ test "DTLS: multiple requests on one session" { try client.handshake(); + var storage: Client.ResponseStorage(0) = .{}; // Send multiple requests sequentially on the same session. for (0..5) |i| { var payload_buf: [32]u8 = undefined; const payload = std.fmt.bufPrint(&payload_buf, "msg-{d}", .{i}) catch unreachable; - const result = try client.post(testing.allocator, "/echo", payload); - defer result.deinit(testing.allocator); + const result = try client.post(storage.buffers(), "/echo", payload); try testing.expectEqual(.content, result.code); try testing.expectEqualSlices(u8, payload, result.payload); } @@ -180,8 +180,8 @@ test "plain UDP works without PSK" { defer client.deinit(); // Should work without handshake — no DTLS. - const result = try client.get(testing.allocator, "/hello"); - defer result.deinit(testing.allocator); + var storage: Client.ResponseStorage(0) = .{}; + const result = try client.get(storage.buffers(), "/hello"); try testing.expectEqual(.content, result.code); } @@ -266,8 +266,8 @@ test "Block1: handler receives full reassembled body" { const payload = [_]u8{0x42} ** 2048; var path_buf: [1]coapz.Option = .{coapz.Option{ .kind = .uri_path, .value = "data" }}; block1_received_len = 0; - const result = try client.upload(testing.allocator, .put, &path_buf, &payload); - defer result.deinit(testing.allocator); + var storage: Client.ResponseStorage(0) = .{}; + const result = try client.upload(storage.buffers(), .put, &path_buf, &payload); try testing.expectEqual(.changed, result.code); // Handler should have received the FULL reassembled body (2048 bytes). @@ -473,13 +473,14 @@ test "DTLS: deferred response is encrypted" { try testing.expectEqual(.established, client.dtls_session.?.state); // Submit CON POST — handler defers. - const handle = try client.submit(.post, &.{coapz.Option{ .kind = .uri_path, .value = "deferred" }}, "request"); + var storage: Client.ResponseStorage(0) = .{}; + const handle = try client.submit(storage.buffers(), .post, &.{coapz.Option{ .kind = .uri_path, .value = "deferred" }}, "request"); // Wait for handler to capture the deferred handle. var attempts: u32 = 0; while (!dtls_deferred_ready.load(.acquire)) : (attempts += 1) { if (attempts > 200) return error.Timeout; - _ = client.poll(testing.allocator, 10) catch {}; + _ = client.poll(10) catch {}; } // Deliver deferred response. @@ -495,16 +496,14 @@ test "DTLS: deferred response is encrypted" { // If sent as plaintext (#83), client won't parse it (expects DTLS records). var result: ?Client.Result = null; for (0..100) |_| { - if (client.poll(testing.allocator, 20) catch null) |completion| { + if (client.poll(20) catch null) |completion| { if (completion.handle == handle) { - result = completion.result; + result = try completion.result; break; } - completion.result.deinit(testing.allocator); } } const r = result orelse return error.Timeout; - defer r.deinit(testing.allocator); try testing.expectEqual(.content, r.code); try testing.expectEqualSlices(u8, "deferred-result", r.payload); @@ -544,8 +543,8 @@ test "DTLS: Block1 upload delivers reassembled body" { const payload = [_]u8{0x42} ** 2048; var path_buf: [1]coapz.Option = .{coapz.Option{ .kind = .uri_path, .value = "data" }}; block1_received_len = 0; - const result = try client.upload(testing.allocator, .put, &path_buf, &payload); - defer result.deinit(testing.allocator); + var storage: Client.ResponseStorage(0) = .{}; + const result = try client.upload(storage.buffers(), .put, &path_buf, &payload); try testing.expectEqual(.changed, result.code); try testing.expectEqual(@as(usize, 2048), block1_received_len); diff --git a/src/packet_view.zig b/src/packet_view.zig new file mode 100644 index 0000000..929028f --- /dev/null +++ b/src/packet_view.zig @@ -0,0 +1,103 @@ +//! Bounded, allocation-free CoAP decoding. All returned bytes borrow the wire +//! buffer; option descriptors borrow caller-provided storage. Never deinit the +//! returned coapz.Packet with an allocator. +const std = @import("std"); +const coapz = @import("coapz"); + +pub const Error = coapz.Error || error{ ResponseOptionsTooSmall, InvalidOption }; + +fn extended(data: []const u8, pos: *usize, nibble: u4) Error!u16 { + switch (nibble) { + 0...12 => return nibble, + 13 => { + if (pos.* >= data.len) return error.TruncatedOption; + const value: u16 = @as(u16, data[pos.*]) + 13; + pos.* += 1; + return value; + }, + 14 => { + if (data.len - pos.* < 2) return error.TruncatedOption; + const raw = std.mem.readInt(u16, data[pos.*..][0..2], .big); + pos.* += 2; + return std.math.add(u16, raw, 269) catch error.InvalidOption; + }, + 15 => return error.InvalidOption, + } +} + +pub fn read(data: []const u8, options: []coapz.Option) Error!coapz.Packet { + if (data.len < 4) return error.MessageTooShort; + if (data[0] >> 6 != 1) return error.InvalidVersion; + const tkl: usize = data[0] & 15; + if (tkl > 8) return error.InvalidTokenLength; + if (data.len < 4 + tkl) return error.MessageTooShort; + var pos: usize = 4 + tkl; + var count: usize = 0; + var kind: u16 = 0; + var payload: []const u8 = &.{}; + while (pos < data.len) { + const header = data[pos]; + pos += 1; + if (header == 255) { + if (pos == data.len) return error.EmptyPayload; + payload = data[pos..]; + break; + } + const delta = try extended(data, &pos, @truncate(header >> 4)); + const len = try extended(data, &pos, @truncate(header)); + kind = std.math.add(u16, kind, delta) catch return error.InvalidOption; + if (len > data.len - pos) return error.TruncatedOption; + if (count >= options.len) return error.ResponseOptionsTooSmall; + options[count] = .{ .kind = @enumFromInt(kind), .value = data[pos..][0..len] }; + count += 1; + pos += len; + } + return .{ .kind = @enumFromInt((data[0] >> 4) & 3), .code = @enumFromInt(data[1]), .msg_id = std.mem.readInt(u16, data[2..4], .big), .token = data[4..][0..tkl], .options = options[0..count], .payload = payload, .data_buf = &.{} }; +} + +test "packet view decodes extended lengths, deltas, and repeated options" { + const a = [_]u8{7} ** 13; + const b = [_]u8{9} ** 269; + const packet: coapz.Packet = .{ .kind = .confirmable, .code = .content, .msg_id = 500, .token = "12345678", .payload = "end", .data_buf = &.{}, .options = &.{ .{ .kind = .uri_path, .value = &a }, .{ .kind = .uri_path, .value = &.{} }, .{ .kind = .size1, .value = &b }, .{ .kind = @enumFromInt(64000), .value = "x" } } }; + var wire: [1024]u8 = undefined; + const data = try packet.writeBuf(&wire); + var options: [4]coapz.Option = undefined; + const view = try read(data, &options); + try std.testing.expectEqualSlices(u8, packet.token, view.token); + try std.testing.expectEqualSlices(u8, packet.payload, view.payload); + for (packet.options, view.options) |expected, actual| { + try std.testing.expectEqual(expected.kind, actual.kind); + try std.testing.expectEqualSlices(u8, expected.value, actual.value); + } +} + +test "packet view rejects malformed headers, options, and truncated extensions" { + var options: [4]coapz.Option = undefined; + try std.testing.expectError(error.MessageTooShort, read(&.{ 0x40, 0x45, 0 }, &options)); + try std.testing.expectError(error.InvalidVersion, read(&.{ 0x80, 0x45, 0, 0 }, &options)); + try std.testing.expectError(error.InvalidTokenLength, read(&.{ 0x49, 0x45, 0, 0 }, &options)); + try std.testing.expectError(error.MessageTooShort, read(&.{ 0x48, 0x45, 0, 0 }, &options)); + try std.testing.expectError(error.TruncatedOption, read(&.{ 0x40, 0x45, 0, 0, 0xd0 }, &options)); + try std.testing.expectError(error.TruncatedOption, read(&.{ 0x40, 0x45, 0, 0, 0x0e, 0 }, &options)); + try std.testing.expectError(error.TruncatedOption, read(&.{ 0x40, 0x45, 0, 0, 0x03, 1 }, &options)); + try std.testing.expectError(error.InvalidOption, read(&.{ 0x40, 0x45, 0, 0, 0xf0 }, &options)); + try std.testing.expectError(error.InvalidOption, read(&.{ 0x40, 0x45, 0, 0, 0x0f }, &options)); + try std.testing.expectError(error.InvalidOption, read(&.{ 0x40, 0x45, 0, 0, 0xe0, 255, 255 }, &options)); +} + +test "bounded packet view matches allocating decoder and rejects insufficient options" { + const wire = [_]u8{ 0x42, 0x45, 0x12, 0x34, 'a', 'b', 0xb1, 'x', 0xff, 'o', 'k' }; + var options: [1]coapz.Option = undefined; + const view = try read(&wire, &options); + const owned = try coapz.Packet.read(std.testing.allocator, &wire); + defer owned.deinit(std.testing.allocator); + try std.testing.expectEqual(owned.kind, view.kind); + try std.testing.expectEqual(owned.code, view.code); + try std.testing.expectEqual(owned.msg_id, view.msg_id); + try std.testing.expectEqualSlices(u8, owned.token, view.token); + try std.testing.expectEqualSlices(u8, owned.payload, view.payload); + try std.testing.expectEqual(owned.options[0].kind, view.options[0].kind); + try std.testing.expectEqualSlices(u8, owned.options[0].value, view.options[0].value); + try std.testing.expectError(error.ResponseOptionsTooSmall, read(&wire, &.{})); + try std.testing.expectError(error.EmptyPayload, read(wire[0..9], &options)); +} diff --git a/src/root.zig b/src/root.zig index 0b9a578..b463807 100644 --- a/src/root.zig +++ b/src/root.zig @@ -47,21 +47,19 @@ //! }); //! defer client.deinit(); //! -//! const result = try client.get(allocator, "/temperature"); -//! defer result.deinit(allocator); +//! var storage: coap.Client.ResponseStorage(4096) = .{}; +//! const result = try client.get(storage.buffers(), "/temperature"); //! std.debug.print("{s}\n", .{result.payload}); //! } //! ``` //! //! ## Memory model //! -//! Both server and client pre-allocate all internal buffers at init. -//! The server handler receives a per-request arena that resets after -//! each tick — no per-request heap allocations occur in the hot path. -//! -//! Client methods like `get()` and `call()` take a separate allocator -//! for the response; the caller owns the `Result` and frees it via -//! `result.deinit(allocator)`. +//! Server and client protocol buffers are preallocated at init. Server handlers +//! receive a resettable arena. CON client responses borrow caller-owned +//! ResponseBuffers, including bounded Block2 storage, with no heap fallback. +//! Results remain valid until that storage is reused; never deinit them. +//! Raw receives and Observe notifications retain explicit allocating APIs. /// CoAP server. See `Server.Config` for configuration options. pub const Server = @import("Server.zig"); diff --git a/src/uri.zig b/src/uri.zig index 23e00bc..f4b667e 100644 --- a/src/uri.zig +++ b/src/uri.zig @@ -6,7 +6,8 @@ /// ```zig /// var buf: [uri.max_options]coapz.Option = undefined; /// const opts = uri.fromUri("/sensors/temp?unit=celsius", &buf); -/// const result = try client.call(allocator, .get, opts, &.{}); +/// var storage: coap.Client.ResponseStorage(4096) = .{}; +/// const result = try client.call(storage.buffers(), .get, opts, &.{}); /// ``` const std = @import("std"); const coapz = @import("coapz");