Improve scheduler feedback.

This commit is contained in:
Enrico Fraccaroli
2023-04-19 10:22:14 +02:00
parent d630fd55f7
commit 6aa814f30a
4 changed files with 95 additions and 75 deletions
+5 -1
View File
@@ -13,9 +13,10 @@
#include "assert.h"
#include "strerror.h"
#include "fs/vfs.h"
#include "process/scheduler.h"
#include "descriptor_tables/tss.h"
#include "devices/fpu.h"
#include "process/scheduler_feedback.h"
#include "process/scheduler.h"
#include "process/prio.h"
#include "process/wait.h"
#include "mem/kheap.h"
@@ -111,10 +112,13 @@ void scheduler_enqueue_task(task_struct *process)
list_head_insert_before(&process->run_list, &runqueue.queue);
// Increment the number of active processes.
++runqueue.num_active;
scheduler_feedback_task_add(process);
}
void scheduler_dequeue_task(task_struct *process)
{
scheduler_feedback_task_remove(process->pid);
// Delete the process from the list of running processes.
list_head_remove(&process->run_list);
// Decrement the number of active processes.
+3 -2
View File
@@ -238,8 +238,9 @@ task_struct *scheduler_pick_next_task(runqueue_t *runqueue)
// Update the last context switch time of the next task.
next->se.exec_start = timer_get_ticks();
scheduler_feedback_update(next);
scheduler_feedback_task_update(next);
scheduler_feedback_update();
return next;
}
+72 -69
View File
@@ -34,12 +34,14 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress
#include "fcntl.h"
#include "stdio.h"
//#define WRITE_ON_FILE
/// @brief
#define FEEDBACK_FILENAME "/var/feedback.txt"
/// @brief
#define FEEDBACK_HEADER "\nPID PRIO NAME\n\0"
/// @brief
#define LOG_INTERVAL 3
#define LOG_INTERVAL_SEC 1
#if defined(SCHEDULER_RR)
#define POLICY_NAME "RR "
@@ -57,22 +59,25 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress
#error "You should enable a scheduling algorithm!"
#endif
#ifdef WRITE_ON_FILE
/// @brief
ssize_t offset;
#endif
/// @brief
size_t next_log;
unsigned long next_log;
/// @brief
size_t total_occurrences;
/// @brief
struct statistic {
pid_t pid;
char name[20];
task_struct *task;
unsigned long occur;
} arr_stats[PID_MAX_LIMIT];
int scheduler_feedback_init()
{
#ifdef WRITE_ON_FILE
// Create the feedback file, if necessary.
int ret = vfs_mkdir("/var", 0644);
if ((ret < 0) && (-ret != EEXIST)) {
@@ -97,84 +102,82 @@ int scheduler_feedback_init()
offset += header_len;
// Close the file.
vfs_close(feedback);
#endif
// Initialize the stat array.
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
arr_stats[i].pid = -1;
arr_stats[i].task = NULL;
arr_stats[i].occur = 0;
}
// Set when the first logging should happen.
next_log = timer_get_seconds() + LOG_INTERVAL;
next_log = timer_get_ticks() + (LOG_INTERVAL_SEC * TICKS_PER_SECOND);
// Initialize the number of occurrences.
total_occurrences = 0;
return 1;
}
void scheduler_feedback_update(task_struct *next)
void scheduler_feedback_update()
{
assert(next && "Received a NULL task.");
// ========================================================================
if (next_log < timer_get_seconds()) {
pr_debug("Scheduling Statistics (%s)\n", POLICY_NAME);
// Open the feedback file.
//vfs_file_t *feedback = vfs_open(FEEDBACK_FILENAME, O_WRONLY, 0644);
//if (feedback == NULL) {
// pr_err("Failed to create the feedback file.\n");
// pr_err("Error: %s\n", strerror(errno));
// return;
//}
//char buffer[NAME_MAX * 2];
//int written = 0;
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
if (arr_stats[i].pid == -1) {
break;
}
if (next_log >= timer_get_ticks()) {
return;
}
pr_debug("Scheduling Statistics (%s)\n", POLICY_NAME);
#ifdef WRITE_ON_FILE
// Open the feedback file.
vfs_file_t *feedback = vfs_open(FEEDBACK_FILENAME, O_WRONLY, 0644);
if (feedback == NULL) {
pr_err("Failed to create the feedback file.\n");
pr_err("Error: %s\n", strerror(errno));
return;
}
char buffer[BUFSIZ];
int written = 0;
#endif
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
if (arr_stats[i].task) {
float tcpu = ((float)arr_stats[i].occur * 100.0) / total_occurrences;
pr_debug("[%3d] %-12s -> TCPU: %.2f%% \n",
arr_stats[i].pid,
arr_stats[i].name,
pr_debug("[%3d] | %-24s | -> TCPU: %.2f%% \n",
arr_stats[i].task->pid,
arr_stats[i].task->name,
tcpu);
//written = sprintf(buffer, "[%3d](%s)[%f], ", arr_stats[i].pid, arr_stats[i].name, tcpu);
//vfs_write(feedback, buffer, offset, written);
//offset += written;
}
//vfs_write(feedback, "/n", offset, 1);
//offset++;
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
if (arr_stats[i].pid == -1) {
break;
}
arr_stats[i].pid = -1;
arr_stats[i].occur = 0;
}
// Update when in the future, the logging should happen.
next_log = timer_get_seconds() + LOG_INTERVAL;
// Reset the number of occurrences.
total_occurrences = 0;
} else {
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
// If the process we are logging is already in the stat array, increase the occurrences.
if (arr_stats[i].pid == next->pid) {
arr_stats[i].occur += 1;
total_occurrences += 1;
break;
}
// If we reached the unused stat entries, it means the current
// process is not stored and we need to insert it.
if (arr_stats[i].pid == -1) {
arr_stats[i].pid = next->pid;
strcpy(arr_stats[i].name, next->name);
arr_stats[i].occur = 1;
total_occurrences += 1;
break;
}
#ifdef WRITE_ON_FILE
written = sprintf(buffer, "[%3d](%s)[%f], ", arr_stats[i].pid, arr_stats[i].name, tcpu);
vfs_write(feedback, buffer, offset, written);
offset += written;
#endif
}
}
#ifdef WRITE_ON_FILE
vfs_write(feedback, "/n", offset, 1);
offset++;
vfs_close(feedback);
#endif
for (size_t i = 0; i < PID_MAX_LIMIT; ++i) {
if (arr_stats[i].task)
arr_stats[i].occur = 0;
}
// Update when in the future, the logging should happen.
next_log = timer_get_ticks() + (LOG_INTERVAL_SEC * TICKS_PER_SECOND);
// Reset the number of occurrences.
total_occurrences = 0;
}
void scheduler_feedback_task_add(task_struct *task)
{
assert(task && "Received a NULL task.");
arr_stats[task->pid].occur = 1;
arr_stats[task->pid].task = task;
}
void scheduler_feedback_task_remove(pid_t pid)
{
assert(pid < PID_MAX_LIMIT && "We received a wrong pid.");
arr_stats[pid].occur = 0;
arr_stats[pid].task = NULL;
}
void scheduler_feedback_task_update(task_struct *task)
{
assert(task && "Received a NULL task.");
arr_stats[task->pid].occur += 1;
total_occurrences += 1;
}