// SafeC Standard Library — IPC Mailbox
#pragma once
#include <std/stddef.h>
#include <std/kernel/ipc.h>
namespace std {
extern unsigned char* memcpy(unsigned char* dst, const unsigned char* src, size_t n);
inline struct Mailbox Mailbox::new(int owner_pid) {
struct Mailbox mb;
mb.head = 0;
mb.tail = 0;
mb.count = 0;
mb.owner_pid = owner_pid;
return mb;
}
inline int Mailbox::send(int sender_pid, int type, []const unsigned char payload) {
if (self.count >= 64) { return 0; } // full
unsigned long size = payload.len;
if (size > (unsigned long)256) { size = (unsigned long)256; } // truncate
int idx = self.head;
self.messages[idx].sender_pid = sender_pid;
self.messages[idx].type = type;
self.messages[idx].size = size;
if (size > 0UL) {
unsafe { memcpy((unsigned char*)self.messages[idx].payload, (const unsigned char*)payload.ptr, size); }
}
self.head = (self.head + 1) & 63;
self.count = self.count + 1;
return 1;
}
inline int Mailbox::recv(&Message out) {
if (self.count <= 0) { return 0; } // empty
int idx = self.tail;
out.sender_pid = self.messages[idx].sender_pid;
out.type = self.messages[idx].type;
out.size = self.messages[idx].size;
if (out.size > (unsigned long)0) {
unsafe { memcpy((unsigned char*)out.payload, (const unsigned char*)self.messages[idx].payload, out.size); }
}
self.tail = (self.tail + 1) & 63;
self.count = self.count - 1;
return 1;
}
inline int Mailbox::peek(&Message out) const {
if (self.count <= 0) { return 0; }
int idx = self.tail;
out.sender_pid = self.messages[idx].sender_pid;
out.type = self.messages[idx].type;
out.size = self.messages[idx].size;
if (out.size > (unsigned long)0) {
unsafe { memcpy((unsigned char*)out.payload, (const unsigned char*)self.messages[idx].payload, out.size); }
}
return 1;
}
inline int Mailbox::has_msg() const {
if (self.count > 0) { return 1; }
return 0;
}
int Mailbox::length() const { return self.count; }
inline void Mailbox::clear() {
self.head = 0;
self.tail = 0;
self.count = 0;
}
} // namespace std