aboutsummaryrefslogtreecommitdiff
path: root/src/core/io_linux.c
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 17:03:03 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 17:03:03 +0330
commit7cb983bbea98d2038b2a8015a6d1f1afd40991c9 (patch)
treeec3d88a15801207fc6d8d3c6d142617ffec85460 /src/core/io_linux.c
parentmerge work/borrow: borrow returns before definition, borrows clause, borrow m... (diff)
parentbench: rss probe path fix (diff)
merge work/actors: wasm seed bootstrap (seed/MANIFEST), shared copy-on-write actor memory, top-level hold blocks on all backends and lsp
Diffstat (limited to 'src/core/io_linux.c')
-rw-r--r--src/core/io_linux.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/core/io_linux.c b/src/core/io_linux.c
index aaf6a18..c3e05dd 100644
--- a/src/core/io_linux.c
+++ b/src/core/io_linux.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
@@ -25,7 +26,11 @@ char Q(void){int c=getchar();J=pk();return c;}
one would wait for a message that comes only after the answer. so J is 1 only
when the end is known, and 0 when more may come. the output is flushed before
any read that can wait, for the same reason. */
-static VM_TLS unsigned char ib[65536];
+#define IBN 65536
+/* each vm thread's buffer is allocated when it first reads, so an actor that never
+ reads standard input carries none */
+static VM_TLS unsigned char *ibp;
+#define ib (ibp ? ibp : (ibp = malloc(IBN)) ? ibp : (fputs("zy: out of memory\n", stderr), exit(2), ibp))
static VM_TLS int ip, in, ieof;
/* make a byte available. wait is 0 to look without waiting. returns 1 when one is ready */
static int fill(int wait)
@@ -37,7 +42,7 @@ static int fill(int wait)
struct pollfd f; f.fd = 0; f.events = POLLIN; f.revents = 0;
if (poll(&f, 1, 0) <= 0) return 0; /* nothing yet: not the end, not a byte */
} else fflush(stdout);
- n = (int)read(0, ib, sizeof ib);
+ n = (int)read(0, ib, IBN);
if (n <= 0) { ieof = 1; return 0; }
ip = 0; in = n;
return 1;
@@ -62,16 +67,20 @@ int input_pending(void)
#endif
}
#ifndef _WIN32
-struct IoSnapshot { unsigned char bytes[65536]; int position, count, ended, flag; };
-size_t io_context_size(void) { return sizeof(struct IoSnapshot); }
+/* what a new worker inherits: the bytes read ahead and not consumed yet, and the flags */
+struct IoSnapshot { int position, count, ended, flag; unsigned char bytes[]; };
+size_t io_context_size(void) { return sizeof(struct IoSnapshot) + (size_t)(ip < in ? in - ip : 0); }
void io_context_snapshot(void *destination) {
struct IoSnapshot *snapshot = destination;
- memcpy(snapshot->bytes, ib, sizeof ib); snapshot->position = ip; snapshot->count = in; snapshot->ended = ieof; snapshot->flag = J;
+ if (ip < in) memcpy(snapshot->bytes, ib + ip, (size_t)(in - ip));
+ snapshot->position = ip; snapshot->count = in; snapshot->ended = ieof; snapshot->flag = J;
}
void io_context_restore(const void *source) {
const struct IoSnapshot *snapshot = source;
- memcpy(ib, snapshot->bytes, sizeof ib); ip = snapshot->position; in = snapshot->count; ieof = snapshot->ended; J = snapshot->flag;
+ ip = snapshot->position; in = snapshot->count; ieof = snapshot->ended; J = snapshot->flag;
+ if (ip < in) memcpy(ib + ip, snapshot->bytes, (size_t)(in - ip));
}
+void io_context_release(void) { free(ibp); ibp = 0; }
#endif
void G(char c){putchar(c);}