47 lines
1.4 KiB
C
47 lines
1.4 KiB
C
#include <OS/IPC.h>
|
|
#include <OS/Scheduler.h>
|
|
#include <Arch/CPU.h>
|
|
#include <Arch/Exceptions.h>
|
|
|
|
UInt64 IPCSend(OSTask* sender, UInt64 handleID, UInt64 data) {
|
|
if (handleID == 0) return -1;
|
|
OSProcess* currentProcess = sender->process;
|
|
OSTask* targetTask = (OSTask*)SchedulerProcessGetHandle(currentProcess, handleID, kOSHandleTypeTask);
|
|
if (!targetTask) return -1;
|
|
|
|
if (targetTask->state == OSTaskStateBlockedReceive) {
|
|
ExceptionsContext* receiverContext = (ExceptionsContext*)targetTask->stackPointer;
|
|
receiverContext->x1 = data;
|
|
receiverContext->x0 = currentProcess->id;
|
|
|
|
targetTask->state = OSTaskStateRunning;
|
|
return 0;
|
|
}
|
|
|
|
if (targetTask->senderWaiting != nullptr) return -2;
|
|
|
|
targetTask->senderWaiting = sender;
|
|
|
|
SchedulerBlockCurrentTask(OSTaskStateBlockedSend);
|
|
return 0;
|
|
}
|
|
|
|
void IPCReceive(ExceptionsContext* receiverFrame) {
|
|
OSTask* receiver = SchedulerGetCurrentTask();
|
|
|
|
if (receiver->senderWaiting != nullptr) {
|
|
OSTask* sender = receiver->senderWaiting;
|
|
|
|
ExceptionsContext* senderContext = (ExceptionsContext*)sender->stackPointer;
|
|
|
|
receiverFrame->x1 = senderContext->x1; // Data
|
|
receiverFrame->x0 = sender->process->id; // Sender ID
|
|
|
|
receiver->senderWaiting = nullptr;
|
|
sender->state = OSTaskStateRunning;
|
|
return;
|
|
}
|
|
|
|
SchedulerBlockCurrentTask(OSTaskStateBlockedReceive);
|
|
}
|