add utilisation tracker

This commit is contained in:
Jack Halford 2020-01-01 22:59:01 +01:00
parent 4148314d84
commit a01e9a5f2a
3 changed files with 21 additions and 14 deletions

View file

@ -78,37 +78,36 @@ pub fn new(entrypoint: usize) !*TaskNode {
defer task.unlock_scheduler(); defer task.unlock_scheduler();
const node = try vmem.create(TaskNode); const node = try vmem.create(TaskNode);
errdefer vmem.destroy(node);
node.data = try Task.create(entrypoint); node.data = try Task.create(entrypoint);
ready_tasks.prepend(node); ready_tasks.prepend(node);
return node; return node;
} }
pub fn sleep_tick(tick: usize) void { pub fn wakeup_tick(tick: usize) bool {
task.lock_scheduler(); task.lock_scheduler();
defer task.unlock_scheduler(); defer task.unlock_scheduler();
task.sleeping_tasks.decrement(tick); task.sleeping_tasks.decrement(tick);
var popped = false; var popped = false;
while (task.sleeping_tasks.popZero()) |sleepnode| { while (task.sleeping_tasks.popZero()) |sleepnode| {
// println("finished sleeping");
// task.format();
const tasknode = sleepnode.data; const tasknode = sleepnode.data;
tasknode.data.state = .ReadyToRun; tasknode.data.state = .ReadyToRun;
vmem.free(@ptrToInt(sleepnode)); vmem.free(@ptrToInt(sleepnode));
task.ready_tasks.prepend(tasknode); task.ready_tasks.prepend(tasknode);
popped = true; popped = true;
} }
if (popped) preempt(); return popped;
} }
// TODO: make a sleep without malloc // TODO: make a sleep without malloc
pub fn usleep(usec: u64) !void { pub fn usleep(usec: u64) !void {
assert(current_task.data.state == .Running); assert(current_task.data.state == .Running);
update_time_used();
const node = try vmem.create(SleepNode); const node = try vmem.create(SleepNode);
update_time_used();
lock_scheduler(); lock_scheduler();
defer unlock_scheduler(); defer unlock_scheduler();
@ -121,16 +120,15 @@ pub fn usleep(usec: u64) !void {
pub fn block(state: TaskState) void { pub fn block(state: TaskState) void {
assert(current_task.data.state == .Running); assert(current_task.data.state == .Running);
assert(state != .Running); assert(state != .Running);
assert(state != .ReadyToRun); assert(state != .ReadyToRun);
update_time_used();
// println("blocking {} as {}", current_task.data.tid, state); // println("blocking {} as {}", current_task.data.tid, state);
lock_scheduler(); lock_scheduler();
defer unlock_scheduler(); defer unlock_scheduler();
update_time_used();
current_task.data.state = state; current_task.data.state = state;
blocked_tasks.append(current_task); blocked_tasks.append(current_task);
schedule(); schedule();
@ -190,14 +188,14 @@ pub fn cleaner_loop() noreturn {
pub var IRQ_disable_counter: usize = 0; pub var IRQ_disable_counter: usize = 0;
pub var postpone_task_switches_counter: isize = 0; // this counter can go negative when we are scheduling after a postpone pub var postpone_task_switches_counter: isize = 0; // this counter can go negative when we are scheduling after a postpone
pub var postpone_task_switches_flag: bool = false; pub var postpone_task_switches_flag: bool = false;
pub fn lock_scheduler() void { fn lock_scheduler() void {
if (constants.SMP == false) { if (constants.SMP == false) {
x86.cli(); x86.cli();
IRQ_disable_counter += 1; IRQ_disable_counter += 1;
postpone_task_switches_counter += 1; postpone_task_switches_counter += 1;
} }
} }
pub fn unlock_scheduler() void { fn unlock_scheduler() void {
if (constants.SMP == false) { if (constants.SMP == false) {
assert(IRQ_disable_counter > 0); assert(IRQ_disable_counter > 0);
postpone_task_switches_counter -= 1; postpone_task_switches_counter -= 1;
@ -331,7 +329,7 @@ pub fn notify(comptime message: []const u8, args: ...) void {
const cursor = vga.cursor; const cursor = vga.cursor;
vga.background = fg; vga.background = fg;
vga.foreground = bg; vga.foreground = bg;
vga.cursor = 80 - message.len - 10; vga.cursor = 80 - message.len;
vga.cursor_enabled = false; vga.cursor_enabled = false;
print(message, args); print(message, args);

View file

@ -6,19 +6,26 @@ pub var TASK_SLICE: u64 = 50 * 1000;
pub fn increment() void { pub fn increment() void {
const tick = x86.interrupt.tick; //us const tick = x86.interrupt.tick; //us
offset_us += tick; offset_us += tick; //global time counter
task.sleep_tick(tick);
var should_preempt = task.wakeup_tick(tick);
if (task_slice_remaining != 0) { if (task_slice_remaining != 0) {
// There is a time slice length // There is a time slice length
if (task_slice_remaining <= tick) return task.preempt(); if (task_slice_remaining <= tick) should_preempt = true;
if (task_slice_remaining > tick) task_slice_remaining -= tick; if (task_slice_remaining > tick) task_slice_remaining -= tick;
} }
if (should_preempt) task.preempt();
} }
pub fn uptime() void { pub fn uptime() void {
var offset_ms: u64 = offset_us / 1000; var offset_ms: u64 = offset_us / 1000;
const offset_s: u64 = offset_ms / 1000; const offset_s: u64 = offset_ms / 1000;
offset_ms = @mod(offset_ms / 100, 10); offset_ms = @mod(offset_ms / 100, 10);
print("{}.{:.3}", offset_s, offset_ms); print("{}.{:.3}", offset_s, offset_ms);
} }
pub fn utilisation() void {
print("{}%", 100 * (offset_us - task.CPU_idle_time) / offset_us);
}

View file

@ -73,6 +73,8 @@ pub fn topbar() void {
time.uptime(); time.uptime();
print(" | "); print(" | ");
time.utilisation();
print(" | ");
task.format_short(); task.format_short();
// print(" ({})", task.IRQ_disable_counter); // print(" ({})", task.IRQ_disable_counter);
println(""); println("");