|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
Plaintext pool accessor - implementation. More...
#include "scratch.h"#include "board_drivers/board_profiles/pc_platform.h"#include "network_drivers/session/worker.h"#include "server/mmgr/arena.h"#include <assert.h>#include <stdint.h>Go to the source code of this file.
Functions | |
| void * | scratch_alloc (size_t n, size_t align) |
Borrow n bytes of scratch, aligned to align. | |
| pc_span | pc_scratch_span (size_t n, size_t align) |
Borrow n bytes as a span whose capacity is bound to the allocation. | |
| void | scratch_reset (void) |
| Reclaim the whole arena (empties it). | |
| size_t | scratch_mark (void) |
| Capture the current arena offset (a savepoint for scratch_release()). | |
| void | scratch_release (size_t mark) |
Reclaim everything allocated since mark (LIFO). | |
| size_t | scratch_used (void) |
| Bytes currently handed out (0 immediately after a reset). | |
| size_t | scratch_high_water (void) |
| Largest scratch_used() value seen since boot (for sizing the arena). | |
| size_t | scratch_capacity (void) |
| Total arena capacity in bytes (PC_SCRATCH_ARENA_SIZE). | |
| bool | pc_scratch_owns (const void *p) |
True if p points inside the plaintext pool. | |
| int | pc_scratch_slot_of (const void *p) |
Which plaintext slot owns p, or -1 if p is not in the plaintext pool. | |
Plaintext pool accessor - implementation.
This file is an access layer, not a second allocator. The pool mechanism is pc_arena (mmgr/arena) and there is exactly one of it; this module owns one instance per worker slot over compile-time-sized storage and decides who may reach it. The secret pool is the same mechanism instantiated again behind its own accessor - identical resource, identical mechanics, different access and control.
Each instance has exactly one accessor (its worker), so the lock-free guarantees in scratch.h hold per slot. With PC_WORKER_COUNT == 1 this is byte-for-byte the original single arena.
Definition in file scratch.cpp.
| void * scratch_alloc | ( | size_t | n, |
| size_t | align | ||
| ) |
Borrow n bytes of scratch, aligned to align.
The returned pointer is valid only until the next scratch_reset() (i.e. only within the current session dispatch). Returns nullptr if the request does not fit the remaining arena - callers MUST handle null and fail closed.
| n | bytes requested (0 yields a valid non-null pointer when space remains). |
| align | required alignment in bytes, a power of two (0 selects the platform default). |
n writable bytes, or nullptr if it does not fit. Definition at line 135 of file scratch.cpp.
References pc_arena_scratch_alloc_aligned().
Referenced by pc_scratch_span(), pc_ssh_conn_close_channel(), pc_ssh_conn_open_forwarded(), pc_ssh_conn_send(), ssh_pkt_send(), and ws_send_frame().
| pc_span pc_scratch_span | ( | size_t | n, |
| size_t | align | ||
| ) |
Borrow n bytes as a span whose capacity is bound to the allocation.
The preferred form. scratch_alloc() hands back a bare pointer, which leaves the caller to carry the length separately and keep the two in agreement by hand at every call - the same severed binding that makes sizeof() on a converted array read 4 bytes instead of the extent. Here one argument sets both fields, so the run length is stated once and cannot drift.
Fails closed: an over-budget request yields {nullptr, 0}, so a caller that omits the pc_span_ok() check writes nothing rather than dereferencing null. Callers should still check and take their defined fail-closed path.
| n | bytes requested. |
| align | required alignment in bytes, a power of two (0 selects the platform default). |
n writable bytes, or an empty span if it does not fit. Definition at line 146 of file scratch.cpp.
References pc_span_from(), and scratch_alloc().
| void scratch_reset | ( | void | ) |
Reclaim the whole arena (empties it).
Called by server_tick() before each event dispatch. Invalidates every pointer previously returned by scratch_alloc().
Definition at line 154 of file scratch.cpp.
References pc_arena_scratch_reset().
| size_t scratch_mark | ( | void | ) |
Capture the current arena offset (a savepoint for scratch_release()).
Definition at line 165 of file scratch.cpp.
References pc_arena_scratch_mark().
| void scratch_release | ( | size_t | mark | ) |
Reclaim everything allocated since mark (LIFO).
Restores the arena to a previous scratch_mark(), freeing every scratch_alloc() made in between. Marks must be released in reverse order (nested scopes). Use ScratchScope for return-safe scoping.
| mark | a value previously returned by scratch_mark() (must be <= the current offset). |
Definition at line 172 of file scratch.cpp.
References pc_arena_scratch_release().
Referenced by ScratchScope::~ScratchScope().
| size_t scratch_used | ( | void | ) |
Bytes currently handed out (0 immediately after a reset).
Definition at line 179 of file scratch.cpp.
References pc_arena_scratch_used().
| size_t scratch_high_water | ( | void | ) |
Largest scratch_used() value seen since boot (for sizing the arena).
Definition at line 185 of file scratch.cpp.
References PC_SCRATCH_SLOTS, and pc_arena::scratch_hw.
| size_t scratch_capacity | ( | void | ) |
Total arena capacity in bytes (PC_SCRATCH_ARENA_SIZE).
Definition at line 201 of file scratch.cpp.
References PC_SCRATCH_ARENA_SIZE.
| bool pc_scratch_owns | ( | const void * | p | ) |
True if p points inside the plaintext pool.
Ownership is an address-range property, not bookkeeping. The slot count and slot size are both compile-time, so the whole pool is ONE region of known extent and the test is a single unsigned subtract and compare - no loop, no per-slot comparison, no per-allocation metadata. A pointer below the base wraps to a huge offset and fails the same bound as one past the end, so a buffer overrun cannot test as still-inside.
This is the plaintext half of the control strategy. The secure pool is a disjoint region and answers its own question, so a secure-pool pointer can never be accepted where a plaintext one is required, or the reverse.
Definition at line 206 of file scratch.cpp.
| int pc_scratch_slot_of | ( | const void * | p | ) |
Which plaintext slot owns p, or -1 if p is not in the plaintext pool.
A divide by a compile-time constant, so a multiply-and-shift rather than real division. Use to assert that a borrow being handed back belongs to the calling worker: crossing slots is the one way the lock-free single-accessor invariant can be violated, and this makes it checkable.
Definition at line 211 of file scratch.cpp.
References PC_SCRATCH_ARENA_SIZE.