node: add local_time and increment it by a fixed amount any time a task runs
This commit is contained in:
@@ -868,14 +868,7 @@ fn fileClose(userdata: ?*anyopaque, files: []const File) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn fileWritePositional(
|
||||
userdata: ?*anyopaque,
|
||||
file : File,
|
||||
header : []const u8,
|
||||
data : []const []const u8,
|
||||
splat : usize,
|
||||
offset : u64
|
||||
) File.WritePositionalError!usize {
|
||||
fn fileWritePositional(userdata: ?*anyopaque, file: File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize {
|
||||
const node: *Node = @ptrCast(@alignCast(userdata.?));
|
||||
var cursor = std.math.cast(usize, offset) orelse return File.WritePositionalError.FileTooBig;
|
||||
var copied: usize = 0;
|
||||
@@ -1201,7 +1194,7 @@ fn now(userdata: ?*anyopaque, clock: Clock) Timestamp {
|
||||
// TODO: Return an appropriate time for each clock
|
||||
_ = clock;
|
||||
|
||||
return .{ .nanoseconds = node.scheduler.current_time * 1000 };
|
||||
return .{ .nanoseconds = node.local_time * 1000 };
|
||||
}
|
||||
|
||||
fn clockResolution(userdata: ?*anyopaque, clock: Clock) Clock.ResolutionError!Duration {
|
||||
|
||||
+8
-38
@@ -15,7 +15,6 @@ pub const TaskID = Scheduler.TaskID;
|
||||
const NestedEntryPoint = Scheduler.NestedEntryPoint;
|
||||
|
||||
const Descriptor = struct {
|
||||
|
||||
const Kind = enum {
|
||||
dir,
|
||||
file,
|
||||
@@ -32,6 +31,7 @@ const Descriptor = struct {
|
||||
};
|
||||
|
||||
gpa: Allocator,
|
||||
local_time: u64,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
argv: [][*:0]const u8,
|
||||
environ_map: std.process.Environ.Map,
|
||||
@@ -80,16 +80,9 @@ fn splitCommandArguments(command: []const u8, arena: Allocator) Allocator.Error!
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
self : *Node,
|
||||
real_io : std.Io,
|
||||
scheduler: *Scheduler,
|
||||
network : *Network,
|
||||
command : []const u8,
|
||||
addresses: []const u32,
|
||||
gpa : Allocator
|
||||
) !void {
|
||||
pub fn init(self: *Node, real_io: std.Io, scheduler: *Scheduler, network: *Network, command: []const u8, addresses: []const u32, gpa: Allocator) !void {
|
||||
self.gpa = gpa;
|
||||
self.local_time = 0;
|
||||
self.arena = .init(gpa);
|
||||
self.scheduler = scheduler;
|
||||
try self.file_system.init(gpa);
|
||||
@@ -237,11 +230,7 @@ pub const CreateDirError = HandleError || FileSystem.CreateError || CancelError;
|
||||
|
||||
pub fn createDir(self: *Node, parent: ?Handle, path: []const u8) CreateDirError!void {
|
||||
try self.scheduler.sleep(10);
|
||||
return self.file_system.createDir(
|
||||
path,
|
||||
try self.handleToOpenDirOrNULL(parent),
|
||||
self.gpa
|
||||
);
|
||||
return self.file_system.createDir(path, try self.handleToOpenDirOrNULL(parent), self.gpa);
|
||||
}
|
||||
|
||||
pub const OpenDirError = error{
|
||||
@@ -285,33 +274,21 @@ pub const CreateFileError = HandleError || FileSystem.CreateError || CancelError
|
||||
|
||||
pub fn createFile(self: *Node, parent: ?Handle, path: []const u8) CreateFileError!void {
|
||||
try self.scheduler.sleep(10);
|
||||
return self.file_system.createFile(
|
||||
path,
|
||||
try self.handleToOpenDirOrNULL(parent),
|
||||
self.gpa
|
||||
);
|
||||
return self.file_system.createFile(path, try self.handleToOpenDirOrNULL(parent), self.gpa);
|
||||
}
|
||||
|
||||
pub const DeleteFileError = HandleError || FileSystem.DeleteFileError || CancelError;
|
||||
|
||||
pub fn deleteFile(self: *Node, parent: ?Handle, path: []const u8) DeleteFileError!void {
|
||||
try self.scheduler.sleep(10);
|
||||
return self.file_system.deleteFile(
|
||||
path,
|
||||
try self.handleToOpenDirOrNULL(parent),
|
||||
self.gpa
|
||||
);
|
||||
return self.file_system.deleteFile(path, try self.handleToOpenDirOrNULL(parent), self.gpa);
|
||||
}
|
||||
|
||||
pub const DeleteDirError = HandleError || FileSystem.DeleteDirError || CancelError;
|
||||
|
||||
pub fn deleteDir(self: *Node, parent: ?Handle, path: []const u8) DeleteDirError!void {
|
||||
try self.scheduler.sleep(10);
|
||||
return self.file_system.deleteDir(
|
||||
path,
|
||||
try self.handleToOpenDirOrNULL(parent),
|
||||
self.gpa
|
||||
);
|
||||
return self.file_system.deleteDir(path, try self.handleToOpenDirOrNULL(parent), self.gpa);
|
||||
}
|
||||
|
||||
pub const OpenFileError = error{
|
||||
@@ -383,14 +360,7 @@ fn writeToStderr(self: *Node, source: []const u8) void {
|
||||
|
||||
pub const WriteFileError = HandleError || Allocator.Error || CancelError;
|
||||
|
||||
pub fn writeFile(
|
||||
self : *Node,
|
||||
handle: Handle,
|
||||
offset: ?usize,
|
||||
header: []const u8,
|
||||
source: []const []const u8
|
||||
) WriteFileError!usize {
|
||||
|
||||
pub fn writeFile(self: *Node, handle: Handle, offset: ?usize, header: []const u8, source: []const []const u8) WriteFileError!usize {
|
||||
try self.scheduler.sleep(100);
|
||||
|
||||
if (handle == 0) {
|
||||
|
||||
+9
-4
@@ -26,6 +26,7 @@ const ContextSwitch = extern struct {
|
||||
|
||||
const STACK_CANARY_SIZE = 256;
|
||||
const STACK_CANARY_BYTE = 0xa5;
|
||||
const TASK_RUN_COST_US = 50;
|
||||
|
||||
pub const TaskID = u64;
|
||||
|
||||
@@ -107,7 +108,6 @@ fn spawnInner(
|
||||
parent_id: ?TaskID,
|
||||
context: ?*const anyopaque,
|
||||
) !*Task {
|
||||
|
||||
if (stack_size > std.math.maxInt(usize) - STACK_CANARY_SIZE)
|
||||
return Allocator.Error.OutOfMemory;
|
||||
|
||||
@@ -196,6 +196,9 @@ fn findBlockedTaskWithLowestWakeupTime(self: *Scheduler) ?*Task {
|
||||
fn advanceTimeAndUnblockTasks(self: *Scheduler, new_time: u64) void {
|
||||
std.debug.assert(self.current_time < new_time);
|
||||
self.current_time = new_time;
|
||||
for (self.tasks.items) |task| {
|
||||
task.node.local_time = @max(task.node.local_time, new_time);
|
||||
}
|
||||
for (self.tasks.items) |*task| {
|
||||
if (task.state == .blocked) {
|
||||
if (task.wakeup_time) |wakeup_time| {
|
||||
@@ -229,9 +232,7 @@ fn advanceTimeAndPickTask(self: *Scheduler) ?*Task {
|
||||
}
|
||||
|
||||
pub fn scheduleOne(self: *Scheduler) bool {
|
||||
const task = self.findTaskWithState(.ready)
|
||||
orelse self.advanceTimeAndPickTask()
|
||||
orelse return false;
|
||||
const task = self.findTaskWithState(.ready) orelse self.advanceTimeAndPickTask() orelse return false;
|
||||
const id = task.id;
|
||||
self.current_id = id;
|
||||
task.state = .running;
|
||||
@@ -296,6 +297,7 @@ fn taskStart(self: *Scheduler) callconv(.c) noreturn {
|
||||
current.wakeup_time = null;
|
||||
current.wakeup_tasks = null;
|
||||
current.wakeup_futex = null;
|
||||
current.node.local_time += TASK_RUN_COST_US;
|
||||
if (current.parent_id) |parent_id| {
|
||||
if (self.findTaskByID(parent_id)) |parent| {
|
||||
if (taskIsWaitingFor(parent, current.id)) {
|
||||
@@ -322,6 +324,7 @@ pub fn sleep(self: *Scheduler, delta_us: u64) !void {
|
||||
current.wakeup_time = self.current_time + delta_us;
|
||||
current.wakeup_tasks = null;
|
||||
current.wakeup_futex = null;
|
||||
current.node.local_time += TASK_RUN_COST_US;
|
||||
contextSwitch(¤t.regs, &self.regs);
|
||||
try self.checkCancel();
|
||||
}
|
||||
@@ -341,6 +344,7 @@ pub fn futexWaitUncancelable(self: *Scheduler, ptr: *const u32, expected: u32) v
|
||||
current.wakeup_time = null;
|
||||
current.wakeup_tasks = null;
|
||||
current.wakeup_futex = ptr;
|
||||
current.node.local_time += TASK_RUN_COST_US;
|
||||
contextSwitch(¤t.regs, &self.regs);
|
||||
}
|
||||
|
||||
@@ -385,6 +389,7 @@ pub fn wait(self: *Scheduler, ids: []const TaskID) !TaskID {
|
||||
task.wakeup_time = null;
|
||||
task.wakeup_tasks = ids;
|
||||
task.wakeup_futex = null;
|
||||
task.node.local_time += TASK_RUN_COST_US;
|
||||
contextSwitch(&task.regs, &self.regs);
|
||||
try self.checkCancel();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user