diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-16 11:01:38 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-16 11:02:00 +0200 |
commit | 9396108034acd4bdd91532e13528f0b94af16653 (patch) | |
tree | 26d7870743b3276555db4f2408a4ce9c3f8ced9a /Kernel/IPC.cpp | |
parent | f6086297047b639ede6fc0e058e4efcfc09ea46f (diff) | |
download | serenity-9396108034acd4bdd91532e13528f0b94af16653.zip |
Import the "gerbert" kernel I worked on earlier this year.
It's a lot crappier than I remembered it. It's gonna need a lot of work.
Diffstat (limited to 'Kernel/IPC.cpp')
-rw-r--r-- | Kernel/IPC.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/Kernel/IPC.cpp b/Kernel/IPC.cpp new file mode 100644 index 0000000000..5e5b0af540 --- /dev/null +++ b/Kernel/IPC.cpp @@ -0,0 +1,104 @@ +#include "IPC.h" +#include "Task.h" +#include "i386.h" +#include "StdLib.h" +#include "VGA.h" +#include "system.h" + +namespace IPC { + +Message receive(Handle src) +{ + for (;;) { + current->ipc.src = src; + block(Task::BlockedReceive); + if (src == Handle::Any && current->ipc.notifies) { + for (BYTE i = 0; i < 32; ++i) { + if (current->ipc.notifies & (1 << i)) { + // FIXME: Source PID is `i' here. Do something with it? + current->ipc.notifies &= ~(1 << i); + break; + } + } + return Message(MSG_NOTIFY); + } + + if (src == Handle::Any || src == current->ipc.msg.sender()) { + return move(current->ipc.msg); + } + + // Why are we here? + ASSERT_NOT_REACHED(); + } +} + +void send(Handle dst, Message&& msg) +{ + Task* task; + + // TODO: Block waiting for `dst' to spawn. + for (;;) { + task = Task::fromIPCHandle(dst); + if (task) + break; + yield(); + } + + // I'll fill this in myself thankyouverymuch. + msg.setSender(current->handle()); + + // Block until `dst' is ready to receive a message. + current->ipc.dst = dst; + block(Task::BlockedSend); + + ASSERT(msg.isValid()); + task->ipc.msg = move(msg); +} + +void notify(Handle dst) +{ + Task* task = Task::fromIPCHandle(dst); + + if (!task) { + // Can't really block here since we might be coming from + // an interrupt handler and that'd be devastating... + // XXX: Need to figure that one out. + kprintf("notify(): no such task %u\n", dst.data()); + return; + } + + if (current->pid() >= 32) { + kprintf( "notify(): PID must be < 32\n" ); + return; + } + + task->ipc.notifies |= 1 << current->pid(); +} + +Message::Message(Message&& other) + : m_data(move(other.m_data)) + , m_type(other.m_type) + , m_sender(other.m_sender) + , m_isValid(other.m_isValid) +{ + other.m_type = 0; + other.m_sender = Handle(); + other.m_isValid = false; +} + +Message& Message::operator=(Message&& other) +{ + if (this == &other) + return *this; + m_data = move(other.m_data); + m_type = other.m_type; + m_sender = other.m_sender; + m_isValid = other.m_isValid; + other.m_type = 0; + other.m_sender = Handle(); + other.m_isValid = false; + return *this; +} + + +} |