mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
First pass at message syscalls
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>;
|
||||||
|
|||||||
@@ -92,6 +92,31 @@ syscall_dispatch(uintptr_t return_rsp, cpu_state ®s)
|
|||||||
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);
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ enum class syscall : uint64_t
|
|||||||
pause,
|
pause,
|
||||||
sleep,
|
sleep,
|
||||||
getpid,
|
getpid,
|
||||||
|
send,
|
||||||
|
receive,
|
||||||
|
|
||||||
last_syscall
|
last_syscall
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user