<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/Makefile, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-10-18T18:30:16Z</updated>
<entry>
<title>Module format v7, 027's 4b-2: keyed documents gone, a keyed list of records holding bytes doing their work: no collections table, DOC, DOC_SIZE or REPLACE (106 opcodes now 103, those from LEN on moved up), keyed messages or a base revision (pure_app_message takes an input and a payload), no PureData document callbacks (a data host opens states and saves them together), no burst by document key; the header 38 bytes; pure-edit-module gone; pure-serve without /objects, ETag, If-Match and If-None-Match, 412 or an app a thread for a module of documents alone (one without states or outputs runs so); a hole closed: an instruction in no handler's, view's or function's block was never verified yet the load's later passes read its arguments (a damaged module read out of bounds once the header moved what the mutation test damaged), now blanked to CONST 0; checks moved: server_documents (DOCS_SOURCE, keyed byte documents with the app's revision, against a Python model, one and three connection threads, a restart) in place of the parity with editor.pure, pipelining and bursts through kill -9 on its inputs and views, the lent budget on a text view (lending a document's read is server_lent_views' already), clocks and tokens on it; message tests without a document host; the HTTP benchmark's document suite runs the earlier document server and the baselines alone; the count harness builds against either message API (runs.sh build: -DPURE_KEYED_MESSAGES before 4b); counts: b33 against b32 with batches within 0.002% but BFS -0.33%, without batches BFS +0.63%, knapsack +0.52%, join +0.38%; the bank's queries (s32 on a v6 module, s33 on v7) field +0.68%, found +0.44%, large +0.42%, the rest within 0.13%; 008 as v7, 027's 4b-2 as made and 4c designed</title>
<updated>2026-10-18T18:30:16Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-18T18:30:16Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b22b8c3f6c5378b47c36370225d7c41d4394bb7c'/>
<id>urn:sha1:b22b8c3f6c5378b47c36370225d7c41d4394bb7c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Makefile: loops aligned in the batch executor alone (BATCH_OPTIMIZE): the lists' loops so aligned cost the bank's queries 0.8-2.0% more instructions (the padding) with their cycles mixed</title>
<updated>2026-10-09T14:14:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-09T14:14:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=1b7e9055f019ecf957e4cfbd659268149593c7cc'/>
<id>urn:sha1:1b7e9055f019ecf957e4cfbd659268149593c7cc</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Makefile: the lists' and the batch executor's loops each start at a 64-byte line (-falign-loops=64 in LIST_OPTIMIZE): a change anywhere in module-batch.c moved knapsack's hot loops and it ran 8.26, 8.74 and 8.20 ms with the same instructions; aligned, every batched work's cycles fell (knapsack 6%, matmul 1.8%, BFS 1.1%) and the executor alone stayed within its noise, at 0.7-2.3% more instructions (the padding)</title>
<updated>2026-10-09T13:38:20Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-09T13:38:20Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=3e3812c74a4e60eece884553db03a90de13b5b0c'/>
<id>urn:sha1:3e3812c74a4e60eece884553db03a90de13b5b0c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Batch executor stage 1 (024): a count's loop whose block has batch forms (lane forms, locals set before read in every round, ifs, numbers set in items) runs, in the executor, up to 1024 rounds at a time: values uniform, affine or lanes (numbers, or whole numbers in four bytes), branches as masks, cells read by affine rows as strided columns, sets kept to the batch's end and made only when no round reads an earlier round's; a fault, a form it lacks or such a read gives the rounds back to the executor one by one, work counted as written. Planned at load (PURE_BATCH=0: none); the executor of a module without such loops is the same code (run aligned to 64: as many instructions and cycles), with one its own copy. knapsack with PURE_JIT=0: 1,056 to 13.7 ms. module_tier compares batches with the executor alone and makes loops of rounds apart; BATCH_SOURCE: widened columns, -0, a fault mid-batch, rounds reading the last's sets</title>
<updated>2026-10-05T21:53:09Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-05T21:53:09Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=10a50dd20abe8542d6ed6487d2c46d964af59c75'/>
<id>urn:sha1:10a50dd20abe8542d6ed6487d2c46d964af59c75</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Run a block through a frame and step, and compile blocks to AArch64 that call the same steps (021)</title>
<updated>2026-10-05T06:38:00Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-05T06:32:17Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=75b9c1c1e936e2b7c55275139897e1c78d7939c1'/>
<id>urn:sha1:75b9c1c1e936e2b7c55275139897e1c78d7939c1</id>
<content type='text'>
- run() keeps a block's operand stack and open loops in a Frame; step()
  runs one instruction (branches and loops too, one dispatch), and
  enter_each, enter_loop, leave_loop and iterate are their own functions.
  The executor is the same machine code, 7% fewer instructions.
- The verifier records each instruction's stack height (from its block's
  start), so compiled code knows each slot's place.
- module-jit.c (AArch64 Linux; elsewhere, or PURE_JIT=0, none): a
  module's handlers', views' and folds' blocks compiled when it loads.
  Branches and loops are branches; every other instruction calls the
  executor's own step, so both run the same meaning. A loop that is not
  opened lands where its iteration would have ended; an empty loop
  iterates in place.
- test-module recompiles a module whose code a test changes after load.
- A search (100,000 nodes, 1,000,000 edges, core only) is 150 ms
  compiled, against 122 ms executed: a call of step for every instruction
  costs more than the executor's switch; the hot instructions are written
  as code next.
