From 40b21d9c752303c4fdd4c37b10e15b2d55a6080e Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 7 Jun 2023 09:37:16 -0700 Subject: [PATCH] [Mammoth] Add Channel object for simple IPC messages --- lib/mammoth/CMakeLists.txt | 6 ++- lib/mammoth/include/mammoth/channel.h | 22 ++++++++++ lib/mammoth/include/mammoth/debug.h | 3 ++ lib/mammoth/src/channel.cpp | 61 +++++++++++++++++++++++++++ lib/mammoth/src/debug.cpp | 5 +++ lib/mammoth/src/process.cpp | 21 +++++---- sys/test2.cpp | 24 +++-------- zion/include/zerrors.h | 4 +- 8 files changed, 116 insertions(+), 30 deletions(-) create mode 100644 lib/mammoth/include/mammoth/channel.h create mode 100644 lib/mammoth/src/channel.cpp diff --git a/lib/mammoth/CMakeLists.txt b/lib/mammoth/CMakeLists.txt index 2daf8c8..52ddf9b 100644 --- a/lib/mammoth/CMakeLists.txt +++ b/lib/mammoth/CMakeLists.txt @@ -1,4 +1,5 @@ add_library(mammoth_lib STATIC + src/channel.cpp src/debug.cpp src/process.cpp src/thread.cpp @@ -12,6 +13,9 @@ target_link_libraries(mammoth_lib zion_lib) set(_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -nostdlib -mabi=sysv -mgeneral-regs-only") +set(_LINK_FLAGS "-nostdlib") set_target_properties(mammoth_lib PROPERTIES - COMPILE_FLAGS "${_COMPILE_FLAGS}") + COMPILE_FLAGS "${_COMPILE_FLAGS}" + LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${_LINK_FLAGS}" + ) diff --git a/lib/mammoth/include/mammoth/channel.h b/lib/mammoth/include/mammoth/channel.h new file mode 100644 index 0000000..4b96407 --- /dev/null +++ b/lib/mammoth/include/mammoth/channel.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +class Channel { + public: + Channel() {} + void adopt_cap(uint64_t id); + uint64_t release_cap(); + + z_err_t WriteStr(const char* msg); + z_err_t ReadStr(char* buffer, uint64_t* size); + + // FIXME: Close channel here. + ~Channel() {} + + private: + uint64_t chan_cap_ = 0; +}; + +uint64_t CreateChannels(Channel& c1, Channel& c2); diff --git a/lib/mammoth/include/mammoth/debug.h b/lib/mammoth/include/mammoth/debug.h index 297aba2..118d0fa 100644 --- a/lib/mammoth/include/mammoth/debug.h +++ b/lib/mammoth/include/mammoth/debug.h @@ -1,9 +1,12 @@ #pragma once #include +#include void dbgln(const char*); // Checks that the code is ok. // if not exits the process. void check(uint64_t); + +void crash(const char*, z_err_t); diff --git a/lib/mammoth/src/channel.cpp b/lib/mammoth/src/channel.cpp new file mode 100644 index 0000000..191c1ff --- /dev/null +++ b/lib/mammoth/src/channel.cpp @@ -0,0 +1,61 @@ +#include "mammoth/channel.h" + +#include + +#include "mammoth/debug.h" + +namespace { + +uint64_t strlen(const char* ptr) { + uint64_t len = 0; + while (*ptr != '\0') { + len++; + ptr++; + } + return len; +} + +} // namespace + +void Channel::adopt_cap(uint64_t id) { + if (chan_cap_ != 0) { + crash("Adopting over channel.", Z_ERR_EXISTS); + } + chan_cap_ = id; +} +uint64_t Channel::release_cap() { + uint64_t cap = chan_cap_; + chan_cap_ = 0; + return cap; +} + +z_err_t Channel::WriteStr(const char* msg) { + if (!chan_cap_) { + return Z_ERR_NULL; + } + uint64_t type = 11; + return ZChannelSend(chan_cap_, type, strlen(msg), + reinterpret_cast(msg), 0, 0); +} + +z_err_t Channel::ReadStr(char* buffer, uint64_t* size) { + if (!chan_cap_) { + return Z_ERR_NULL; + } + uint64_t type; + uint64_t num_caps; + return ZChannelRecv(chan_cap_, *size, reinterpret_cast(buffer), 0, + 0, &type, size, &num_caps); +} + +z_err_t CreateChannels(Channel& c1, Channel& c2) { + uint64_t chan1, chan2; + z_err_t err = ZChannelCreate(&chan1, &chan2); + if (err != Z_OK) { + return err; + } + + c1.adopt_cap(chan1); + c2.adopt_cap(chan2); + return Z_OK; +} diff --git a/lib/mammoth/src/debug.cpp b/lib/mammoth/src/debug.cpp index e28f29d..665e08c 100644 --- a/lib/mammoth/src/debug.cpp +++ b/lib/mammoth/src/debug.cpp @@ -29,3 +29,8 @@ void check(uint64_t code) { } ZProcessExit(code); } + +void crash(const char* str, uint64_t code) { + dbgln(str); + ZProcessExit(code); +} diff --git a/lib/mammoth/src/process.cpp b/lib/mammoth/src/process.cpp index ced946f..533d82d 100644 --- a/lib/mammoth/src/process.cpp +++ b/lib/mammoth/src/process.cpp @@ -1,9 +1,10 @@ -#include "include/mammoth/process.h" +#include "mammoth/process.h" #include #include -#include "include/mammoth/debug.h" +#include "mammoth/channel.h" +#include "mammoth/debug.h" namespace { @@ -83,16 +84,15 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) { } // namespace uint64_t SpawnProcessFromElfRegion(uint64_t program) { - dbgln("Channel Create"); - uint64_t local_chan; - uint64_t foreign_chan; - check(ZChannelCreate(&local_chan, &foreign_chan)); + Channel local, foreign; + check(CreateChannels(local, foreign)); dbgln("Spawn"); uint64_t proc_cap; uint64_t as_cap; - check(ZProcessSpawn(Z_INIT_PROC_SELF, foreign_chan, &proc_cap, &as_cap, - &foreign_chan)); + uint64_t foreign_chan_id; + check(ZProcessSpawn(Z_INIT_PROC_SELF, foreign.release_cap(), &proc_cap, + &as_cap, &foreign_chan_id)); uint64_t entry_point = LoadElfProgram(program, as_cap); dbgln("Thread Create"); @@ -100,10 +100,9 @@ uint64_t SpawnProcessFromElfRegion(uint64_t program) { check(ZThreadCreate(proc_cap, &thread_cap)); dbgln("Thread start"); - check(ZThreadStart(thread_cap, entry_point, foreign_chan, 0)); + check(ZThreadStart(thread_cap, entry_point, foreign_chan_id, 0)); - const uint8_t* msg = reinterpret_cast("Hello!"); - check(ZChannelSend(local_chan, 0, 7, msg, 0, 0)); + local.WriteStr("Hello!"); return Z_OK; } diff --git a/sys/test2.cpp b/sys/test2.cpp index f3fc31e..45d3616 100644 --- a/sys/test2.cpp +++ b/sys/test2.cpp @@ -1,15 +1,6 @@ +#include #include #include -#include - -#define CHECK(expr) \ - { \ - uint64_t code = expr; \ - if (code != Z_OK) { \ - ZDebug("crash!"); \ - return 1; \ - } \ - } void thread_entry(void* a) { dbgln("In thread"); @@ -26,12 +17,11 @@ int main(uint64_t bootstrap_cap) { Thread t1(thread_entry, a); Thread t2(thread_entry, b); - uint64_t num_bytes = 10; - uint64_t num_caps; - uint8_t bytes[10]; - uint64_t type; - check(ZChannelRecv(bootstrap_cap, num_bytes, bytes, 0, 0, &type, &num_bytes, - &num_caps)); - dbgln(reinterpret_cast(bytes)); + uint64_t size = 10; + char buff[10]; + Channel c1; + c1.adopt_cap(bootstrap_cap); + check(c1.ReadStr(buff, &size)); + dbgln(buff); return 0; } diff --git a/zion/include/zerrors.h b/zion/include/zerrors.h index 96c0c4c..63815d3 100644 --- a/zion/include/zerrors.h +++ b/zion/include/zerrors.h @@ -7,7 +7,9 @@ #define Z_ERR_INVALID 0x2 #define Z_ERR_DENIED 0x3 #define Z_ERR_UNIMPLEMENTED 0x4 -#define Z_ERR_BUFF_SIZE 0x05 +#define Z_ERR_BUFF_SIZE 005 +#define Z_ERR_NULL 0x6 +#define Z_ERR_EXISTS 0x7 #define Z_ERR_CAP_NOT_FOUND 0x100 #define Z_ERR_CAP_TYPE 0x101