diff options
| author | eunhhu <[email protected]> | 2026-10-19 09:58:47 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-19 09:58:47 +0100 |
| commit | b8e6a2e5b8fc64ec47adfbe583b8a27200cc5a2e (patch) | |
| tree | d3a2a5041e42e4ca2fa4a7ec8e5cd10147c9030b /core/module.h | |
| parent | 31ef28609c6135058ffa0645fed9edd75c1086c7 (diff) | |
| download | pure-b8e6a2e5b8fc64ec47adfbe583b8a27200cc5a2e.tar.gz pure-b8e6a2e5b8fc64ec47adfbe583b8a27200cc5a2e.zip | |
The modules an app ran are freed (research 115's next step): every app's module a Loaded with holds (each snapshot of it, each request read with it); one replaced is retired and freed on the apps thread once no app runs it, every connection thread has begun a pass since (woken for it), and nothing holds it; who keeps a module to ask later whether it is the same asks its serial (core: PureModule.serial, a reader's module_serial, pure_snapshot_module, pure_snapshot_release says it freed; serve: routes, groups, links, bindings, queries, the published snapshot), as an address may come back; a link binds under its receiver's lock, a link naming an input under binding_lock; 030's memory.py: 4,000 changes 0 bytes a change (was 19,284), 4,100 freed; stress.py: readers, view workers, push streams and a body across changes, 586 of 600 loads at a freed module's address, every answer right, ASan 1,000 changes clean; a push group that looked while its app resumed missed the new snapshot (published before the app took requests) and waited for its next save: woken again once it takes them (server_view_workers had failed once under load)
Diffstat (limited to 'core/module.h')
| -rw-r--r-- | core/module.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/core/module.h b/core/module.h index 43d9ccb..aff6240 100644 --- a/core/module.h +++ b/core/module.h @@ -453,6 +453,9 @@ typedef struct { uint16_t *signature_record; bool calls; /* it has functions: its blocks run in the executor that calls (module.c) */ uint32_t nesting; /* its loops' deepest nesting (set at load) */ + /* Which load this is, of the process's: never 0, never the same twice. Who keeps a module's address to ask later + * whether it is the same module asks this instead, since another may come to that address once one is freed. */ + uint64_t serial; } PureModule; /* Whether a state of m is transient (PURE_STATE_TRANSIENT). */ @@ -533,6 +536,7 @@ typedef struct { unsigned char *bytes; size_t used, capacity; } PureArena; enum { PURE_LIST_HEARD = 0x10000, PURE_LIST_OUTBOX, PURE_LIST_RUNTIME = 2 }; typedef struct { const PureModule *module; + uint64_t module_serial; /* a reader's: its module's serial when it read (the module may since be freed) */ PureData data; /* The arrays of each state (027's 4f-2), sized to the module in one block (states) for the states it was laid out * for (laid). */ @@ -792,7 +796,10 @@ void pure_app_checkpointed(PureApp *, PureCheckpoint *, PureResult); PureSnapshot *pure_app_snapshot(PureApp *); void pure_snapshot_hold(PureSnapshot *); /* On any thread; the last reference frees it. */ -void pure_snapshot_release(PureSnapshot *); +/* Let a reference go: true when it was the last, the snapshot freed. */ +bool pure_snapshot_release(PureSnapshot *); +/* The module the snapshot's app ran when it was taken. */ +const PureModule *pure_snapshot_module(const PureSnapshot *); /* Show a snapshot's states in reader, a zeroed app or a reader before: its * views read them while the snapshot is held, with the reader's own arena and * row cache (one thread at a time). It applies no events. pure_app_stop frees |
