summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-06-12 17:21:40 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-07-08 10:18:08 -0600
commit19291b127d2fa0f5e134b9858e39ceadee389e77 (patch)
tree025d5f1534912606ab034c744c7fd5ac90858a9d
parent72b9036dc961d9fe7e0e9deb12e87f121a4d0ccf (diff)
lib9p_util: Add a listing of coroutineslukeshu/proc
-rw-r--r--flashimg/cpu_main/main.c3
-rw-r--r--lib9p_util/CMakeLists.txt1
-rw-r--r--lib9p_util/coroutine.c177
-rw-r--r--lib9p_util/include/util9p/coroutine.h18
-rw-r--r--lib9p_util/tests/demo_server.c2
-rw-r--r--libcr/coroutine.c9
6 files changed, 206 insertions, 4 deletions
diff --git a/flashimg/cpu_main/main.c b/flashimg/cpu_main/main.c
index 40bf81e..4732982 100644
--- a/flashimg/cpu_main/main.c
+++ b/flashimg/cpu_main/main.c
@@ -37,6 +37,7 @@
#include "usb_keyboard.h"
/* 9P files */
+#include <util9p/coroutine.h>
#include <util9p/nut.h>
#include <util9p/static.h>
#include <util9p/uptime.h>
@@ -119,12 +120,12 @@ static struct lib9p_srv_file root =
STATIC_DIR("harness",
API_FILE("flash.bin", flash,
.io = &flashio),
+ API_FILE("proc.txt", coroutine),
STATIC_FILE("rom.bin",
.data_start = (void*)0x00000000,
.data_size = 16*1024),
API_FILE("uptime.txt", uptime),
// TODO: system.log
- // TODO: proc.txt
// TODO: cpuinfo.txt
// TODO: ctl
),
diff --git a/lib9p_util/CMakeLists.txt b/lib9p_util/CMakeLists.txt
index 99dfbde..32e98de 100644
--- a/lib9p_util/CMakeLists.txt
+++ b/lib9p_util/CMakeLists.txt
@@ -6,6 +6,7 @@
add_library(lib9p_util INTERFACE)
target_include_directories(lib9p_util INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_sources(lib9p_util INTERFACE
+ coroutine.c
nut.c
static.c
uptime.c
diff --git a/lib9p_util/coroutine.c b/lib9p_util/coroutine.c
new file mode 100644
index 0000000..b9320a9
--- /dev/null
+++ b/lib9p_util/coroutine.c
@@ -0,0 +1,177 @@
+/* lib9p_util/coroutine.c - 9P access to libcr process information
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h>
+#include <libmisc/fmt.h>
+#include <libmisc/heap.h>
+#include <util9p/static.h>
+
+#include <util9p/static.h>
+#include <util9p/coroutine.h>
+
+/******************************************************************************/
+
+LO_IMPLEMENTATION_C(lib9p_srv_file, struct coroutine_file, coroutine_file);
+
+static_assert(CONFIG_COROUTINE_NUM < 1000);
+
+#define MAX(a, b) ( ((a)>(b)) ? (a) : (b) )
+
+static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8);
+#define SIZE_MAX_BASE10_LEN (sizeof(size_t) == 4 ? 10 : 20)
+
+struct coroutine_fio {
+ struct coroutine_file *parent;
+ size_t buf_len;
+ char buf[
+ (3 +2 /* cid */
+ +MAX(CONFIG_COROUTINE_NAME_LEN, 4) +2 /* name */
+ +14 +2 /* state; len("CR_INITIALIZING")=14 */
+ +MAX(SIZE_MAX_BASE10_LEN, 9) +2 /* stack_cap */
+ +MAX(SIZE_MAX_BASE10_LEN, 9) +2 /* stack_max */
+ +MAX(SIZE_MAX_BASE10_LEN, 9) +1 /* stack_cur */
+ )*(CONFIG_COROUTINE_NUM+1)];
+
+};
+LO_IMPLEMENTATION_STATIC(lib9p_srv_fio, struct coroutine_fio, coroutine_fio);
+
+/* srv_file *******************************************************************/
+
+void coroutine_file_free(struct coroutine_file *self) {
+ assert(self);
+}
+struct lib9p_qid coroutine_file_qid(struct coroutine_file *self) {
+ assert(self);
+
+ return (struct lib9p_qid){
+ .type = LIB9P_QT_FILE,
+ .vers = 1,
+ .path = self->pathnum,
+ };
+}
+
+error coroutine_file_stat(struct coroutine_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat *out) {
+ assert(self);
+ assert(ctx);
+ assert(out);
+
+ *out = ((struct lib9p_srv_stat){
+ .qid = coroutine_file_qid(self),
+ .mode = 0444,
+ .atime_sec = UTIL9P_ATIME,
+ .mtime_sec = UTIL9P_MTIME,
+ .size = 0,
+ .name = lib9p_str(self->name),
+ .owner_uid = { .name = lib9p_str("root"), .num = 0 },
+ .owner_gid = { .name = lib9p_str("root"), .num = 0 },
+ .last_modifier_uid = { .name = lib9p_str("root"), .num = 0 },
+ .extension = lib9p_str(NULL),
+ });
+ return ERROR_NULL;
+}
+error coroutine_file_wstat(struct coroutine_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat) {
+ assert(self);
+ assert(ctx);
+
+ return error_new(E_POSIX_EROFS, "read-only part of filesystem");
+}
+error coroutine_file_remove(struct coroutine_file *self, struct lib9p_srv_ctx *ctx) {
+ assert(self);
+ assert(ctx);
+
+ return error_new(E_POSIX_EROFS, "read-only part of filesystem");
+}
+
+LIB9P_SRV_NOTDIR(, struct coroutine_file, coroutine_file);
+
+lib9p_srv_fio_or_error coroutine_file_fopen(struct coroutine_file *self, struct lib9p_srv_ctx *ctx,
+ bool LM_UNUSED(rd), bool LM_UNUSED(wr), bool LM_UNUSED(trunc)) {
+ assert(self);
+ assert(ctx);
+
+ struct coroutine_fio *ret = heap_alloc(1, struct coroutine_fio);
+ ret->parent = self;
+
+ return ERROR_NEW_VAL(lib9p_srv_fio, LO_BOX(lib9p_srv_fio, ret));
+}
+
+/* srv_fio ********************************************************************/
+
+static uint32_t coroutine_fio_iounit(struct coroutine_fio *self) {
+ assert(self);
+ return sizeof(self->buf);
+}
+
+static void coroutine_fio_iofree(struct coroutine_fio *self) {
+ assert(self);
+ heap_free(self);
+}
+
+static struct lib9p_qid coroutine_fio_ioqid(struct coroutine_fio *self) {
+ assert(self);
+ assert(self->parent);
+ return coroutine_file_qid(self->parent);
+}
+
+static error coroutine_fio_pread(struct coroutine_fio *self, struct lib9p_srv_ctx *ctx,
+ lo_interface io_writer dst, uint64_t byte_offset, uint32_t byte_count) {
+ assert(self);
+ assert(ctx);
+
+ if (byte_offset == 0 || self->buf_len == 0) {
+ struct fmt_buf _w = { .dat = self->buf, .cap = sizeof(self->buf) };
+ lo_interface fmt_dest w = lo_box_fmt_buf_as_fmt_dest(&_w);
+
+ size_t w_cid = 3;
+ size_t w_name = MAX(CONFIG_COROUTINE_NAME_LEN, strlen("name"));
+ size_t w_state = strlen("CR_INITIALZING");
+ size_t w_stack_cap = MAX(SIZE_MAX_BASE10_LEN, strlen("stack_cap"));
+ size_t w_stack_max = MAX(SIZE_MAX_BASE10_LEN, strlen("stack_max"));
+ size_t w_stack_cur = MAX(SIZE_MAX_BASE10_LEN, strlen("stack_cur"));
+
+ fmt_print(w,
+ (ljust, w_cid, ' ', "cid"), " ",
+ (ljust, w_name, ' ', "name"), " ",
+ (ljust, w_state, ' ', "state"), " ",
+ (rjust, w_stack_cap, ' ', "stack_cap"), " ",
+ (rjust, w_stack_max, ' ', "stack_max"), " ",
+ (rjust, w_stack_cur, ' ', "stack_cur"), "\n");
+ for (cid_t cid = 1; cid <= CONFIG_COROUTINE_NUM; cid++) {
+ struct cr_cid_info info;
+ cr_cid_info(cid, &info);
+ if (info.state == CR_NONE)
+ continue;
+ fmt_print(w,
+ (ljust, w_cid, ' ', cid), " ",
+ (ljust, w_name, ' ', (strn, info.name, sizeof(info.name))), " ",
+ (ljust, w_state, ' ', coroutine_state_str(info.state)), " ",
+ (rjust, w_stack_cap, ' ', info.stack_cap), " ",
+ (rjust, w_stack_max, ' ', info.stack_max), " ",
+ (rjust, w_stack_cur, ' ', info.stack_cur), "\n");
+ }
+ assert(_w.len <= _w.cap);
+ self->buf_len = _w.len;
+ }
+
+ if (byte_offset > (uint64_t)self->buf_len)
+ return error_new(E_POSIX_EINVAL, "offset is past end-of-file length");
+
+ size_t beg_off = (size_t)byte_offset;
+ size_t end_off = beg_off + (size_t)byte_count;
+ if (end_off > self->buf_len)
+ end_off = self->buf_len;
+ return io_write(dst, &((char *)(self->buf))[beg_off], end_off-beg_off).err;
+}
+
+static uint32_t_or_error coroutine_fio_pwrite(struct coroutine_fio *self, struct lib9p_srv_ctx *ctx,
+ const void *LM_UNUSED(buf),
+ uint32_t LM_UNUSED(byte_count),
+ uint64_t LM_UNUSED(byte_offset)) {
+ assert(self);
+ assert(ctx);
+
+ return ERROR_NEW_ERR(uint32_t, error_new(E_POSIX_EROFS, "read-only part of filesystem"));
+}
diff --git a/lib9p_util/include/util9p/coroutine.h b/lib9p_util/include/util9p/coroutine.h
new file mode 100644
index 0000000..00533a9
--- /dev/null
+++ b/lib9p_util/include/util9p/coroutine.h
@@ -0,0 +1,18 @@
+/* util9p/coroutine.h - 9P access to libcr process information
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _UTIL9P_COROUTINE_H_
+#define _UTIL9P_COROUTINE_H_
+
+#include <lib9p/srv.h>
+
+struct coroutine_file {
+ char *name;
+ uint64_t pathnum;
+};
+LO_IMPLEMENTATION_H(lib9p_srv_file, struct coroutine_file, coroutine_file);
+
+#endif /* _UTIL9P_COROUTINE_H_ */
diff --git a/lib9p_util/tests/demo_server.c b/lib9p_util/tests/demo_server.c
index cb6d5ee..28530f9 100644
--- a/lib9p_util/tests/demo_server.c
+++ b/lib9p_util/tests/demo_server.c
@@ -20,6 +20,7 @@
#include <libhw/host_net.h>
#include <libmisc/macro.h>
+#include <util9p/coroutine.h>
#include <util9p/static.h>
#include <util9p/uptime.h>
#include <util9p/whoami.h>
@@ -77,6 +78,7 @@ static struct lib9p_srv_file root =
API_FILE(4, "uptime.txt", uptime),
API_FILE(5, "video.nut", nut,
.framebuffer = globals.framebuffer),
+ API_FILE(6, "proc.txt", coroutine),
);
static lib9p_srv_file_or_error get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) {
diff --git a/libcr/coroutine.c b/libcr/coroutine.c
index d776e90..a81ffbd 100644
--- a/libcr/coroutine.c
+++ b/libcr/coroutine.c
@@ -865,12 +865,15 @@ void cr_cid_info(cid_t cid, struct cr_cid_info *ret) {
#if CONFIG_COROUTINE_VALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
#endif
- uint8_t v = stack[i];
+ if (stack[i] != stack_pattern[i%sizeof(stack_pattern)]) {
#if CONFIG_COROUTINE_VALGRIND
- VALGRIND_ENABLE_ERROR_REPORTING;
+ VALGRIND_ENABLE_ERROR_REPORTING;
#endif
- if (v != stack_pattern[i%sizeof(stack_pattern)])
break;
+ }
+#if CONFIG_COROUTINE_VALGRIND
+ VALGRIND_ENABLE_ERROR_REPORTING;
+#endif
ret->stack_max--;
}