-
Notifications
You must be signed in to change notification settings - Fork 0
/
Notes.txt
191 lines (155 loc) · 4.57 KB
/
Notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
* ContinuOS.org oder continuix.org
* global namespace: /proc etc,
* local part: /..../ (explicitly), contains local-only + local parts of global
for procs: get info from state, calc prefix, re-search with prefix
* process state represented
* process snapshots
* remote calls handled transparently
== Judy ==
http://judy.sourceforge.net/doc/JudySL_3x.htm
== Index format ==
=== use cases ===
* get url: direct io, filtering on headers
* filter on url list: intersect list of urls with header
on-disk array of entry pointers
updated on change, pointed to by Judy array w. urls
entrylen | next
statdata
len | uri
len | Key: val
len | Kval # encoded key, non-ascii
len | ff | pointer
0000
entryptr
nextptr
key | off
key | off
... (encoded)
XXXX0000
=== per key: list of locations ===
bytelen
added
keylen | canonkey
delta-coded varint | varint ... with full addrs in fixed offsets
added negative to remove
appended, sorted on thresh: tmp Judy1 array
=== Request ===
2next | key: val | 00
2next | key: val | 00
2next | FF | pointer
== spreading work ==
primary: pipe w. fixed records:
offset to shm, op
== Support for compiler without computed goto ==
maintain a switch stack, define switch to use it
needs two stacks (or needs to keep track of nesting)
== Channels and communication ==
* spawn returns process pointer (continuation), is available locally at
/..../proc/<hexpointer>
* can be mounted to some name: mount(pointer, "/proc/name");
this sets flag (mounted) and inserts pointer in local namespace (forward and
backward)
* on process quit, remove self from local namespace if mounted flag set
* typed send: globally defined, common message part, defined initializers for
type checking
* central type registry. Compound types/ASN.1? RDF?
* on receive: if exp matches, return m, else enqueue
children - cancel with quit, just pointers to contis
subscriptions - cancel with unsubscribe, pointers to contis
outbox - outstanding sends, cancel request if not yet replied, pointers to
messages
watchers
timer: one per thread, set to call back whoever set it last
timeout_reset()
timeout_cancel()
fd: block(fd, what, timeout)
additional: spawn as child thread (or as root)
tid = spawn(fun, arg1, arg2)
tid = spawn_root(fun, arg1, arg2)
int send(tid, message *m) // returns 0/1, appends m to outbox
int send_path("/proc/xy", message *m) // resolves path, sends to tid, returns 0/1
struct message * call(tid, message *m) // returns 'reply': matches on ref
struct message * call_path("/proc/xy", message *m) // resolve, call
struct message * receive(); // any: macro voodoo -> 1
struct message * receive(spec); // only matching spec
struct message {
unsigned int op; // switched on at receiver
struct conti *link; // callback or caller, depending on op
struct message *ref; // pointer to initial message in replies, to
// separate replies from same process
unsigned int argtype x; // for run-time checking, serialization
void *arg; // size + buffer, len + array etc
}
struct message *m = new_message(op, buf);
send(tid, m);
while(m = receive()) {
switch(m->op) {
case stdin:
// process buffer
break;
case stdout:
// set callback to stdout
break;
case return:
// subthread returned something to parent
break;
case quit:
goto out;
default:
// describe self?
}
}
=== http pipeline ===
int senders = 0;
int receivers = 1;
struct conti *receiver;
struct conti *sender = NULL;
struct message *m, *receiver_m;
receiver = spawn(handle_request, fd, etc);
while(m = receive()) {
switch(m->op) {
case timeout:
goto out;
case reply:
if (m->link == receiver) {
if(senders == 0) {
// allow handler to continue
sender = receiver;
send(sender, continue_message());
// send off another handler
receiver = spawn(handle_request, fd, etc);
senders = 1;
} else {
// have to wait for sender
unreceive(m);
}
} else if(m->link == sender) {
if (sender = receive(m->op == reply
&& m->link == receiver)
{
// was waiting, allow it to write
send(sender, continue_message());
// send off another handler
receiver = spawn(handle_request, fd, etc);
senders = 1;
} else {
senders = 0;
// as the sender quits, there is no need to
// enqueue it
}
}
break;
/* part of default */
case quit:
goto out;
DEFAULT_CASE;
}
out:
/* deal with local state, free malloced buffers, close fds */
/* send quit to all children
** send error to all queued messages that are not replies, dealloc
** messages
** call back parent with quit message */
CO_RETURN();
/* dealloc self (obstack) */
}