First pass at message syscalls

This commit is contained in:
Justin C. Miller
2019-02-07 18:19:22 -08:00
parent 8e85ae5318
commit aca442ee87
5 changed files with 141 additions and 8 deletions

View File

@@ -9,6 +9,11 @@ _start:
mov rax, 1 ; DEBUG syscall mov rax, 1 ; DEBUG syscall
int 0xee int 0xee
cmp r12, 1
je .dosend
jne .doreceive
.preloop:
mov r11, 0 ; counter mov r11, 0 ; counter
mov rbx, 20 ; sleep timeout mov rbx, 20 ; sleep timeout
@@ -31,3 +36,15 @@ _start:
mov r11, 0 mov r11, 0
jmp .loop jmp .loop
.dosend:
mov rax, 6 ; SEND syscall
mov rdi, 2 ; target is pid 2
int 0xee
jmp .preloop
.doreceive:
mov rax, 7 ; RECEIVE syscall
mov rdi, 1 ; source is pid 2
int 0xee
jmp .preloop

View File

@@ -1,28 +1,65 @@
#include "process.h" #include "process.h"
#include "scheduler.h"
void bool
process::wait_on_signal(uint64_t sigmask) process::wait_on_signal(uint64_t sigmask)
{ {
waiting = process_wait::signal; waiting = process_wait::signal;
waiting_info = sigmask; waiting_info = sigmask;
flags -= process_flags::ready; flags -= process_flags::ready;
return true;
} }
void bool
process::wait_on_child(uint32_t pid) process::wait_on_child(uint32_t pid)
{ {
waiting = process_wait::child; waiting = process_wait::child;
waiting_info = pid; waiting_info = pid;
flags -= process_flags::ready; flags -= process_flags::ready;
return true;
} }
void bool
process::wait_on_time(uint64_t time) process::wait_on_time(uint64_t time)
{ {
waiting = process_wait::time; waiting = process_wait::time;
waiting_info = time; waiting_info = time;
flags -= process_flags::ready; flags -= process_flags::ready;
return true;
}
bool
process::wait_on_send(uint32_t target_id)
{
scheduler &s = scheduler::get();
process *target = s.get_process_by_id(target_id);
if (!target) return false;
if (!target->wake_on_receive(this)) {
waiting = process_wait::send;
waiting_info = target_id;
flags -= process_flags::ready;
}
return true;
}
bool
process::wait_on_receive(uint32_t source_id)
{
scheduler &s = scheduler::get();
process *source = s.get_process_by_id(source_id);
if (!source) return false;
if (!source->wake_on_send(this)) {
waiting = process_wait::receive;
waiting_info = source_id;
flags -= process_flags::ready;
return true;
}
return false;
} }
bool bool
@@ -49,7 +86,6 @@ process::wake_on_child(process *child)
return true; return true;
} }
bool bool
process::wake_on_time(uint64_t now) process::wake_on_time(uint64_t now)
{ {
@@ -62,3 +98,28 @@ process::wake_on_time(uint64_t now)
return true; return true;
} }
bool
process::wake_on_send(process *target)
{
if (waiting != process_wait::send ||
waiting_info != target->pid)
return false;
waiting = process_wait::none;
flags += process_flags::ready;
return true;
}
bool
process::wake_on_receive(process *source)
{
if (waiting != process_wait::receive ||
waiting_info != source->pid)
return false;
waiting = process_wait::none;
flags += process_flags::ready;
return true;
}

View File

@@ -25,7 +25,9 @@ enum class process_wait : uint8_t
none, none,
signal, signal,
child, child,
time time,
send,
receive
}; };
/// A process /// A process
@@ -52,15 +54,30 @@ struct process
/// Unready this process until it gets a signal /// Unready this process until it gets a signal
/// \arg sigmask A bitfield of signals to wake on /// \arg sigmask A bitfield of signals to wake on
void wait_on_signal(uint64_t sigmask); /// \returns Whether the process should be rescheduled
bool wait_on_signal(uint64_t sigmask);
/// Unready this process until a child exits /// Unready this process until a child exits
/// \arg pid PID of the child to wait for, or 0 for any /// \arg pid PID of the child to wait for, or 0 for any
void wait_on_child(uint32_t pid); /// \returns Whether the process should be rescheduled
bool wait_on_child(uint32_t pid);
/// Unready this process until after the given time /// Unready this process until after the given time
/// \arg time The time after which to wake /// \arg time The time after which to wake
void wait_on_time(uint64_t time); /// \returns Whether the process should be rescheduled
bool wait_on_time(uint64_t time);
/// Try to send to the target process, becoming unready if it
/// is not waiting on receive.
/// \arg target_id The process to send to
/// \returns Whether the process should be rescheduled
bool wait_on_send(uint32_t target_id);
/// Try to receive from one or more processes, becoming unready
/// if none of them are waiting on a send to this process.
/// \arg source_id The process to receive from
/// \returns Whether the process should be rescheduled
bool wait_on_receive(uint32_t source_id);
/// If this process is waiting on the given signal, wake it /// If this process is waiting on the given signal, wake it
/// \argument signal The signal sent to the process /// \argument signal The signal sent to the process
@@ -76,6 +93,17 @@ struct process
/// \argument now The current time /// \argument now The current time
/// \returns True if this wake was handled /// \returns True if this wake was handled
bool wake_on_time(uint64_t now); bool wake_on_time(uint64_t now);
/// If this process is waiting to send to this target, wake it
/// \argument target The target process
/// \returns True if this wake was handled
bool wake_on_send(process *target);
/// If this process is waiting to receieve from this source, wake it
/// \argument source The process that is sending
/// \returns True if this wake was handled
bool wake_on_receive(process *source);
}; };
using process_list = kutil::linked_list<process>; using process_list = kutil::linked_list<process>;

View File

@@ -92,6 +92,31 @@ syscall_dispatch(uintptr_t return_rsp, cpu_state &regs)
regs.rax = p->pid; regs.rax = p->pid;
break; break;
case syscall::send:
{
uint32_t target = regs.rdi;
cons->set_color(11);
cons->printf("\nProcess %u: Received SEND syscall, target %u\n", p->pid, target);
cons->set_color();
if (p->wait_on_send(target))
return_rsp = s.schedule(return_rsp);
}
break;
case syscall::receive:
{
uint32_t source = regs.rdi;
cons->set_color(11);
cons->printf("\nProcess %u: Received RECEIVE syscall, source %u\n", p->pid, source);
cons->set_color();
if (p->wait_on_receive(source))
return_rsp = s.schedule(return_rsp);
}
break;
default: default:
cons->set_color(9); cons->set_color(9);

View File

@@ -12,6 +12,8 @@ enum class syscall : uint64_t
pause, pause,
sleep, sleep,
getpid, getpid,
send,
receive,
last_syscall last_syscall
}; };