</content>
</entry>
<entry>
<title>Search an event's keyed lists by a key set and lists by fingers, add by key in one descent, and loop without recursion (020)</title>
<updated>2026-10-04T16:39:18Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-04T16:39:18Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=602780a58c3286d6843e8ff89bd7a3093891a7ad'/>
<id>urn:sha1:602780a58c3286d6843e8ff89bd7a3093891a7ad</id>
<content type='text'>
- An event's list keyed by a number keeps its keys beside its tree: bits
  while they are small whole numbers, else an open-addressing table;
  has() reads only that, and inserts, removes, key changes, their undoing
  and clears keep it.
- Each thread keeps fingers on the last four leaves it read (list id and
  version must match): reads by position and searches by key that land in
  them do not descend.
- pure_list_add finds a key's place and inserts there in one descent; a
  stored keyed list's appends take it too, journaled as inserts.
- Child searches count over the whole guide; item fields know at load
  whether they are text; loops run on a stack of loop records, not by
  recursion; module-list.c builds at -O3.
- test-module: the key set and fingers answer as a model at every step
  (bits to table, removes inside runs, undone changes, clears, shares),
  and a stored keyed list's adds replay from its journal.
</content>
</entry>
<entry>
<title>Take an app's requests only with a token its tokens file grants (017, 3b)</title>
<updated>2026-10-04T11:46:34Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-04T11:46:34Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6'/>
<id>urn:sha1:9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6</id>
<content type='text'>
An app given a tokens file (tokens=FILE in --apps, --tokens FILE for the
one app of a host) answers a request only when it bears a token
(Authorization: Bearer) whose SHA-256 the file lists with a grant: read
for its views, queries and documents, write for all, input=NAME for
those inputs alone; 401 unauthorized (WWW-Authenticate: Bearer) without
one, 403 forbidden past its grant. A delivery sealed by a key --sender
names needs none. The digests are compared in constant time; a
connection keeps its last token's digest, so the same token is hashed
once. SHA-256 is the host's own (serve/sha256.c), no OpenSSL loaded. A
reading puts a changed tokens file in place with the app running on; a
file that is not one stops the app. pure-serve --make-token GRANT makes
a token and its line. load takes PURE_LOAD_TOKEN.
</content>
</entry>
<entry>
<title>Take the sending loop out of the links, for the wires to join it (017, 2b)</title>
<updated>2026-10-01T08:00:45Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-01T08:00:45Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=50f8ea3c249009fcbe649561e7aba32580bab454'/>
<id>urn:sha1:50f8ea3c249009fcbe649561e7aba32580bab454</id>
<content type='text'>
link/sending.c is the process's sending loop: a sender joins it with its
round and the socket it waits on, and is rounded when its socket is
ready, when pushed, and when its time comes. Links are its first
senders; nothing they do changed. Events of a sender that left while the
loop waited are let go (the epoll is level-triggered: the others' come
again).
</content>
</entry>
<entry>
<title>Balance the snapshot register's count, and free the runtime lists in order</title>
<updated>2026-09-30T04:37:11Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-30T04:37:11Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b0bec448d30f198dc4817d71fc8c72654907a3a9'/>
<id>urn:sha1:b0bec448d30f198dc4817d71fc8c72654907a3a9</id>
<content type='text'>
Under AddressSanitizer with leaks counted, the module checks lost 672
KB in 10,185 allocations. Two causes, both from the snapshot rework
(d1e8f38):

- A snapshot's register counted its snapshots with ++ under its spin,
  but a snapshot's last release took one off atomically outside it. A
  release on a reader's thread racing the owner's next snapshot could
  lose either change: the register then outlived every snapshot (the
  leak seen), or went while one still used it. The count is atomic now.
- pure_app_stop handed what its lists let go to the newest snapshot (or
  freed it) and only then freed the outbox and the numbers heard, whose
  shared nodes and texts went to that hand-over's list again, for good.
  They are freed with the other lists now.

make check builds the module checks a second time under AddressSanitizer
and UndefinedBehaviorSanitizer (build/test-module-sanitized, 25 s) and
fails on a leak. Before d1e8f38 the same build stops at a
heap-use-after-free in retire; now it is clean.
</content>
</entry>
<entry>
<title>Tick a stateless app's timers, and wait for them on the monotonic clock</title>
<updated>2026-09-29T17:04:43Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T17:04:24Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=8fe9ce66573be53ff56fe2a8afc693dabeae9585'/>
<id>urn:sha1:8fe9ce66573be53ff56fe2a8afc693dabeae9585</id>
<content type='text'>
run_timers ticked nothing in an app without states, taking a timer to
be able to change nothing else; but a tick may send, and the outbox is
the app's state (the host gives such an app an owner for it). A timer
that only sends never ticked (review 004, F4). Now an app ticks when it
has states or outputs; one with neither runs on every connection thread
and has nothing a tick could do.

When a timer is due was reckoned on the wall clock: set back, a timer
waited for the time it had reached again (review 004, an earlier P2).
The next tick is now reckoned on the monotonic clock; events still see
the wall clock (now).

check.py's server_timers runs the review's heartbeat (a timer, an
output, no state) and sees it tick, then again with the wall clock set
back an hour 0.2 s in (build/clock-back.so, an LD_PRELOAD of
clock_gettime): 29 ticks in 0.6 s, where the server before this stops at
9.
</content>
</entry>
</feed>
