[Mammoth] Add Channel object for simple IPC messages

This commit is contained in:
Drew Galbraith 2023-06-07 09:37:16 -07:00
parent 65439c163a
commit 40b21d9c75
8 changed files with 116 additions and 30 deletions

View File

@ -1,4 +1,5 @@
add_library(mammoth_lib STATIC add_library(mammoth_lib STATIC
src/channel.cpp
src/debug.cpp src/debug.cpp
src/process.cpp src/process.cpp
src/thread.cpp src/thread.cpp
@ -12,6 +13,9 @@ target_link_libraries(mammoth_lib
zion_lib) zion_lib)
set(_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -nostdlib -mabi=sysv -mgeneral-regs-only") 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 set_target_properties(mammoth_lib PROPERTIES
COMPILE_FLAGS "${_COMPILE_FLAGS}") COMPILE_FLAGS "${_COMPILE_FLAGS}"
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${_LINK_FLAGS}"
)

View File

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
#include <zerrors.h>
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);

View File

@ -1,9 +1,12 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <zerrors.h>
void dbgln(const char*); void dbgln(const char*);
// Checks that the code is ok. // Checks that the code is ok.
// if not exits the process. // if not exits the process.
void check(uint64_t); void check(uint64_t);
void crash(const char*, z_err_t);

View File

@ -0,0 +1,61 @@
#include "mammoth/channel.h"
#include <zcall.h>
#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<const uint8_t*>(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<uint8_t*>(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;
}

View File

@ -29,3 +29,8 @@ void check(uint64_t code) {
} }
ZProcessExit(code); ZProcessExit(code);
} }
void crash(const char* str, uint64_t code) {
dbgln(str);
ZProcessExit(code);
}

View File

@ -1,9 +1,10 @@
#include "include/mammoth/process.h" #include "mammoth/process.h"
#include <zcall.h> #include <zcall.h>
#include <zerrors.h> #include <zerrors.h>
#include "include/mammoth/debug.h" #include "mammoth/channel.h"
#include "mammoth/debug.h"
namespace { namespace {
@ -83,16 +84,15 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) {
} // namespace } // namespace
uint64_t SpawnProcessFromElfRegion(uint64_t program) { uint64_t SpawnProcessFromElfRegion(uint64_t program) {
dbgln("Channel Create"); Channel local, foreign;
uint64_t local_chan; check(CreateChannels(local, foreign));
uint64_t foreign_chan;
check(ZChannelCreate(&local_chan, &foreign_chan));
dbgln("Spawn"); dbgln("Spawn");
uint64_t proc_cap; uint64_t proc_cap;
uint64_t as_cap; uint64_t as_cap;
check(ZProcessSpawn(Z_INIT_PROC_SELF, foreign_chan, &proc_cap, &as_cap, uint64_t foreign_chan_id;
&foreign_chan)); check(ZProcessSpawn(Z_INIT_PROC_SELF, foreign.release_cap(), &proc_cap,
&as_cap, &foreign_chan_id));
uint64_t entry_point = LoadElfProgram(program, as_cap); uint64_t entry_point = LoadElfProgram(program, as_cap);
dbgln("Thread Create"); dbgln("Thread Create");
@ -100,10 +100,9 @@ uint64_t SpawnProcessFromElfRegion(uint64_t program) {
check(ZThreadCreate(proc_cap, &thread_cap)); check(ZThreadCreate(proc_cap, &thread_cap));
dbgln("Thread start"); 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<const uint8_t*>("Hello!"); local.WriteStr("Hello!");
check(ZChannelSend(local_chan, 0, 7, msg, 0, 0));
return Z_OK; return Z_OK;
} }

View File

@ -1,15 +1,6 @@
#include <mammoth/channel.h>
#include <mammoth/debug.h> #include <mammoth/debug.h>
#include <mammoth/thread.h> #include <mammoth/thread.h>
#include <zcall.h>
#define CHECK(expr) \
{ \
uint64_t code = expr; \
if (code != Z_OK) { \
ZDebug("crash!"); \
return 1; \
} \
}
void thread_entry(void* a) { void thread_entry(void* a) {
dbgln("In thread"); dbgln("In thread");
@ -26,12 +17,11 @@ int main(uint64_t bootstrap_cap) {
Thread t1(thread_entry, a); Thread t1(thread_entry, a);
Thread t2(thread_entry, b); Thread t2(thread_entry, b);
uint64_t num_bytes = 10; uint64_t size = 10;
uint64_t num_caps; char buff[10];
uint8_t bytes[10]; Channel c1;
uint64_t type; c1.adopt_cap(bootstrap_cap);
check(ZChannelRecv(bootstrap_cap, num_bytes, bytes, 0, 0, &type, &num_bytes, check(c1.ReadStr(buff, &size));
&num_caps)); dbgln(buff);
dbgln(reinterpret_cast<char*>(bytes));
return 0; return 0;
} }

View File

@ -7,7 +7,9 @@
#define Z_ERR_INVALID 0x2 #define Z_ERR_INVALID 0x2
#define Z_ERR_DENIED 0x3 #define Z_ERR_DENIED 0x3
#define Z_ERR_UNIMPLEMENTED 0x4 #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_NOT_FOUND 0x100
#define Z_ERR_CAP_TYPE 0x101 #define Z_ERR_CAP_TYPE 0x101