aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-07-27 14:56:38 +0200
committerHimbeer <himbeer@disroot.org>2024-07-27 14:56:38 +0200
commit69cb92899b7827efdeb9c625299eb4ec197abff7 (patch)
tree550c17f05b2ac71835db5fdd980f2276b51637ca /src
parent36c55a9589e66773205195cd29910f261f2c7c86 (diff)
syscall: Support termination of other processes or (individual) threads
Closes #57.
Diffstat (limited to 'src')
-rw-r--r--src/lib/process.zig8
-rw-r--r--src/lib/syscall.zig33
2 files changed, 34 insertions, 7 deletions
diff --git a/src/lib/process.zig b/src/lib/process.zig
index 89ce369..4b7c095 100644
--- a/src/lib/process.zig
+++ b/src/lib/process.zig
@@ -170,7 +170,7 @@ pub const Info = struct {
var node = list.first;
while (node) |proc_node| : (node = proc_node.next) {
- if (self.shouldRemove(&proc_node.data)) {
+ if (self.shouldTerminate(&proc_node.data)) {
if (proc_node.data.thread_id != self.thread_id) {
proc_node.data.terminate();
}
@@ -208,11 +208,11 @@ pub const Info = struct {
self.state = .waiting;
}
- fn shouldRemove(self: *const Info, candidate: *const Info) bool {
- return candidate.id == self.id and self.shouldRemoveThread(candidate);
+ pub fn shouldTerminate(self: *const Info, candidate: *const Info) bool {
+ return candidate.id == self.id and self.shouldTerminateThread(candidate);
}
- fn shouldRemoveThread(self: *const Info, candidate: *const Info) bool {
+ fn shouldTerminateThread(self: *const Info, candidate: *const Info) bool {
return candidate.thread_id == self.thread_id or self.thread_id == 0;
}
diff --git a/src/lib/syscall.zig b/src/lib/syscall.zig
index 9841675..0f1a44a 100644
--- a/src/lib/syscall.zig
+++ b/src/lib/syscall.zig
@@ -35,10 +35,11 @@ pub fn handler(proc: *process.Info, trap_frame: *trap.Frame) !void {
100009 => ret(null, trap_frame, read(proc, trap_frame)),
100010 => ret(null, trap_frame, write(proc, trap_frame)),
100011 => ret(null, trap_frame, list(proc, trap_frame)),
- 100012 => ret(null, trap_frame, terminate(proc)),
+ 100012 => ret(null, trap_frame, end(proc)),
100013 => ret(null, trap_frame, processId(proc)),
100014 => ret(null, trap_frame, threadId(proc)),
100015 => ret(null, trap_frame, launch(trap_frame)),
+ 100016 => ret(null, trap_frame, terminate(proc, trap_frame)),
else => return HandleError.UnknownSyscall,
}
}
@@ -306,8 +307,8 @@ fn list(proc: *process.Info, trap_frame: *trap.Frame) void {
sysexchange.frameReturn(null, trap_frame, result);
}
-// terminate() void
-fn terminate(proc: *process.Info) void {
+// end() void
+fn end(proc: *process.Info) void {
proc.terminate();
process.schedule() catch |err| {
std.debug.panic("Unable to schedule because all processes are terminated: {}", .{err});
@@ -337,3 +338,29 @@ fn launch(trap_frame: *const trap.Frame) !usize {
const new_proc = try process.create(mem.page_allocator, bytes);
return new_proc.id;
}
+
+pub const TerminateError = error{
+ PidOutOfRange,
+ ProcessNotFound,
+};
+
+// terminate(pid: u16, tid: usize) !void
+fn terminate(proc: *const process.Info, trap_frame: *const trap.Frame) !void {
+ const pid: u16 = @truncate(trap_frame.general_purpose_registers[10]);
+ const tid = trap_frame.general_purpose_registers[11];
+
+ if (pid != trap_frame.general_purpose_registers[10]) {
+ return TerminateError.PidOutOfRange;
+ }
+
+ const target = process.findThread(pid, tid) orelse {
+ return TerminateError.ProcessNotFound;
+ };
+ target.terminate();
+
+ if (target.shouldTerminate(proc)) {
+ process.schedule() catch |err| {
+ std.debug.panic("Unable to schedule because all processes are terminated: {}", .{err});
+ };
+ }
+}