mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
inefficiently print task cpu usage
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include "LockGuard.hpp"
|
||||
#include "SkipList.hpp"
|
||||
#include "String.hpp"
|
||||
#include "TestTemplates.hpp"
|
||||
#include "globals.hpp"
|
||||
@@ -82,6 +83,45 @@ void freeprinter() {
|
||||
}
|
||||
}
|
||||
|
||||
void statprinter() {
|
||||
SkipList<uint64_t, std::pair<String, uint64_t>> last_times = getTaskTimePerPid();
|
||||
std::atomic<uint64_t> last_print_time = micros;
|
||||
while (1) {
|
||||
sleep_self(1000000);
|
||||
uint64_t prev_print_time = last_print_time;
|
||||
last_print_time = micros;
|
||||
SkipList<uint64_t, std::pair<String, uint64_t>> prev_times = std::move(last_times);
|
||||
last_times = getTaskTimePerPid();
|
||||
|
||||
uint64_t slice = last_print_time - prev_print_time;
|
||||
if (slice == 0) continue;
|
||||
|
||||
for (const auto &t: prev_times) {
|
||||
auto f = last_times.find(t.key);
|
||||
if (!f->end && f->key == t.key) {
|
||||
assert(f->data.second >= t.data.second);
|
||||
String buf;
|
||||
buf += "PID: ";
|
||||
buf += t.key;
|
||||
buf += " ";
|
||||
buf += t.data.first;
|
||||
buf += " usage: ";
|
||||
buf += (((f->data.second - t.data.second) * 100ULL) / slice);
|
||||
buf += "%\n";
|
||||
all_tty_putstr(buf.c_str());
|
||||
} else {
|
||||
String buf;
|
||||
buf += "PID: ";
|
||||
buf += t.key;
|
||||
buf += " ";
|
||||
buf += t.data.first;
|
||||
buf += " dead \n";
|
||||
all_tty_putstr(buf.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Mutex testmutex;
|
||||
|
||||
void mtest1() {
|
||||
@@ -153,6 +193,7 @@ void ktask_main() {
|
||||
|
||||
new_ktask(ktask, "one");
|
||||
new_ktask(freeprinter, "freeprinter");
|
||||
new_ktask(statprinter, "statprinter");
|
||||
new_ktask(mtest1, "mtest1");
|
||||
new_ktask(mtest2, "mtest2");
|
||||
new_ktask(mtest3, "mtest3");
|
||||
|
||||
@@ -52,6 +52,17 @@ static void free_task(struct Task *t) {
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
SkipList<uint64_t, std::pair<String, uint64_t>> getTaskTimePerPid() {
|
||||
SkipList<uint64_t, std::pair<String, uint64_t>> ret;
|
||||
{
|
||||
LockGuard l(AllTasks_lock);
|
||||
for (const auto &t: AllTasks) {
|
||||
ret.add(t.data->pid, std::make_pair(t.data->name, t.data->used_time.load()));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void task_freer() {
|
||||
while (true) {
|
||||
sleep_self(10000);
|
||||
@@ -60,6 +71,11 @@ static void task_freer() {
|
||||
while (!TasksToFree.empty()) {
|
||||
List<Task *>::Node *t = TasksToFree.back();
|
||||
TasksToFree.pop_back();
|
||||
uint64_t pid = t->val->pid;
|
||||
{
|
||||
LockGuard l(AllTasks_lock);
|
||||
AllTasks.erase(pid);
|
||||
}
|
||||
free_task(t->val);
|
||||
delete t;
|
||||
}
|
||||
@@ -90,6 +106,7 @@ struct Task *new_ktask(void (*fn)(), const char *name) {
|
||||
newt->state = TS_RUNNING;
|
||||
newt->mode = TASKMODE_KERN;
|
||||
newt->pid = max_pid.fetch_add(1);
|
||||
newt->used_time = 0;
|
||||
|
||||
sanity_check_frame(&newt->frame);
|
||||
|
||||
@@ -199,9 +216,14 @@ extern "C" void switch_task(struct task_frame *cur_frame) {
|
||||
|
||||
if (!NextTasks_lock.try_lock()) return;
|
||||
|
||||
static uint64_t lastSwitchMicros = 0;
|
||||
uint64_t prevSwitchMicros = lastSwitchMicros;
|
||||
lastSwitchMicros = micros;
|
||||
|
||||
if (RunningTask) {
|
||||
RunningTask->val->frame = *cur_frame;
|
||||
__builtin_memcpy(RunningTask->val->fxsave, temp_fxsave, 512);
|
||||
RunningTask->val->used_time.fetch_add(lastSwitchMicros - prevSwitchMicros);
|
||||
if (RunningTask->val->state == TS_RUNNING) {
|
||||
NextTasks.emplace_front(RunningTask);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#define OS1_TASK_H
|
||||
|
||||
#include "List.hpp"
|
||||
#include "SkipList.hpp"
|
||||
#include "String.hpp"
|
||||
#include "idt.hpp"
|
||||
|
||||
#define TASK_SS 16384
|
||||
@@ -25,6 +27,7 @@ enum TaskState {
|
||||
struct Task {
|
||||
struct task_frame frame;
|
||||
uint64_t pid;
|
||||
std::atomic<uint64_t> used_time;
|
||||
struct AddressSpace *addressSpace;
|
||||
uint64_t *stack;
|
||||
char *fxsave;
|
||||
@@ -51,6 +54,9 @@ void unblock(List<Task *>::Node *what);
|
||||
|
||||
extern "C" void switch_task(struct task_frame *cur_frame);
|
||||
|
||||
// TODO: that's quite inefficient!
|
||||
SkipList<uint64_t, std::pair<String, uint64_t>> getTaskTimePerPid();
|
||||
|
||||
void yield_self();
|
||||
|
||||
extern "C" void _yield_self_kern();// Expects the caller to save interrupt state
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "idt.hpp"
|
||||
#include "io.hpp"
|
||||
|
||||
volatile uint64_t ticks;
|
||||
volatile uint64_t micros;
|
||||
volatile std::atomic<uint64_t> ticks;
|
||||
volatile std::atomic<uint64_t> micros;
|
||||
|
||||
unsigned read_pit_count(void) {
|
||||
unsigned count = 0;
|
||||
@@ -48,6 +48,6 @@ void init_timer() {
|
||||
}
|
||||
|
||||
void timer_tick() {
|
||||
ticks++;
|
||||
micros += MICROS_PER_TICK;
|
||||
ticks.fetch_add(1);
|
||||
micros.fetch_add(MICROS_PER_TICK);
|
||||
}
|
||||
@@ -5,10 +5,11 @@
|
||||
#ifndef OS1_TIMER_H
|
||||
#define OS1_TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
extern volatile uint64_t ticks;
|
||||
extern volatile uint64_t micros;
|
||||
extern volatile std::atomic<uint64_t> ticks;
|
||||
extern volatile std::atomic<uint64_t> micros;
|
||||
|
||||
void init_timer();
|
||||
void timer_tick();
|
||||
|
||||
Reference in New Issue
Block a user