[Mammoth] Add Channel object for simple IPC messages
This commit is contained in:
parent
65439c163a
commit
40b21d9c75
8 changed files with 116 additions and 30 deletions
|
|
@ -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}"
|
||||
)
|
||||
|
|
|
|||
22
lib/mammoth/include/mammoth/channel.h
Normal file
22
lib/mammoth/include/mammoth/channel.h
Normal 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);
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zerrors.h>
|
||||
|
||||
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);
|
||||
|
|
|
|||
61
lib/mammoth/src/channel.cpp
Normal file
61
lib/mammoth/src/channel.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -29,3 +29,8 @@ void check(uint64_t code) {
|
|||
}
|
||||
ZProcessExit(code);
|
||||
}
|
||||
|
||||
void crash(const char* str, uint64_t code) {
|
||||
dbgln(str);
|
||||
ZProcessExit(code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#include "include/mammoth/process.h"
|
||||
#include "mammoth/process.h"
|
||||
|
||||
#include <zcall.h>
|
||||
#include <zerrors.h>
|
||||
|
||||
#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<const uint8_t*>("Hello!");
|
||||
check(ZChannelSend(local_chan, 0, 7, msg, 0, 0));
|
||||
local.WriteStr("Hello!");
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue