feat(v4.0.0): storage speaks messages -- a device over v3's block chains, common and private
What is on a storage port (v4/system/storage.c): it takes Block read, Block write and Block data and answers Block data or Block done. It holds a view of a common chain, a private chain, or both; private block k is number 2^32 - 1 - k. Behind it is v3's block subsystem, reached through v4/system/store_v3.c, the one v4 file that includes v3's headers. v3's block code links here with its two device back ends, its log and its clock, and nothing else of v3. v4/tests/test_store.c: 36 checks at 64 bits, 35 at 32, and under the sanitizers. docs/v4.0.0/MESH.md 8.3, 8.4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0e761cb117
commit
4a505a154d
@@ -34,6 +34,18 @@
|
||||
#define V4_MSG_OUTPUT 2 /* what a node printed */
|
||||
#define V4_MSG_DONE 3 /* how the text ended: one word, V4_TEXT_* */
|
||||
|
||||
/* Storage (docs/v4.0.0/MESH.md 8.3). A block's number is one word of
|
||||
* payload, written as it is; a block is 1024 characters. */
|
||||
#define V4_MSG_BLOCK_READ 4 /* the block's number; answered by BLOCK_DATA, or BLOCK_DONE with an error */
|
||||
#define V4_MSG_BLOCK_WRITE 5 /* the block's number; a BLOCK_DATA follows; answered by BLOCK_DONE */
|
||||
#define V4_MSG_BLOCK_DATA 6 /* 1024 characters */
|
||||
#define V4_MSG_BLOCK_DONE 7 /* one word, V4_STORE_* */
|
||||
|
||||
#define V4_STORE_OK 0
|
||||
#define V4_STORE_NONE 1 /* there is no storage for that number */
|
||||
#define V4_STORE_REFUSED 2
|
||||
#define V4_STORE_RANGE 3 /* there is no such block */
|
||||
|
||||
/* how text ended */
|
||||
#define V4_TEXT_QUIT 0 /* QUIT: nothing is to be said */
|
||||
#define V4_TEXT_COMPLETED 1 /* a console says " ok" */
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/* storage.h -- what is on a storage port. docs/v4.0.0/MESH.md section 8.
|
||||
*
|
||||
* A device (fabric.h) that speaks the block messages of message.h and
|
||||
* answers them from one or two chains of blocks: a view. The common chain
|
||||
* is the store its nodes share; the private chain is one node's own. What
|
||||
* a chain is, is its owner's affair: the device reaches it only through
|
||||
* v4_store_ops, and the kernel's block subsystem stands behind those
|
||||
* (system/store_v3.c).
|
||||
*
|
||||
* WHICH CHAIN A NUMBER MEANS. Block numbers are 1 to V4_STORE_TOP.
|
||||
* - Private block k is number V4_STORE_TOP - k, and is the private
|
||||
* chain's block V4_STORE_FIRST + k, its first on a device. A number
|
||||
* is the private chain's when k is less than the blocks that chain has
|
||||
* on devices.
|
||||
* - Any other number is the common chain's, as it is.
|
||||
* - With no common chain, a number below V4_STORE_FIRST is the private
|
||||
* chain's, as it is: its fast RAM.
|
||||
* - A number that belongs to no chain the view has: V4_STORE_NONE.
|
||||
* - 0, a number above V4_STORE_TOP, or one past the end of its chain:
|
||||
* V4_STORE_RANGE.
|
||||
*
|
||||
* It has a number, as a node has: messages for it are addressed to that
|
||||
* number and its answers come from it. A message for any other number is
|
||||
* let go.
|
||||
*
|
||||
* A write is two messages, BLOCK_WRITE with the number and BLOCK_DATA with
|
||||
* the block; they are paired by who sent them. BLOCK_DATA from a sender
|
||||
* with no BLOCK_WRITE before it is answered V4_STORE_REFUSED.
|
||||
*
|
||||
* The device always takes what it is sent, so that a node writing to it is
|
||||
* never left waiting on a device that is waiting to be read: answers queue,
|
||||
* V4_STORE_PENDING of them. Only when that many wait is the first word of
|
||||
* another message not taken yet.
|
||||
*
|
||||
* Nothing here uses the C library.
|
||||
*/
|
||||
#ifndef V4_STORAGE_H
|
||||
#define V4_STORAGE_H
|
||||
|
||||
#include "v4/message.h"
|
||||
|
||||
#define V4_STORE_TOP 0xffffffffUL
|
||||
#define V4_STORE_FIRST 2048UL
|
||||
#define V4_STORE_PENDING 64u
|
||||
#define V4_STORE_BYTES 1024u
|
||||
|
||||
/* A chain of blocks. read and write return V4_STORE_*; `blocks` is how
|
||||
* many block numbers the chain answers to, counting from 0, its fast RAM
|
||||
* included. */
|
||||
typedef struct {
|
||||
int (*read)(void *chain, uint32_t block, unsigned char *bytes);
|
||||
int (*write)(void *chain, uint32_t block, const unsigned char *bytes);
|
||||
uint32_t (*blocks)(void *chain);
|
||||
} v4_store_ops;
|
||||
|
||||
typedef struct {
|
||||
const v4_store_ops *ops;
|
||||
void *common, *private_chain; /* 0: the view has none */
|
||||
v4_cell number;
|
||||
|
||||
v4_message in; /* the message arriving */
|
||||
struct { int used; v4_cell from; uint64_t block; } writing[V4_STORE_PENDING]; /* BLOCK_WRITEs whose data has not come */
|
||||
struct { v4_cell to; int read; uint64_t block; int status; } answer[V4_STORE_PENDING];
|
||||
unsigned head, count; /* the answers waiting: the oldest, and how many */
|
||||
v4_message out; /* the answer being given */
|
||||
unsigned out_at;
|
||||
int out_ready;
|
||||
unsigned char bytes[V4_STORE_BYTES];
|
||||
|
||||
unsigned long taken; /* whole messages taken, for whoever counts */
|
||||
} v4_store;
|
||||
|
||||
void v4_store_init(v4_store *s, const v4_store_ops *ops, void *common, void *private_chain, v4_cell number);
|
||||
|
||||
/* The two functions of a v4_device; `self` is the v4_store. */
|
||||
int v4_store_take(void *self, v4_cell value);
|
||||
int v4_store_give(void *self, v4_cell *value);
|
||||
|
||||
/* The kernel's block subsystem as chains: a chain is a blk_chain_t *
|
||||
* (v3/include/block_subsystem.h). system/store_v3.c. */
|
||||
extern const v4_store_ops v4_store_v3;
|
||||
|
||||
#endif /* V4_STORAGE_H */
|
||||
Reference in New Issue
Block a user