From 0d0cec9420c95f400925f6432324c0e5c923430d Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 15 Mar 2023 15:59:23 +0100 Subject: [PATCH 01/26] File di Prova by Cip e Tom --- prova.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 prova.txt diff --git a/prova.txt b/prova.txt new file mode 100644 index 0000000..3b69572 --- /dev/null +++ b/prova.txt @@ -0,0 +1 @@ +siamo qui \ No newline at end of file From a650fb9c6298a60595bd3402cd03cfcd55300691 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 15 Mar 2023 18:25:00 +0100 Subject: [PATCH 02/26] Fix Scheduler_priority and Scheduler_CFS --- mentos/src/process/scheduler_algorithm.c | 26 +++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 57d8cdc..6c27c1d 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -18,6 +18,8 @@ #include "process/wait.h" #include "process/scheduler.h" +int flag = 0; + /// @brief Updates task execution statistics. /// @param task the task to update. static void __update_task_statistics(task_struct *task); @@ -97,7 +99,7 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski task_struct *next = list_entry(runqueue->queue.next, struct task_struct, run_list); // Get its static priority. - time_t min = /*...*/; + time_t min = (next->se).prio; // Search for the task with the smallest static priority. list_for_each_decl(it, &runqueue->queue) @@ -106,7 +108,7 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski if (it == &runqueue->queue) continue; // Get the current entry. - task_struct *entry = list_entry(it, task_struct, run_list); + task_struct *entry = list_entry(it, struct task_struct, run_list); // We consider only runnable processes if (entry->state != TASK_RUNNING) continue; @@ -114,9 +116,9 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski if (__is_periodic_task(entry) && skip_periodic) continue; // Check if the entry has a lower priority. - if (/*...*/) { - // Chose the `entry` as the `next` task. - /*...*/ + if ((entry->se).prio <= min) { + min = (entry->se).prio; // aggiorno la priorità piu bassa trovata + next = entry; // scambio il prossimo processo con quello a priorità piu bassa trovato } } return next; @@ -141,7 +143,7 @@ static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_per task_struct *next = list_entry(runqueue->queue.next, struct task_struct, run_list); // Get its virtual runtime. - time_t min = /* ... */; + time_t min = (next->se).vruntime; // prendo il peso del processo attuale in esecuzione // Search for the task with the smallest vruntime value. list_for_each_decl(it, &runqueue->queue) @@ -160,6 +162,10 @@ static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_per // Check if the element in the list has a smaller vruntime value. /* ... */ + if ((entry->se).vruntime <= min) { + min = (entry->se).vruntime; // aggiorno il vrtime con quello piu basso trovato + next = entry; // scambio il prossimo processo con quello a priorità piu bassa trovato + } } return next; #else @@ -252,16 +258,16 @@ static void __update_task_statistics(task_struct *task) // If the task is not a periodic task we have to update the virtual runtime. if (!task->se.is_periodic) { // Get the weight of the current task. - time_t weight = /* ... */; + time_t weight = GET_WEIGHT((task)->se.prio);/* ... */; // If the weight is different from the default load, compute it. if (weight != NICE_0_LOAD) { // Get the multiplicative factor for its delta_exec. - double factor = /* ... */; + double factor = ((double)NICE_0_LOAD / (double)weight);/* ... */; // Weight the delta_exec with the multiplicative factor. - task->se.exec_runtime = /* ... */; + task->se.exec_runtime = ((int)(((double)task->se.exec_runtime) * factor));/* ... */ } // Update vruntime of the current task. - task->se.vruntime += /* ... */; + task->se.vruntime += task->se.exec_runtime; } #endif } From 95ec1d8a33a0a5aff24886a4cb15143d7bb62bdf Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 15 Mar 2023 18:38:00 +0100 Subject: [PATCH 03/26] Fix Scheduler_priority and CFS --- mentos/src/process/scheduler_algorithm.c | 2 -- prova.txt | 1 - 2 files changed, 3 deletions(-) delete mode 100644 prova.txt diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 6c27c1d..bc8537c 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -18,8 +18,6 @@ #include "process/wait.h" #include "process/scheduler.h" -int flag = 0; - /// @brief Updates task execution statistics. /// @param task the task to update. static void __update_task_statistics(task_struct *task); diff --git a/prova.txt b/prova.txt deleted file mode 100644 index 3b69572..0000000 --- a/prova.txt +++ /dev/null @@ -1 +0,0 @@ -siamo qui \ No newline at end of file From 40fac6e194bb094ef16e9f407676732cfee8fb68 Mon Sep 17 00:00:00 2001 From: tommyvilo <50549764+tommyvilo@users.noreply.github.com> Date: Sat, 18 Mar 2023 21:09:29 +0100 Subject: [PATCH 04/26] Add files via upload --- mentos/src/process/feedbackScheduler.c | 40 ++++++++++++++++++++++++ mentos/src/process/scheduler_algorithm.c | 8 +++++ 2 files changed, 48 insertions(+) create mode 100644 mentos/src/process/feedbackScheduler.c diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/feedbackScheduler.c new file mode 100644 index 0000000..700c480 --- /dev/null +++ b/mentos/src/process/feedbackScheduler.c @@ -0,0 +1,40 @@ +//#include "../fs/open.c" +//NB diocaro: dopo 2 ore ho scoperto che il bro ha ridefinito le open, le close, le write con la dicitura "sys_" davanti +//sta tutto in /mentos/src/fs/..... + +#include "fcntl.h" +#include "stdio.h" + + +int writeFeedback() +{ + mode_t mode = 000777; + char buffer[100 + 1]; + const char* name = "feedback.txt"; + + + int fptr = 0; + //fptr = sys_open("/../../../files/home/feedback.txt", O_WRONLY | O_CREAT | O_TRUNC , mode); + //fptr = sys_open("/../../../files/home/feedback.txt", O_RDONLY | O_CREAT | O_EXCL , mode); + //fptr = sys_open("/../../../files/home/feedback.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + fptr = sys_open(name, O_CREAT | O_WRONLY , S_IRUSR | S_IWUSR); + + if(fptr == -1){ + printf("suca"); + return 0; + } + + + // Reading up to MAX_READ bytes from STDIN. + ssize_t numRead = sys_read(fptr, buffer, 100); + + buffer[numRead] = '\0'; + printf("Input data: %s\n", buffer); + + + //write to file + //sys_write(fptr,"ciao",4); + //printf("suca"); //questo va + sys_close(fptr); //il problema è qui, se chiudiamo il file non arriviamo al login, se non chiudiamo il file invece proviamo a fare login ma non riusciamo perchè non riesce ad aprire passwd + return 1; +} \ No newline at end of file diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index bc8537c..115577e 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -18,6 +18,9 @@ #include "process/wait.h" #include "process/scheduler.h" +//scheduler feedback files +#include "feedbackScheduler.c" + /// @brief Updates task execution statistics. /// @param task the task to update. static void __update_task_statistics(task_struct *task); @@ -44,6 +47,8 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri if (list_head_size(&runqueue->curr->run_list) <= 1) { return runqueue->curr; } + + // Search for the next task (we do not start from the head, so INSIDE, skip the head). list_for_each_decl(it, &runqueue->curr->run_list) { @@ -59,8 +64,11 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri if (__is_periodic_task(entry) && skip_periodic) continue; // We have our next entry. + + int c = writeFeedback(); //prova di stampa return entry; } + return NULL; } From 25c8a1049bb17691d3cd5bff18d56d2d0306c7f9 Mon Sep 17 00:00:00 2001 From: "Enrico Fraccaroli (Galfurian)" Date: Tue, 21 Mar 2023 09:20:55 -0400 Subject: [PATCH 05/26] Use the right function for the kernel-side logging. --- mentos/src/process/feedbackScheduler.c | 51 ++++++++++++++------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/feedbackScheduler.c index 700c480..1bcc03c 100644 --- a/mentos/src/process/feedbackScheduler.c +++ b/mentos/src/process/feedbackScheduler.c @@ -4,37 +4,40 @@ #include "fcntl.h" #include "stdio.h" +#include "fs/vfs.h" +/// Size of the buffer. +#define BUFFER_SIZE 256 int writeFeedback() { - mode_t mode = 000777; - char buffer[100 + 1]; - const char* name = "feedback.txt"; - + mode_t mode = 000777; + char buffer[BUFFER_SIZE]; + const char *name = "feedback.txt"; - int fptr = 0; - //fptr = sys_open("/../../../files/home/feedback.txt", O_WRONLY | O_CREAT | O_TRUNC , mode); - //fptr = sys_open("/../../../files/home/feedback.txt", O_RDONLY | O_CREAT | O_EXCL , mode); - //fptr = sys_open("/../../../files/home/feedback.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - fptr = sys_open(name, O_CREAT | O_WRONLY , S_IRUSR | S_IWUSR); + // NOTE: You should check if the file exists, or create it, during the boot + // phase of the system. Choose a place where to put it, a location like + // `/var/scheduling_feedback.txt`. + vfs_file_t *file = vfs_open(name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); - if(fptr == -1){ - printf("suca"); - return 0; - } - + if (file == NULL) { + printf("Error: Failed to open feedback file."); + return 0; + } - // Reading up to MAX_READ bytes from STDIN. - ssize_t numRead = sys_read(fptr, buffer, 100); + // NOTE: You need also to save the offset where you are reading or writing + // the file. You are not using the simplified read() or write(), this one is + // a kernel-side function. + ssize_t numRead, offset = 0; - buffer[numRead] = '\0'; - printf("Input data: %s\n", buffer); + // Reading up to MAX_READ bytes from STDIN. + numRead = vfs_read(file, buffer, offset, BUFFER_SIZE); + buffer[numRead] = '\0'; + printf("Input data: %s\n", buffer); - - //write to file - //sys_write(fptr,"ciao",4); - //printf("suca"); //questo va - sys_close(fptr); //il problema è qui, se chiudiamo il file non arriviamo al login, se non chiudiamo il file invece proviamo a fare login ma non riusciamo perchè non riesce ad aprire passwd - return 1; + //write to file + //vfs_write(file,"ciao",4); + //printf("suca"); //questo va + vfs_close(file); //il problema è qui, se chiudiamo il file non arriviamo al login, se non chiudiamo il file invece proviamo a fare login ma non riusciamo perchè non riesce ad aprire passwd + return 1; } \ No newline at end of file From 0fcd132e8596fde203537f7b973b27903e7bc524 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Tue, 21 Mar 2023 18:49:28 +0100 Subject: [PATCH 06/26] fix and write on file --- mentos/src/process/feedbackScheduler.c | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/feedbackScheduler.c index 1bcc03c..968da60 100644 --- a/mentos/src/process/feedbackScheduler.c +++ b/mentos/src/process/feedbackScheduler.c @@ -1,5 +1,4 @@ //#include "../fs/open.c" -//NB diocaro: dopo 2 ore ho scoperto che il bro ha ridefinito le open, le close, le write con la dicitura "sys_" davanti //sta tutto in /mentos/src/fs/..... #include "fcntl.h" @@ -8,17 +7,20 @@ /// Size of the buffer. #define BUFFER_SIZE 256 +int count = 0; int writeFeedback() { + if(count == 300000) + { mode_t mode = 000777; char buffer[BUFFER_SIZE]; - const char *name = "feedback.txt"; + const char *name = "/home/user/feedback.txt"; // NOTE: You should check if the file exists, or create it, during the boot // phase of the system. Choose a place where to put it, a location like // `/var/scheduling_feedback.txt`. - vfs_file_t *file = vfs_open(name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); + vfs_file_t *file = vfs_open(name, O_RDWR, mode); if (file == NULL) { printf("Error: Failed to open feedback file."); @@ -28,16 +30,23 @@ int writeFeedback() // NOTE: You need also to save the offset where you are reading or writing // the file. You are not using the simplified read() or write(), this one is // a kernel-side function. - ssize_t numRead, offset = 0; + ssize_t offset = 0; + buffer[0] = 'P'; + buffer[1] = 'i'; + buffer[2] = 'd'; + buffer[3] = '\0'; + vfs_write(file, buffer, offset, 2); + offset = 0; // Reading up to MAX_READ bytes from STDIN. - numRead = vfs_read(file, buffer, offset, BUFFER_SIZE); - buffer[numRead] = '\0'; - printf("Input data: %s\n", buffer); + //numRead = vfs_read(file, buffer, offset, BUFFER_SIZE); + //buffer[numRead+1] = '5'; + printf("luca"); //write to file //vfs_write(file,"ciao",4); - //printf("suca"); //questo va - vfs_close(file); //il problema è qui, se chiudiamo il file non arriviamo al login, se non chiudiamo il file invece proviamo a fare login ma non riusciamo perchè non riesce ad aprire passwd - return 1; -} \ No newline at end of file + vfs_close(file); + } + count++; + return 1; +} \ No newline at end of file From 16a27a022faec8ed3ca4cc2ff03856072a024859 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Tue, 21 Mar 2023 18:50:45 +0100 Subject: [PATCH 07/26] file for statistics --- files/home/user/feedback.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 files/home/user/feedback.txt diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt new file mode 100644 index 0000000..6ee2a80 --- /dev/null +++ b/files/home/user/feedback.txt @@ -0,0 +1 @@ +wei \ No newline at end of file From fa153550718d7de935c64845d2b75bd0a0022d7f Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Sat, 25 Mar 2023 16:08:37 +0100 Subject: [PATCH 08/26] Defining general architecture of the task --- mentos/src/process/feedbackScheduler.c | 118 +++++++++++++++++++++---- 1 file changed, 100 insertions(+), 18 deletions(-) diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/feedbackScheduler.c index 968da60..5e45980 100644 --- a/mentos/src/process/feedbackScheduler.c +++ b/mentos/src/process/feedbackScheduler.c @@ -1,18 +1,94 @@ -//#include "../fs/open.c" -//sta tutto in /mentos/src/fs/..... +/// @file feedbackScheduler.c +/// @brief Manage the current PID for the scheduler feedback session +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. #include "fcntl.h" #include "stdio.h" #include "fs/vfs.h" -/// Size of the buffer. -#define BUFFER_SIZE 256 +//Variabili Globali +// Size of the buffer. +//#define BUFFER_SIZE 256 +#define MAX_STORAGE 50 int count = 0; -int writeFeedback() -{ - if(count == 300000) - { +int flag = 0; +int count2 = 0; +pid_t salvati[10] = {0}; +int i = 0; + + + +int countChar(char[]); + + +/* + PID 1 --> INIT + PID 2 --> KTHREADD +*/ + +/* +Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo processo da eseguire +*/ +void writeFeedback(pid_t pid, char name[]) +{ + int brake = 0; + + char start[] = "start"; + + //analizzo se nome del PID passato come argomento corrisponde al comando START + for(int j = 0 ; j < countChar(name) && brake == 0; j++) + { + if(start[j] != name[j]) + { + brake = 1; + } + } + + //Entra solo una volta, ovvero la prima volta che viene dato start + if(brake == 0 && count == MAX_STORAGE) + { + //RESET BUFFER + } + + //Se prima volta e' start bene, proseguiamo siccome brake e' zero, + //le successive brake NON zero ma count > 0 poiche start passato in precedenza + //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo + if(count != MAX_STORAGE && (count != 0 || brake == 0 )) + { + //REGISTRAZIONE PID IN BUFFER + } + + //QUI SE BUFFER PIENO SCRIVO SU FILE + //QUI SOTTO PROBABILMENTE QUASI TUTTO DA CANCELLARE + + if(pid != 1 && pid != 2) + { + flag = 1; + } + else if(i<10) + { + salvati[i] = pid; + i++; + } + + + if(count2%10 == 0) + { + if(flag == 1 && pid != 1 && pid != 2) + { + //printf("%s con %d caratteri\n",name,countChar(name)); + //printf("%s\n",start); + //printf("%i\n",pid); + //printf("Ho stampato: %s\n", name); + } + } + count2++; + + + //ROBA PER LAVORARE SUI FILE + /* mode_t mode = 000777; char buffer[BUFFER_SIZE]; const char *name = "/home/user/feedback.txt"; @@ -37,16 +113,22 @@ int writeFeedback() buffer[3] = '\0'; vfs_write(file, buffer, offset, 2); - offset = 0; - // Reading up to MAX_READ bytes from STDIN. - //numRead = vfs_read(file, buffer, offset, BUFFER_SIZE); - //buffer[numRead+1] = '5'; - printf("luca"); - //write to file //vfs_write(file,"ciao",4); vfs_close(file); - } - count++; - return 1; -} \ No newline at end of file + } + */ +} + + +/* +Funzione che conta caratteri del array di char passato +*/ + +int countChar(char name[]){ + int ct = 0; + while(name[ct]!='\0'){ + ct++; + } + return ct; +} \ No newline at end of file From bc5f3c2b2ae1502c6d300e142e8b9ba77cb68de2 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Sat, 25 Mar 2023 16:12:27 +0100 Subject: [PATCH 09/26] adding the pid's process' name to writeFeedback's arguments --- mentos/src/process/scheduler_algorithm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 115577e..9c0008f 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -64,8 +64,10 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri if (__is_periodic_task(entry) && skip_periodic) continue; // We have our next entry. - - int c = writeFeedback(); //prova di stampa + + //function to track the scheduler algorithm + writeFeedback(entry->pid, entry->name); + return entry; } From 62db896e48d80396a9aa2d849c7c98468cae5511 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 29 Mar 2023 18:58:55 +0200 Subject: [PATCH 10/26] File where PID are saved --- files/home/user/feedback.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt index 6ee2a80..51e8660 100644 --- a/files/home/user/feedback.txt +++ b/files/home/user/feedback.txt @@ -1 +1,16 @@ -wei \ No newline at end of file +--PID'S RECORDING SESSION-- + +PID NOME + + + + + + + + + + + + + From d193fa1ced1f200da8f9a6f6f993ff15f126aba5 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 29 Mar 2023 19:01:28 +0200 Subject: [PATCH 11/26] Update Task --- mentos/src/process/feedbackScheduler.c | 139 +++++++++++++------------ 1 file changed, 71 insertions(+), 68 deletions(-) diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/feedbackScheduler.c index 5e45980..76c8658 100644 --- a/mentos/src/process/feedbackScheduler.c +++ b/mentos/src/process/feedbackScheduler.c @@ -3,22 +3,36 @@ /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. +/* +HOW TO: +all'avvio di MentOS, usa comando start, verrai avvisato su terminale quando la sessione sarà terminata. +Puoi verificare i risultati a video lanciando il comando cat sul file del desktop (feedback.txt) + +es: +~ start +~ cat feedback.txt + +Questa e' una versione di prova in cui registriamo una brevissima sessione di soli 10 pid. +(Funzionante per ora solo con lo scheduler RR) +Istruzioni relative ai parametri della funzione start (che sono work in progress) sono in start.c +*/ + #include "fcntl.h" #include "stdio.h" #include "fs/vfs.h" +#include "string.h" + + +// Size of the buffer. +#define BUFFER_SIZE 256 + +#define MAX_SIZE_NAME 20 //Variabili Globali -// Size of the buffer. -//#define BUFFER_SIZE 256 -#define MAX_STORAGE 50 +#define MAX_STORAGE 10 int count = 0; - -int flag = 0; -int count2 = 0; -pid_t salvati[10] = {0}; -int i = 0; - - +pid_t PID_BUFFER[MAX_STORAGE] = {0}; +char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; int countChar(char[]); @@ -38,86 +52,75 @@ void writeFeedback(pid_t pid, char name[]) char start[] = "start"; //analizzo se nome del PID passato come argomento corrisponde al comando START - for(int j = 0 ; j < countChar(name) && brake == 0; j++) + for(int i = 0 ; i < countChar(name) && brake == 0; i++) { - if(start[j] != name[j]) + if(start[i] != name[i]) { brake = 1; } } - //Entra solo una volta, ovvero la prima volta che viene dato start - if(brake == 0 && count == MAX_STORAGE) + //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) + if(brake == 0 && count == MAX_STORAGE-1) { //RESET BUFFER + for(int i = 0; i < MAX_STORAGE; i++) + { + PID_BUFFER[i] = 0; + } + count = 0; + } //Se prima volta e' start bene, proseguiamo siccome brake e' zero, //le successive brake NON zero ma count > 0 poiche start passato in precedenza //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if(count != MAX_STORAGE && (count != 0 || brake == 0 )) + if(count != MAX_STORAGE-1 && (count != 0 || brake == 0 )) { //REGISTRAZIONE PID IN BUFFER + PID_BUFFER[count] = pid; + strcpy(PID_NAME[count],name); + count++; } //QUI SE BUFFER PIENO SCRIVO SU FILE - //QUI SOTTO PROBABILMENTE QUASI TUTTO DA CANCELLARE - if(pid != 1 && pid != 2) + if(count == MAX_STORAGE-1) { - flag = 1; - } - else if(i<10) - { - salvati[i] = pid; - i++; + mode_t mode = 000777; + char buffer[BUFFER_SIZE]; + const char *namef = "/home/user/feedback.txt"; + ssize_t offset = sizeof(char)*38; + char temp[6]; //max PID 99999 + + // NOTE: You should check if the file exists, or create it, during the boot + // phase of the system. Choose a place where to put it, a location like + // `/var/scheduling_feedback.txt`. + vfs_file_t *file = vfs_open(namef, O_RDWR, mode); + + if (file == NULL) { + printf("Error: Failed to open feedback file."); + } + + for(int i=0; i < MAX_STORAGE; i++) + { + itoa(temp,PID_BUFFER[i],10); + offset += vfs_write(file, temp, offset, sizeof(char)*countChar(temp)); + offset += vfs_write(file, " ", offset, sizeof(char)*3); + offset += vfs_write(file, PID_NAME[i], offset, sizeof(char)*countChar(PID_NAME[i])); + offset += vfs_write(file, "\n", offset, sizeof(char)); + //ripristino array temp + for(int j=0; j < 5; j++) + { + temp[j] = 0; + } + + } + printf("End Recording\n"); + vfs_close(file); + count = 0; } - - if(count2%10 == 0) - { - if(flag == 1 && pid != 1 && pid != 2) - { - //printf("%s con %d caratteri\n",name,countChar(name)); - //printf("%s\n",start); - //printf("%i\n",pid); - //printf("Ho stampato: %s\n", name); - } - } - count2++; - - - //ROBA PER LAVORARE SUI FILE - /* - mode_t mode = 000777; - char buffer[BUFFER_SIZE]; - const char *name = "/home/user/feedback.txt"; - - // NOTE: You should check if the file exists, or create it, during the boot - // phase of the system. Choose a place where to put it, a location like - // `/var/scheduling_feedback.txt`. - vfs_file_t *file = vfs_open(name, O_RDWR, mode); - - if (file == NULL) { - printf("Error: Failed to open feedback file."); - return 0; - } - - // NOTE: You need also to save the offset where you are reading or writing - // the file. You are not using the simplified read() or write(), this one is - // a kernel-side function. - ssize_t offset = 0; - buffer[0] = 'P'; - buffer[1] = 'i'; - buffer[2] = 'd'; - buffer[3] = '\0'; - vfs_write(file, buffer, offset, 2); - - //write to file - //vfs_write(file,"ciao",4); - vfs_close(file); - } - */ } From 913deff2d4002e28c418da3eb2f88c19e57616a8 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 29 Mar 2023 19:02:23 +0200 Subject: [PATCH 12/26] add start command --- programs/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 5e36d4c..82f7847 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -69,6 +69,11 @@ set(PROGRAMS poweroff.c rm.c shell.c + + + start.c + + uname.c cat.c echo.c From e6c733a881fd13581df16afb671372c23beea0bb Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 29 Mar 2023 19:03:48 +0200 Subject: [PATCH 13/26] Function to start the session of PID's recording --- programs/start.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 programs/start.c diff --git a/programs/start.c b/programs/start.c new file mode 100644 index 0000000..63b0073 --- /dev/null +++ b/programs/start.c @@ -0,0 +1,26 @@ +/// @file start.c +/// @brief Start the scheduler feedback session +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. +#include +#include +#include + + +/* +Start, funzionamento: L'utente scrivendo start da shell (interna a MentOS) avviera' la registrazione di un numero +fissato di PID. +Tre tipologie di parametri/flag accettati dalla start: + + -start --> avvia la recording senza alcun parametro (ci aspettiamo file con PID 1 e 2 alternati) + -start -p --> avvia la recording utilizzando anche la funzione fork, cosi da far vedere nel file PID diversi (almeno inizialmente) + -start -f file.c --> avvia la recording lanciando prima il file passato come parametro + +*/ + +int main() +{ + //N.B va implementato il reset della struttura che alloca i dati(PID) + printf("Avvio Recording\n"); + return 0; +} \ No newline at end of file From fc36a1dad0375d241c46b9ea1d2f704d648ba957 Mon Sep 17 00:00:00 2001 From: "Enrico Fraccaroli (Galfurian)" Date: Fri, 31 Mar 2023 09:55:11 -0400 Subject: [PATCH 14/26] Update scheduling feedback system. --- mentos/CMakeLists.txt | 2 + mentos/inc/io/proc_modules.h | 2 + mentos/inc/process/scheduler_feedback.h | 13 ++++ mentos/src/io/proc_feedback.c | 50 ++++++++++++ mentos/src/kernel.c | 19 +++++ mentos/src/process/scheduler_algorithm.c | 4 +- ...edbackScheduler.c => scheduler_feedback.c} | 76 +++++++++---------- 7 files changed, 125 insertions(+), 41 deletions(-) create mode 100644 mentos/inc/process/scheduler_feedback.h create mode 100644 mentos/src/io/proc_feedback.c rename mentos/src/process/{feedbackScheduler.c => scheduler_feedback.c} (72%) diff --git a/mentos/CMakeLists.txt b/mentos/CMakeLists.txt index af565fa..13fc177 100644 --- a/mentos/CMakeLists.txt +++ b/mentos/CMakeLists.txt @@ -127,6 +127,7 @@ set(KERNEL_SOURCES src/io/debug.c src/io/proc_video.c src/io/proc_running.c + src/io/proc_feedback.c src/io/proc_system.c src/io/vga/vga.c src/ipc/msg.c @@ -166,6 +167,7 @@ set(KERNEL_SOURCES src/descriptor_tables/tss.c src/descriptor_tables/tss.S src/process/scheduler_algorithm.c + src/process/scheduler_feedback.c src/process/scheduler.c src/process/process.c src/process/wait.c diff --git a/mentos/inc/io/proc_modules.h b/mentos/inc/io/proc_modules.h index 123edc8..5712a5f 100644 --- a/mentos/inc/io/proc_modules.h +++ b/mentos/inc/io/proc_modules.h @@ -14,3 +14,5 @@ int procv_module_init(); /// @brief Initialize the procfs system files. /// @return 0 on success, 1 on failure. int procs_module_init(); + +int procfb_module_init(); diff --git a/mentos/inc/process/scheduler_feedback.h b/mentos/inc/process/scheduler_feedback.h new file mode 100644 index 0000000..853bb39 --- /dev/null +++ b/mentos/inc/process/scheduler_feedback.h @@ -0,0 +1,13 @@ +/// @file scheduler_feedback.h +/// @author Enrico Fraccaroli (enry.frak@gmail.com) +/// @brief + +#pragma once + +#include "sys/types.h" + +void writeFeedback(pid_t pid, char name[]); + +/// @brief Initialize the scheduler feedback system. +/// @return 1 on success, 0 on failure. +int scheduler_feedback_init(); diff --git a/mentos/src/io/proc_feedback.c b/mentos/src/io/proc_feedback.c new file mode 100644 index 0000000..f2b6c3c --- /dev/null +++ b/mentos/src/io/proc_feedback.c @@ -0,0 +1,50 @@ +/// @file proc_feedback.c +/// @brief Contains callbacks for procfs system files. +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#include "fs/procfs.h" +#include "process/process.h" +#include "sys/errno.h" +#include "io/debug.h" +#include "string.h" + +static ssize_t procfb_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte) +{ + return 0; +} + +/// Filesystem general operations. +static vfs_sys_operations_t procfb_sys_operations = { + .mkdir_f = NULL, + .rmdir_f = NULL, + .stat_f = NULL +}; + +/// Filesystem file operations. +static vfs_file_operations_t procfb_fs_operations = { + .open_f = NULL, + .unlink_f = NULL, + .close_f = NULL, + .read_f = procfb_read, + .write_f = NULL, + .lseek_f = NULL, + .stat_f = NULL, + .ioctl_f = NULL, + .getdents_f = NULL +}; + +int procfb_module_init() +{ + // Create the file. + proc_dir_entry_t *file = proc_create_entry("feedback", NULL); + if (file == NULL) { + pr_err("Cannot create `/proc/feedback`.\n"); + return 1; + } + pr_debug("Created `/proc/feedback` (%p)\n", file); + // Set the specific operations. + file->sys_operations = &procfb_sys_operations; + file->fs_operations = &procfb_fs_operations; + return 0; +} diff --git a/mentos/src/kernel.c b/mentos/src/kernel.c index a051c1e..abe8ef7 100644 --- a/mentos/src/kernel.c +++ b/mentos/src/kernel.c @@ -31,6 +31,7 @@ #include "drivers/keyboard/keymap.h" #include "drivers/ps2.h" #include "process/scheduler.h" +#include "process/scheduler_feedback.h" #include "hardware/timer.h" #include "fs/vfs.h" #include "devices/fpu.h" @@ -344,6 +345,24 @@ int kmain(boot_info_t *boot_informations) } print_ok(); + //========================================================================== + pr_notice("Initialize scheduler feedback system...\n"); + printf("Initialize scheduler feedback system..."); + if (!scheduler_feedback_init()) { + print_fail(); + return 1; + } + print_ok(); + + //========================================================================== + pr_notice("Initialize scheduler feedback system (2)...\n"); + printf("Initialize scheduler feedback system (2)..."); + if (procfb_module_init()) { + print_fail(); + return 1; + } + print_ok(); + //========================================================================== pr_notice("Creating init process...\n"); printf("Creating init process..."); diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 9c0008f..0bed6b9 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -17,9 +17,7 @@ #include "klib/list_head.h" #include "process/wait.h" #include "process/scheduler.h" - -//scheduler feedback files -#include "feedbackScheduler.c" +#include "process/scheduler_feedback.h" /// @brief Updates task execution statistics. /// @param task the task to update. diff --git a/mentos/src/process/feedbackScheduler.c b/mentos/src/process/scheduler_feedback.c similarity index 72% rename from mentos/src/process/feedbackScheduler.c rename to mentos/src/process/scheduler_feedback.c index 76c8658..01e6aa1 100644 --- a/mentos/src/process/feedbackScheduler.c +++ b/mentos/src/process/scheduler_feedback.c @@ -1,4 +1,4 @@ -/// @file feedbackScheduler.c +/// @file scheduler_feedback.c /// @brief Manage the current PID for the scheduler feedback session /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. @@ -17,11 +17,14 @@ Questa e' una versione di prova in cui registriamo una brevissima sessione di so Istruzioni relative ai parametri della funzione start (che sono work in progress) sono in start.c */ +#include "process/scheduler_feedback.h" + #include "fcntl.h" #include "stdio.h" #include "fs/vfs.h" #include "string.h" +#define FEEDBACK_FILENAME "/home/user/feedback.txt" // Size of the buffer. #define BUFFER_SIZE 256 @@ -30,13 +33,12 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress //Variabili Globali #define MAX_STORAGE 10 -int count = 0; -pid_t PID_BUFFER[MAX_STORAGE] = {0}; +int count = 0; +pid_t PID_BUFFER[MAX_STORAGE] = { 0 }; char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; int countChar(char[]); - /* PID 1 --> INIT PID 2 --> KTHREADD @@ -46,51 +48,44 @@ int countChar(char[]); Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo processo da eseguire */ void writeFeedback(pid_t pid, char name[]) -{ +{ int brake = 0; char start[] = "start"; //analizzo se nome del PID passato come argomento corrisponde al comando START - for(int i = 0 ; i < countChar(name) && brake == 0; i++) - { - if(start[i] != name[i]) - { + for (int i = 0; i < countChar(name) && brake == 0; i++) { + if (start[i] != name[i]) { brake = 1; } } //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) - if(brake == 0 && count == MAX_STORAGE-1) - { + if (brake == 0 && count == MAX_STORAGE - 1) { //RESET BUFFER - for(int i = 0; i < MAX_STORAGE; i++) - { + for (int i = 0; i < MAX_STORAGE; i++) { PID_BUFFER[i] = 0; } count = 0; - } - //Se prima volta e' start bene, proseguiamo siccome brake e' zero, + //Se prima volta e' start bene, proseguiamo siccome brake e' zero, //le successive brake NON zero ma count > 0 poiche start passato in precedenza //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if(count != MAX_STORAGE-1 && (count != 0 || brake == 0 )) - { + if (count != MAX_STORAGE - 1 && (count != 0 || brake == 0)) { //REGISTRAZIONE PID IN BUFFER PID_BUFFER[count] = pid; - strcpy(PID_NAME[count],name); + strcpy(PID_NAME[count], name); count++; } //QUI SE BUFFER PIENO SCRIVO SU FILE - if(count == MAX_STORAGE-1) - { + if (count == MAX_STORAGE - 1) { mode_t mode = 000777; char buffer[BUFFER_SIZE]; const char *namef = "/home/user/feedback.txt"; - ssize_t offset = sizeof(char)*38; + ssize_t offset = sizeof(char) * 38; char temp[6]; //max PID 99999 // NOTE: You should check if the file exists, or create it, during the boot @@ -102,36 +97,41 @@ void writeFeedback(pid_t pid, char name[]) printf("Error: Failed to open feedback file."); } - for(int i=0; i < MAX_STORAGE; i++) - { - itoa(temp,PID_BUFFER[i],10); - offset += vfs_write(file, temp, offset, sizeof(char)*countChar(temp)); - offset += vfs_write(file, " ", offset, sizeof(char)*3); - offset += vfs_write(file, PID_NAME[i], offset, sizeof(char)*countChar(PID_NAME[i])); + for (int i = 0; i < MAX_STORAGE; i++) { + itoa(temp, PID_BUFFER[i], 10); + offset += vfs_write(file, temp, offset, sizeof(char) * countChar(temp)); + offset += vfs_write(file, " ", offset, sizeof(char) * 3); + offset += vfs_write(file, PID_NAME[i], offset, sizeof(char) * countChar(PID_NAME[i])); offset += vfs_write(file, "\n", offset, sizeof(char)); //ripristino array temp - for(int j=0; j < 5; j++) - { + for (int j = 0; j < 5; j++) { temp[j] = 0; } - } printf("End Recording\n"); - vfs_close(file); + vfs_close(file); count = 0; } - -} - +} /* Funzione che conta caratteri del array di char passato */ -int countChar(char name[]){ - int ct = 0; - while(name[ct]!='\0'){ +int countChar(char name[]) +{ + int ct = 0; + while (name[ct] != '\0') { ct++; } return ct; -} \ No newline at end of file +} + +int scheduler_feedback_init() +{ + // + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + // + vfs_file_t *feedback = vfs_creat(FEEDBACK_FILENAME, mode); + return 1; +} From 2a123f6986c39886be1f2fa4639305b50ae04f9e Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Fri, 31 Mar 2023 18:25:04 +0200 Subject: [PATCH 15/26] Bug Fixing start scheduler feedback --- files/home/user/feedback.txt | 2 +- mentos/src/process/scheduler_feedback.c | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt index 51e8660..d767e30 100644 --- a/files/home/user/feedback.txt +++ b/files/home/user/feedback.txt @@ -1,7 +1,7 @@ --PID'S RECORDING SESSION-- PID NOME - + diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index 01e6aa1..a73e14f 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -36,7 +36,7 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress int count = 0; pid_t PID_BUFFER[MAX_STORAGE] = { 0 }; char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; - +pid_t oldPid = -1; int countChar(char[]); /* @@ -49,19 +49,26 @@ Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo */ void writeFeedback(pid_t pid, char name[]) { + int brake = 0; - char start[] = "start"; + //analizzo se nome del PID passato come argomento corrisponde al comando START for (int i = 0; i < countChar(name) && brake == 0; i++) { - if (start[i] != name[i]) { + if ((start[i] != name[i]) || oldPid==pid ) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po brake = 1; } } - //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) - if (brake == 0 && count == MAX_STORAGE - 1) { + //questo ci serve per andare a salvare il pid di una nuova start lanciata da terminale + //il primissimo start viene detectato OR detecta uno start con un pid nuovo + if((oldPid==-1 && brake == 0) || (oldPid!=-1 && brake == 0 && oldPid!=pid) ) + oldPid = pid; + + //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) e richiesta una nuova + if (brake == 0 && count == MAX_STORAGE) { + //RESET BUFFER for (int i = 0; i < MAX_STORAGE; i++) { PID_BUFFER[i] = 0; @@ -69,10 +76,12 @@ void writeFeedback(pid_t pid, char name[]) count = 0; } + + //Se prima volta e' start bene, proseguiamo siccome brake e' zero, //le successive brake NON zero ma count > 0 poiche start passato in precedenza //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if (count != MAX_STORAGE - 1 && (count != 0 || brake == 0)) { + if (count != MAX_STORAGE && (count != 0 || brake == 0)) { //REGISTRAZIONE PID IN BUFFER PID_BUFFER[count] = pid; strcpy(PID_NAME[count], name); @@ -81,7 +90,7 @@ void writeFeedback(pid_t pid, char name[]) //QUI SE BUFFER PIENO SCRIVO SU FILE - if (count == MAX_STORAGE - 1) { + if (count == MAX_STORAGE) { mode_t mode = 000777; char buffer[BUFFER_SIZE]; const char *namef = "/home/user/feedback.txt"; From c19da29ab71df5415a11a43709b9fde1b786d14d Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Wed, 5 Apr 2023 09:21:22 +0200 Subject: [PATCH 16/26] Bug Fixing and add a new feature --- files/home/user/feedback.txt | 17 ++--- mentos/inc/process/scheduler_feedback.h | 2 +- mentos/src/process/scheduler_algorithm.c | 9 ++- mentos/src/process/scheduler_feedback.c | 92 ++++++++++++++++++++---- programs/CMakeLists.txt | 6 +- programs/start.c | 41 ++++++++++- 6 files changed, 131 insertions(+), 36 deletions(-) diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt index d767e30..ee9ae06 100644 --- a/files/home/user/feedback.txt +++ b/files/home/user/feedback.txt @@ -1,16 +1,7 @@ --PID'S RECORDING SESSION-- -PID NOME - - - - - - - - - - - - +MODE: + +PID PRIO NAME + \ No newline at end of file diff --git a/mentos/inc/process/scheduler_feedback.h b/mentos/inc/process/scheduler_feedback.h index 853bb39..b42c4a3 100644 --- a/mentos/inc/process/scheduler_feedback.h +++ b/mentos/inc/process/scheduler_feedback.h @@ -6,7 +6,7 @@ #include "sys/types.h" -void writeFeedback(pid_t pid, char name[]); +void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio); /// @brief Initialize the scheduler feedback system. /// @return 1 on success, 0 on failure. diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 0bed6b9..33f002a 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -64,7 +64,7 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri // We have our next entry. //function to track the scheduler algorithm - writeFeedback(entry->pid, entry->name); + writeFeedback(entry->pid, entry->name, entry->parent->pid, 1, (entry->se).prio); return entry; } @@ -127,6 +127,10 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski next = entry; // scambio il prossimo processo con quello a priorità piu bassa trovato } } + + //function to track the scheduler algorithm + writeFeedback(next->pid, next->name, next->parent->pid, 2, (next->se).prio); + return next; #else return __scheduler_rr(runqueue, skip_periodic); @@ -173,6 +177,9 @@ static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_per next = entry; // scambio il prossimo processo con quello a priorità piu bassa trovato } } + //function to track the scheduler algorithm + writeFeedback(next->pid, next->name, next->parent->pid, 3, (next->se).prio); + return next; #else return __scheduler_rr(runqueue, skip_periodic); diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index a73e14f..2e1648f 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -35,9 +35,13 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress #define MAX_STORAGE 10 int count = 0; pid_t PID_BUFFER[MAX_STORAGE] = { 0 }; +int PID_PRIO[MAX_STORAGE] = { 0 }; char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; pid_t oldPid = -1; +ssize_t offset; +int err = 1; int countChar(char[]); +void wipe(); /* PID 1 --> INIT @@ -47,24 +51,26 @@ int countChar(char[]); /* Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo processo da eseguire */ -void writeFeedback(pid_t pid, char name[]) +void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) { - - int brake = 0; char start[] = "start"; + int brake = 0; - //analizzo se nome del PID passato come argomento corrisponde al comando START for (int i = 0; i < countChar(name) && brake == 0; i++) { - if ((start[i] != name[i]) || oldPid==pid ) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po + + if ((start[i] != name[i]) || oldPid==pid || oldPid==padre || countChar(name) != countChar(start) ) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po brake = 1; } } - + //questo ci serve per andare a salvare il pid di una nuova start lanciata da terminale - //il primissimo start viene detectato OR detecta uno start con un pid nuovo - if((oldPid==-1 && brake == 0) || (oldPid!=-1 && brake == 0 && oldPid!=pid) ) + //il primissimo start viene detectato OR detecta uno start con un pid nuovo MA con mio padre diverso dal creatore della sessione attuale o finita (oldPid) + if((oldPid==-1 && brake == 0) || (oldPid!=-1 && brake == 0 && oldPid!=pid && oldPid!=padre) ){ + oldPid = pid; + + } //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) e richiesta una nuova if (brake == 0 && count == MAX_STORAGE) { @@ -72,7 +78,9 @@ void writeFeedback(pid_t pid, char name[]) //RESET BUFFER for (int i = 0; i < MAX_STORAGE; i++) { PID_BUFFER[i] = 0; + PID_PRIO[i] = 0; } + err = 1; count = 0; } @@ -81,9 +89,10 @@ void writeFeedback(pid_t pid, char name[]) //Se prima volta e' start bene, proseguiamo siccome brake e' zero, //le successive brake NON zero ma count > 0 poiche start passato in precedenza //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if (count != MAX_STORAGE && (count != 0 || brake == 0)) { - //REGISTRAZIONE PID IN BUFFER + if (count != MAX_STORAGE && (count != 0 || brake == 0 )) { + //REGISTRAZIONE PID IN BUFFER in modalita start SENZA parametri PID_BUFFER[count] = pid; + PID_PRIO[count] = prio; strcpy(PID_NAME[count], name); count++; } @@ -91,25 +100,57 @@ void writeFeedback(pid_t pid, char name[]) //QUI SE BUFFER PIENO SCRIVO SU FILE if (count == MAX_STORAGE) { - mode_t mode = 000777; + mode_t flag = 000777; char buffer[BUFFER_SIZE]; const char *namef = "/home/user/feedback.txt"; - ssize_t offset = sizeof(char) * 38; + offset = sizeof(char) * 34; //PER SCRITTURA MODALITA char temp[6]; //max PID 99999 + char temp_prio[4]; + char rr[] = "ROUND ROBIN\n"; + char priority[] = "HIGH PRIORITY FIRST\n"; + char cfs[] = "FAIR SHARE\n"; + char testo[] = "\nPID PRIO NAME\n"; // NOTE: You should check if the file exists, or create it, during the boot // phase of the system. Choose a place where to put it, a location like // `/var/scheduling_feedback.txt`. - vfs_file_t *file = vfs_open(namef, O_RDWR, mode); + vfs_file_t *file = vfs_open(namef, O_RDWR, flag); if (file == NULL) { printf("Error: Failed to open feedback file."); } + if(mode == 1){ + + offset += vfs_write(file, " ", offset, sizeof(char)); + offset += vfs_write(file, rr, offset, sizeof(char)*countChar(rr)); + } + else if(mode == 2){ + + offset += vfs_write(file, " ", offset, sizeof(char)); + offset += vfs_write(file, priority, offset, sizeof(char)*countChar(priority)); + } + else{ + + offset += vfs_write(file, " ", offset, sizeof(char)); + offset += vfs_write(file, cfs, offset, sizeof(char)*countChar(cfs)); + } + + /* + offset += vfs_write(file, "\n", offset, sizeof(char)); + offset += vfs_write(file, "\n", offset, sizeof(char)); + offset += sizeof(char)* (13);*/ + + offset += vfs_write(file, testo, offset, sizeof(char)*countChar(testo)); + + for (int i = 0; i < MAX_STORAGE; i++) { itoa(temp, PID_BUFFER[i], 10); + itoa(temp_prio, PID_PRIO[i], 10); offset += vfs_write(file, temp, offset, sizeof(char) * countChar(temp)); offset += vfs_write(file, " ", offset, sizeof(char) * 3); + offset += vfs_write(file, temp_prio, offset, sizeof(char) * countChar(temp_prio)); + offset += vfs_write(file, " ", offset, sizeof(char) * 3); offset += vfs_write(file, PID_NAME[i], offset, sizeof(char) * countChar(PID_NAME[i])); offset += vfs_write(file, "\n", offset, sizeof(char)); //ripristino array temp @@ -117,12 +158,35 @@ void writeFeedback(pid_t pid, char name[]) temp[j] = 0; } } - printf("End Recording\n"); vfs_close(file); count = 0; } + + if(!strcmp(name,"error") && err){ + + wipe(); + err--; + } } +/* +Funzione che pulisce la sessione +*/ +void wipe() +{ + mode_t flag = 000777; + const char *namef = "/home/user/feedback.txt"; + vfs_file_t *file = vfs_open(namef, O_RDWR, flag); + count = 0; + + for(int i = 34*sizeof(char); i < offset; i+=sizeof(char)){ + + vfs_write(file, " ", i, sizeof(char)); + } + vfs_close(file); +} + + /* Funzione che conta caratteri del array di char passato */ diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 82f7847..a0e1504 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -69,11 +69,7 @@ set(PROGRAMS poweroff.c rm.c shell.c - - - start.c - - + start.c uname.c cat.c echo.c diff --git a/programs/start.c b/programs/start.c index 63b0073..48b9302 100644 --- a/programs/start.c +++ b/programs/start.c @@ -6,6 +6,9 @@ #include #include +#include +#include +#include /* Start, funzionamento: L'utente scrivendo start da shell (interna a MentOS) avviera' la registrazione di un numero @@ -18,9 +21,43 @@ Tre tipologie di parametri/flag accettati dalla start: */ -int main() +//int clonaccio(int, char *); + +int main(int argc, char *argv[]) { //N.B va implementato il reset della struttura che alloca i dati(PID) - printf("Avvio Recording\n"); + + //aka utente ha inserito un comando start con flag errati + if(argc > 1 && (strcmp(argv[1],"-p") || strcmp(argv[1],"-f"))){ + printf("start has no command '%s'\n\n", argv[1]); + execl("../../bin/startERR","error", NULL, NULL); + return -1; + } + + printf("Start Recording\n"); + + if(argc == 2){ + + if(!(strcmp(argv[1],"-p"))){ + + for(int i = 0; i < 5; i++){ + + if(fork()==0){ + + //volendo no fork qua, ma solo chiamata a t_fork 5 con una exec + //execl("../../bin/start0", "figlio", NULL, NULL); + exit(1); + + } + + } + + for(int i = 0; i < 5; i++){ + wait(NULL); + } + + } + } + printf("End Recording\n"); return 0; } \ No newline at end of file From 8e9b86476c0c7b87f0a8ea8d808a9d1f241f4e08 Mon Sep 17 00:00:00 2001 From: tommyvilo Date: Wed, 5 Apr 2023 09:40:12 +0200 Subject: [PATCH 17/26] Changing chmod permission file --- files/home/user/feedback.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 files/home/user/feedback.txt diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt old mode 100644 new mode 100755 From 84fbca5798a770613d4005da2a8b3d1d8853399c Mon Sep 17 00:00:00 2001 From: tommyvilo Date: Wed, 5 Apr 2023 17:49:09 +0200 Subject: [PATCH 18/26] Bug fixing and detecting wrong parameters --- files/home/user/feedback.txt | 0 files/usr/share/man/start.man | 12 +++ mentos/src/process/scheduler_feedback.c | 17 ++-- programs/CMakeLists.txt | 3 +- programs/start.c | 102 +++++++++++++++++------- programs/startERR.c | 5 ++ programs/tests/CMakeLists.txt | 3 + programs/tests/myProg.c | 7 ++ 8 files changed, 109 insertions(+), 40 deletions(-) mode change 100755 => 100644 files/home/user/feedback.txt create mode 100644 files/usr/share/man/start.man create mode 100644 programs/startERR.c create mode 100644 programs/tests/myProg.c diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt old mode 100755 new mode 100644 diff --git a/files/usr/share/man/start.man b/files/usr/share/man/start.man new file mode 100644 index 0000000..d9995ba --- /dev/null +++ b/files/usr/share/man/start.man @@ -0,0 +1,12 @@ +SYNOPSIS + start [OPTIONS] [FILE] + +DESCRIPTION + Start a recording session aimed at displaying an ordered list of 50 items + containing information about the processes that the CPU has just processed. + + +OPTIONS + -h: shows command help. //non funziona per ora lol + -p: start the session with generated children + -f [FILE]: start the session launching a specified program \ No newline at end of file diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index 2e1648f..d62798c 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -72,18 +72,7 @@ void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) } - //Entra solo una volta, dopo aver finito la sessione (riempito il buffer) e richiesta una nuova - if (brake == 0 && count == MAX_STORAGE) { - - //RESET BUFFER - for (int i = 0; i < MAX_STORAGE; i++) { - PID_BUFFER[i] = 0; - PID_PRIO[i] = 0; - } - err = 1; - count = 0; - } - + //Se prima volta e' start bene, proseguiamo siccome brake e' zero, @@ -160,6 +149,7 @@ void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) } vfs_close(file); count = 0; + err = 1; } if(!strcmp(name,"error") && err){ @@ -178,9 +168,12 @@ void wipe() const char *namef = "/home/user/feedback.txt"; vfs_file_t *file = vfs_open(namef, O_RDWR, flag); count = 0; + offset += sizeof(char)*100; //overkill for(int i = 34*sizeof(char); i < offset; i+=sizeof(char)){ + //NB: se riusciamo a creare un file nostro e scrivere non solo sugli spazi + //questo costrutto non funziona, del sovrascrivere finche count non e' zero vfs_write(file, " ", i, sizeof(char)); } vfs_close(file); diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index a0e1504..2395326 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -69,7 +69,8 @@ set(PROGRAMS poweroff.c rm.c shell.c - start.c + start.c + startERR.c uname.c cat.c echo.c diff --git a/programs/start.c b/programs/start.c index 48b9302..e4244ec 100644 --- a/programs/start.c +++ b/programs/start.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Start, funzionamento: L'utente scrivendo start da shell (interna a MentOS) avviera' la registrazione di un numero @@ -25,39 +26,86 @@ Tre tipologie di parametri/flag accettati dalla start: int main(int argc, char *argv[]) { - //N.B va implementato il reset della struttura che alloca i dati(PID) - - //aka utente ha inserito un comando start con flag errati - if(argc > 1 && (strcmp(argv[1],"-p") || strcmp(argv[1],"-f"))){ - printf("start has no command '%s'\n\n", argv[1]); - execl("../../bin/startERR","error", NULL, NULL); - return -1; + int flag = 0; + + if(argc == 1){ + printf("Start Recording\n"); + printf("End Recording\n"); + return 0; } + else if(argc == 2 && !(strcmp(argv[1],"-p"))){ - printf("Start Recording\n"); + printf("Start Recording\n"); - if(argc == 2){ + for(int i = 0; i < 5; i++){ - if(!(strcmp(argv[1],"-p"))){ - - for(int i = 0; i < 5; i++){ - - if(fork()==0){ - - //volendo no fork qua, ma solo chiamata a t_fork 5 con una exec - //execl("../../bin/start0", "figlio", NULL, NULL); - exit(1); - - } - - } - - for(int i = 0; i < 5; i++){ - wait(NULL); + if(fork()==0){ + exit(1); } } + + for(int i = 0; i < 5; i++){ + wait(NULL); + } + + printf("End Recording\n"); + return 0; + + } + else if( argc==3 && !strcmp(argv[1],"-f") ){ + + char destination[] = "../../bin/tests/"; + strcat(destination,argv[2]); + if(fork()==0){ + flag = execl(destination, "customProgram", NULL, NULL); + if(flag == -1){ + execl("../../bin/startERR","error", NULL, NULL); + } + } + wait(NULL); + + /* + if(flag != -1) + { + printf("Start Recording\n"); + printf("End Recording\n"); + }*/ + + int fd; + mode_t flag1 = 000111; + char destination1[] = "../../bin/tests/"; + strcat(destination1,argv[2]); + fd = open(destination1, S_IRUSR, flag1); + if( fd != -1 ){ + printf("Start Recording\n"); + printf("End Recording\n"); + close(fd); + } + else{ + printf("start: file '%s' not found!\n\n", destination1); + } + + + return 0; } - printf("End Recording\n"); - return 0; + + if(argc != 1){ + //se arriviamo qui, significa che sono stati passati parametri errati + if(strcmp(argv[1],"-f")){ + printf("start: start has no command '%s'\n\n", argv[1]); + execl("../../bin/startERR","error", NULL, NULL); + } + else{ + printf("start: missing FILE for OPTION '%s'\n\n", argv[1]); + execl("../../bin/startERR","error", NULL, NULL); + } + } + + + /* + if(argc > 1 && (strcmp(argv[1],"-p") && strcmp(argv[1],"-f"))){ //da rafforzare + + }*/ + } \ No newline at end of file diff --git a/programs/startERR.c b/programs/startERR.c new file mode 100644 index 0000000..ebe8be1 --- /dev/null +++ b/programs/startERR.c @@ -0,0 +1,5 @@ + +int main(void) +{ + return -1; +} \ No newline at end of file diff --git a/programs/tests/CMakeLists.txt b/programs/tests/CMakeLists.txt index 22d2855..e961136 100644 --- a/programs/tests/CMakeLists.txt +++ b/programs/tests/CMakeLists.txt @@ -85,6 +85,9 @@ set(TESTS t_kill.c t_itimer.c t_gid.c + + # Testing my program + myProg.c ) foreach(TEST ${TESTS}) diff --git a/programs/tests/myProg.c b/programs/tests/myProg.c new file mode 100644 index 0000000..598de09 --- /dev/null +++ b/programs/tests/myProg.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + printf("File di test\n"); + return 0; +} From 998ffd2c29c589b042d9c76ed8e788025596fef5 Mon Sep 17 00:00:00 2001 From: emmekappaa Date: Fri, 7 Apr 2023 23:01:29 +0200 Subject: [PATCH 19/26] Implemented Statistics --- mentos/src/fs/vfs.c | 2 +- mentos/src/process/scheduler_algorithm.c | 107 ++++++++++++++++++++--- mentos/src/process/scheduler_feedback.c | 83 ++++++++---------- 3 files changed, 131 insertions(+), 61 deletions(-) diff --git a/mentos/src/fs/vfs.c b/mentos/src/fs/vfs.c index 5a85272..4d1d62d 100644 --- a/mentos/src/fs/vfs.c +++ b/mentos/src/fs/vfs.c @@ -324,7 +324,7 @@ vfs_file_t *vfs_creat(const char *path, mode_t mode) // Retrieve the file. vfs_file_t *file = sb_root->sys_operations->creat_f(absolute_path, mode); if (file == NULL) { - pr_err("vfs_open(%s): Cannot find the given file (%s)!\n", path, strerror(errno)); + pr_err("vfs_creat(%s): Cannot find the given file (%s)!\n", path, strerror(errno)); errno = ENOENT; return NULL; } diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 33f002a..e93a969 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -23,6 +23,8 @@ /// @param task the task to update. static void __update_task_statistics(task_struct *task); +void feedback(pid_t pid, char name[], pid_t padre, int mode, int prio); + /// @brief Checks if the given task is actually a periodic task. /// @param task the task to check. /// @return true if the task is periodic, false otherwise. @@ -45,7 +47,6 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri if (list_head_size(&runqueue->curr->run_list) <= 1) { return runqueue->curr; } - // Search for the next task (we do not start from the head, so INSIDE, skip the head). list_for_each_decl(it, &runqueue->curr->run_list) @@ -62,13 +63,10 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri if (__is_periodic_task(entry) && skip_periodic) continue; // We have our next entry. - - //function to track the scheduler algorithm - writeFeedback(entry->pid, entry->name, entry->parent->pid, 1, (entry->se).prio); - + return entry; } - + return NULL; } @@ -93,7 +91,7 @@ static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_peri /// If you pick the first task every time (i.e., init), and use its prio (i.e., /// 120), what would happen if inside the for-loop when you check "if the entry /// has a lower priority", you use a lesser-than sign? -/// First, it will check against init itself, so 120 < 120 is false. +/// First, it will check against init itself, so 120 < 120 is false. /// Then, it will check against shell, again, 120 < 120 is false. /// As such, shell or the other processes will never be selected. There are /// different ways of solving this problem, each of which requires changes only @@ -129,8 +127,8 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski } //function to track the scheduler algorithm - writeFeedback(next->pid, next->name, next->parent->pid, 2, (next->se).prio); - + //writeFeedback(next->pid, next->name, next->parent->pid, 2, (next->se).prio); + return next; #else return __scheduler_rr(runqueue, skip_periodic); @@ -178,7 +176,7 @@ static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_per } } //function to track the scheduler algorithm - writeFeedback(next->pid, next->name, next->parent->pid, 3, (next->se).prio); + //writeFeedback(next->pid, next->name, next->parent->pid, 3, (next->se).prio); return next; #else @@ -245,6 +243,8 @@ 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(); + feedback(next->pid, next->name, next->parent->pid, 1, (next->se).prio); + writeFeedback(next->pid, next->name, next->parent->pid, 1, (next->se).prio); return next; } @@ -271,16 +271,97 @@ static void __update_task_statistics(task_struct *task) // If the task is not a periodic task we have to update the virtual runtime. if (!task->se.is_periodic) { // Get the weight of the current task. - time_t weight = GET_WEIGHT((task)->se.prio);/* ... */; + time_t weight = GET_WEIGHT((task)->se.prio); /* ... */ + ; // If the weight is different from the default load, compute it. if (weight != NICE_0_LOAD) { // Get the multiplicative factor for its delta_exec. - double factor = ((double)NICE_0_LOAD / (double)weight);/* ... */; + double factor = ((double)NICE_0_LOAD / (double)weight); /* ... */ + ; // Weight the delta_exec with the multiplicative factor. - task->se.exec_runtime = ((int)(((double)task->se.exec_runtime) * factor));/* ... */ + task->se.exec_runtime = ((int)(((double)task->se.exec_runtime) * factor)); /* ... */ } // Update vruntime of the current task. task->se.vruntime += task->se.exec_runtime; } #endif } + +//Nuova funzione per statistiche RunTime + +#include +#include +#define MAX_STORAGE 500000 + +typedef struct statistic { + pid_t pid; + char name[20]; + int occur; +} stat; + +int countPid = 1; +int countPid_1 = 1; + +stat arr_stats[MAX_STORAGE] = { 0, "", 0 }; + +pid_t PID_BUFFER1[MAX_STORAGE] = { 0 }; +char PID_NAME1[MAX_STORAGE][40]; + +void feedback(pid_t pid, char name[], pid_t padre, int mode, int prio) +{ + //se lasciamo a 600k sono 31 secondi circa, nb -> ovviamente dipende dalla cpu del pc che ospita la macchina + if (!(countPid_1 % 500000)) { + //printf("PID %i name :%s\n", pid, name); + //qui dentro dobbiamo: ordinare senza ripetizioni sia pid_buffer1 sia pid_name1 + //e in piu ci serve un altro array per contare le occorreze + //se facciamo cosi poi possimao permetterci di ciclare un for e semplicemente stampare i tre cosi + int end = 0; + printf("\nSTATS:\n"); + + for (int i = 0; i < MAX_STORAGE && !end; i++) { + if (arr_stats[i].pid == 0) { + end = 1; + } else { + printf("Name: %s, Pid: %i, TCPU: %.4f%% \n", arr_stats[i].name, arr_stats[i].pid, arr_stats[i].occur * 100 / (double)MAX_STORAGE); + } + } + end = 0; + //resettiamo + for (int i = 0; i < MAX_STORAGE && !end; i++) { + if (arr_stats[i].pid == 0) { //se trovo che ho finito di ciclare i valori registrati + end = 1; //esco dal for + } + arr_stats[i].pid = 0; + arr_stats[i].occur = 0; + } + + countPid = 0; + countPid_1 = 0; + } else { + //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo + if (countPid != MAX_STORAGE) { + //REGISTRAZIONE PID IN BUFFER + int stored = 0; + int endArr = 0; + int i; + for (i = 0; i < MAX_STORAGE && !stored && !endArr; i++) { + if (arr_stats[i].pid == pid) { + arr_stats[i].occur++; + stored = 1; + } + if (arr_stats[i].pid == 0) { //se trovo che ho finito di ciclpidare i valori registrati + endArr = 1; //esco dal for + } + } + if (!stored) { //se non avevo registrato il valore + + i--; + arr_stats[i].pid = pid; + strcpy(arr_stats[i].name, name); + arr_stats[i].occur = 1; + } + countPid++; + } + } + countPid_1++; +} diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index d62798c..cbbd9df 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -23,8 +23,9 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress #include "stdio.h" #include "fs/vfs.h" #include "string.h" +#include "debug.h" -#define FEEDBACK_FILENAME "/home/user/feedback.txt" +#define FEEDBACK_FILENAME "/feedback2.txt" // Size of the buffer. #define BUFFER_SIZE 256 @@ -35,9 +36,9 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress #define MAX_STORAGE 10 int count = 0; pid_t PID_BUFFER[MAX_STORAGE] = { 0 }; -int PID_PRIO[MAX_STORAGE] = { 0 }; +int PID_PRIO[MAX_STORAGE] = { 0 }; char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; -pid_t oldPid = -1; +pid_t oldPid = -1; ssize_t offset; int err = 1; int countChar(char[]); @@ -54,34 +55,28 @@ Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) { char start[] = "start"; - int brake = 0; - + int brake = 0; + //analizzo se nome del PID passato come argomento corrisponde al comando START for (int i = 0; i < countChar(name) && brake == 0; i++) { - - if ((start[i] != name[i]) || oldPid==pid || oldPid==padre || countChar(name) != countChar(start) ) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po + if ((start[i] != name[i]) || oldPid == pid || oldPid == padre || countChar(name) != countChar(start)) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po brake = 1; } } - + //questo ci serve per andare a salvare il pid di una nuova start lanciata da terminale //il primissimo start viene detectato OR detecta uno start con un pid nuovo MA con mio padre diverso dal creatore della sessione attuale o finita (oldPid) - if((oldPid==-1 && brake == 0) || (oldPid!=-1 && brake == 0 && oldPid!=pid && oldPid!=padre) ){ - + if ((oldPid == -1 && brake == 0) || (oldPid != -1 && brake == 0 && oldPid != pid && oldPid != padre)) { oldPid = pid; - } - - - //Se prima volta e' start bene, proseguiamo siccome brake e' zero, //le successive brake NON zero ma count > 0 poiche start passato in precedenza //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if (count != MAX_STORAGE && (count != 0 || brake == 0 )) { + if (count != MAX_STORAGE && (count != 0 || brake == 0)) { //REGISTRAZIONE PID IN BUFFER in modalita start SENZA parametri PID_BUFFER[count] = pid; - PID_PRIO[count] = prio; + PID_PRIO[count] = prio; strcpy(PID_NAME[count], name); count++; } @@ -92,13 +87,13 @@ void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) mode_t flag = 000777; char buffer[BUFFER_SIZE]; const char *namef = "/home/user/feedback.txt"; - offset = sizeof(char) * 34; //PER SCRITTURA MODALITA - char temp[6]; //max PID 99999 + offset = sizeof(char) * 34; //PER SCRITTURA MODALITA + char temp[6]; //max PID 99999 char temp_prio[4]; - char rr[] = "ROUND ROBIN\n"; + char rr[] = "ROUND ROBIN\n"; char priority[] = "HIGH PRIORITY FIRST\n"; - char cfs[] = "FAIR SHARE\n"; - char testo[] = "\nPID PRIO NAME\n"; + char cfs[] = "FAIR SHARE\n"; + char testo[] = "\nPID PRIO NAME\n"; // NOTE: You should check if the file exists, or create it, during the boot // phase of the system. Choose a place where to put it, a location like @@ -109,29 +104,23 @@ void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) printf("Error: Failed to open feedback file."); } - if(mode == 1){ - + if (mode == 1) { offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, rr, offset, sizeof(char)*countChar(rr)); - } - else if(mode == 2){ - + offset += vfs_write(file, rr, offset, sizeof(char) * countChar(rr)); + } else if (mode == 2) { offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, priority, offset, sizeof(char)*countChar(priority)); - } - else{ - + offset += vfs_write(file, priority, offset, sizeof(char) * countChar(priority)); + } else { offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, cfs, offset, sizeof(char)*countChar(cfs)); + offset += vfs_write(file, cfs, offset, sizeof(char) * countChar(cfs)); } - + /* offset += vfs_write(file, "\n", offset, sizeof(char)); offset += vfs_write(file, "\n", offset, sizeof(char)); offset += sizeof(char)* (13);*/ - offset += vfs_write(file, testo, offset, sizeof(char)*countChar(testo)); - + offset += vfs_write(file, testo, offset, sizeof(char) * countChar(testo)); for (int i = 0; i < MAX_STORAGE; i++) { itoa(temp, PID_BUFFER[i], 10); @@ -149,11 +138,10 @@ void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) } vfs_close(file); count = 0; - err = 1; + err = 1; } - if(!strcmp(name,"error") && err){ - + if (!strcmp(name, "error") && err) { wipe(); err--; } @@ -164,14 +152,13 @@ Funzione che pulisce la sessione */ void wipe() { - mode_t flag = 000777; + mode_t flag = 000777; const char *namef = "/home/user/feedback.txt"; - vfs_file_t *file = vfs_open(namef, O_RDWR, flag); - count = 0; - offset += sizeof(char)*100; //overkill - - for(int i = 34*sizeof(char); i < offset; i+=sizeof(char)){ + vfs_file_t *file = vfs_open(namef, O_RDWR, flag); + count = 0; + offset += sizeof(char) * 100; //overkill + for (int i = 34 * sizeof(char); i < offset; i += sizeof(char)) { //NB: se riusciamo a creare un file nostro e scrivere non solo sugli spazi //questo costrutto non funziona, del sovrascrivere finche count non e' zero vfs_write(file, " ", i, sizeof(char)); @@ -179,7 +166,6 @@ void wipe() vfs_close(file); } - /* Funzione che conta caratteri del array di char passato */ @@ -196,8 +182,11 @@ int countChar(char name[]) int scheduler_feedback_init() { // - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + //mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // - vfs_file_t *feedback = vfs_creat(FEEDBACK_FILENAME, mode); + //vfs_file_t *feedback = vfs_creat(FEEDBACK_FILENAME, mode); + //if (feedback == NULL) + // pr_debug("non va"); + return 1; } From 09aa9a6a39a6c8d39e6e7bcc3a6cc128c6a831fc Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Tue, 18 Apr 2023 15:18:15 +0200 Subject: [PATCH 20/26] Fix O_CREAT check. Fix inode cretion error during the boot phase. --- mentos/src/fs/ext2.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/mentos/src/fs/ext2.c b/mentos/src/fs/ext2.c index 011e4de..b02e111 100644 --- a/mentos/src/fs/ext2.c +++ b/mentos/src/fs/ext2.c @@ -491,6 +491,10 @@ static bool_t ext2_valid_permissions(int flags, mode_t mask, uid_t uid, gid_t gi { // Check the permissions. task_struct *task = scheduler_get_current_process(); + if (task == NULL) { + pr_warning("Failed to get the current running process, assuming we are booting.\n"); + return true; + } // The current task is the owner. if (task->uid == uid) { if (!bitmask_check(mask, S_IRUSR)) @@ -2154,11 +2158,6 @@ static int ext2_create_inode( pr_err("Received a null EXT2 inode.\n"); return -1; } - task_struct *task = scheduler_get_current_process(); - if (task == NULL) { - pr_err("Failed to get the current running process.\n"); - return -1; - } // Allocate an inode, inside the preferred_group if possible. int inode_index = ext2_allocate_inode(fs, preferred_group); if (inode_index == 0) { @@ -2172,10 +2171,19 @@ static int ext2_create_inode( pr_err("Failed to read the newly created inode.\n"); return -1; } + // Get the UID and GID. + uid_t uid = 0, gid = 0; + task_struct *task = scheduler_get_current_process(); + if (task != NULL) { + pr_warning("Failed to get the current running process, assuming we are booting.\n"); + } else { + uid = task->uid; + gid = task->gid; + } // Set the inode mode. inode->mode = mode; // Set the user identifiers of the owners. - inode->uid = task->uid; + inode->uid = uid; // Set the size of the file in bytes. inode->size = 0; // Set the time that the inode was accessed. @@ -2187,7 +2195,7 @@ static int ext2_create_inode( // Set the time that the inode was deleted. inode->dtime = 0; // Set the group identifiers of the owners. - inode->gid = task->gid; + inode->gid = gid; // Set the number of hard links. inode->links_count = 0; // Set the blocks count. @@ -2335,7 +2343,7 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode) search.parent_inode = 0; // First check, if a file with the given name already exists. if (!ext2_resolve_path(fs->root, absolute_path, &search)) { - if (bitmask_check(flags, O_CREAT | O_EXCL)) { + if (bitmask_check(flags, O_CREAT) && bitmask_check(flags, O_EXCL)) { pr_err("A file or directory already exists at `%s` (O_CREAT | O_EXCL).\n", absolute_path); return NULL; } else if (bitmask_check(flags, O_DIRECTORY) && (direntry.file_type != ext2_file_type_directory)) { @@ -2722,15 +2730,15 @@ static int ext2_mkdir(const char *path, mode_t permission) pr_err("Failed to properly get the parent directory (%s == %s).\n", parent_path, path); return -ENOENT; } + // Set the inode mode. + uint32_t mode = EXT2_S_IFDIR; + mode |= 0xFFF & permission; // Get the parent VFS node. - vfs_file_t *parent = vfs_open(parent_path, O_RDONLY, 0); + vfs_file_t *parent = vfs_open(parent_path, O_RDONLY, mode); if (parent == NULL) { pr_err("Failed to open parent directory (%s).\n", parent_path); return -ENOENT; } - // Set the inode mode. - uint32_t mode = EXT2_S_IFDIR; - mode |= 0xFFF & permission; // Get the group index of the parent. uint32_t group_index = ext2_get_group_index_from_inode(fs, parent->ino); // Create and initialize the new inode. From d630fd55f71d8fb0e64f79e35273a89d7d4e6b77 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Tue, 18 Apr 2023 17:52:19 +0200 Subject: [PATCH 21/26] Clean up the feedback code. --- files/home/user/feedback.txt | 7 - mentos/inc/process/scheduler_feedback.h | 5 +- mentos/src/process/scheduler_algorithm.c | 88 +------ mentos/src/process/scheduler_feedback.c | 308 +++++++++++------------ 4 files changed, 154 insertions(+), 254 deletions(-) delete mode 100644 files/home/user/feedback.txt diff --git a/files/home/user/feedback.txt b/files/home/user/feedback.txt deleted file mode 100644 index ee9ae06..0000000 --- a/files/home/user/feedback.txt +++ /dev/null @@ -1,7 +0,0 @@ ---PID'S RECORDING SESSION-- - -MODE: - -PID PRIO NAME - - \ No newline at end of file diff --git a/mentos/inc/process/scheduler_feedback.h b/mentos/inc/process/scheduler_feedback.h index b42c4a3..10326be 100644 --- a/mentos/inc/process/scheduler_feedback.h +++ b/mentos/inc/process/scheduler_feedback.h @@ -5,8 +5,11 @@ #pragma once #include "sys/types.h" +#include "process/process.h" -void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio); +/// @brief Function which is called by scheduler_algorithm after choosing the +/// next task, and updates the sceduling statistics. +void scheduler_feedback_update(task_struct * next); /// @brief Initialize the scheduler feedback system. /// @return 1 on success, 0 on failure. diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index e93a969..055dd34 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -126,9 +126,6 @@ static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t ski } } - //function to track the scheduler algorithm - //writeFeedback(next->pid, next->name, next->parent->pid, 2, (next->se).prio); - return next; #else return __scheduler_rr(runqueue, skip_periodic); @@ -175,8 +172,6 @@ static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_per next = entry; // scambio il prossimo processo con quello a priorità piu bassa trovato } } - //function to track the scheduler algorithm - //writeFeedback(next->pid, next->name, next->parent->pid, 3, (next->se).prio); return next; #else @@ -243,8 +238,8 @@ 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(); - feedback(next->pid, next->name, next->parent->pid, 1, (next->se).prio); - writeFeedback(next->pid, next->name, next->parent->pid, 1, (next->se).prio); + + scheduler_feedback_update(next); return next; } @@ -286,82 +281,3 @@ static void __update_task_statistics(task_struct *task) } #endif } - -//Nuova funzione per statistiche RunTime - -#include -#include -#define MAX_STORAGE 500000 - -typedef struct statistic { - pid_t pid; - char name[20]; - int occur; -} stat; - -int countPid = 1; -int countPid_1 = 1; - -stat arr_stats[MAX_STORAGE] = { 0, "", 0 }; - -pid_t PID_BUFFER1[MAX_STORAGE] = { 0 }; -char PID_NAME1[MAX_STORAGE][40]; - -void feedback(pid_t pid, char name[], pid_t padre, int mode, int prio) -{ - //se lasciamo a 600k sono 31 secondi circa, nb -> ovviamente dipende dalla cpu del pc che ospita la macchina - if (!(countPid_1 % 500000)) { - //printf("PID %i name :%s\n", pid, name); - //qui dentro dobbiamo: ordinare senza ripetizioni sia pid_buffer1 sia pid_name1 - //e in piu ci serve un altro array per contare le occorreze - //se facciamo cosi poi possimao permetterci di ciclare un for e semplicemente stampare i tre cosi - int end = 0; - printf("\nSTATS:\n"); - - for (int i = 0; i < MAX_STORAGE && !end; i++) { - if (arr_stats[i].pid == 0) { - end = 1; - } else { - printf("Name: %s, Pid: %i, TCPU: %.4f%% \n", arr_stats[i].name, arr_stats[i].pid, arr_stats[i].occur * 100 / (double)MAX_STORAGE); - } - } - end = 0; - //resettiamo - for (int i = 0; i < MAX_STORAGE && !end; i++) { - if (arr_stats[i].pid == 0) { //se trovo che ho finito di ciclare i valori registrati - end = 1; //esco dal for - } - arr_stats[i].pid = 0; - arr_stats[i].occur = 0; - } - - countPid = 0; - countPid_1 = 0; - } else { - //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if (countPid != MAX_STORAGE) { - //REGISTRAZIONE PID IN BUFFER - int stored = 0; - int endArr = 0; - int i; - for (i = 0; i < MAX_STORAGE && !stored && !endArr; i++) { - if (arr_stats[i].pid == pid) { - arr_stats[i].occur++; - stored = 1; - } - if (arr_stats[i].pid == 0) { //se trovo che ho finito di ciclpidare i valori registrati - endArr = 1; //esco dal for - } - } - if (!stored) { //se non avevo registrato il valore - - i--; - arr_stats[i].pid = pid; - strcpy(arr_stats[i].name, name); - arr_stats[i].occur = 1; - } - countPid++; - } - } - countPid_1++; -} diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index cbbd9df..ef0e595 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -3,6 +3,13 @@ /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. +// Include the kernel log levels. +#include "sys/kernel_levels.h" +/// Change the header. +#define __DEBUG_HEADER__ "[SCHFBK]" +/// Set the log level. +#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG + /* HOW TO: all'avvio di MentOS, usa comando start, verrai avvisato su terminale quando la sessione sarà terminata. @@ -18,175 +25,156 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress */ #include "process/scheduler_feedback.h" - +#include "hardware/timer.h" +#include "strerror.h" +#include "io/debug.h" +#include "fs/vfs.h" +#include "assert.h" +#include "string.h" #include "fcntl.h" #include "stdio.h" -#include "fs/vfs.h" -#include "string.h" -#include "debug.h" -#define FEEDBACK_FILENAME "/feedback2.txt" +/// @brief +#define FEEDBACK_FILENAME "/var/feedback.txt" +/// @brief +#define FEEDBACK_HEADER "\nPID PRIO NAME\n\0" +/// @brief +#define LOG_INTERVAL 3 -// Size of the buffer. -#define BUFFER_SIZE 256 +#if defined(SCHEDULER_RR) +#define POLICY_NAME "RR " +#elif defined(SCHEDULER_PRIORITY) +#define POLICY_NAME "PRIO " +#elif defined(SCHEDULER_CFS) +#define POLICY_NAME "CFS " +#elif defined(SCHEDULER_EDF) +#define POLICY_NAME "EDF " +#elif defined(SCHEDULER_RM) +#define POLICY_NAME "RM " +#elif defined(SCHEDULER_AEDF) +#define POLICY_NAME "AEDF " +#else +#error "You should enable a scheduling algorithm!" +#endif -#define MAX_SIZE_NAME 20 - -//Variabili Globali -#define MAX_STORAGE 10 -int count = 0; -pid_t PID_BUFFER[MAX_STORAGE] = { 0 }; -int PID_PRIO[MAX_STORAGE] = { 0 }; -char PID_NAME[MAX_STORAGE][MAX_SIZE_NAME]; -pid_t oldPid = -1; +/// @brief ssize_t offset; -int err = 1; -int countChar(char[]); -void wipe(); +/// @brief +size_t next_log; +/// @brief +size_t total_occurrences; -/* - PID 1 --> INIT - PID 2 --> KTHREADD -*/ - -/* -Funzione che viene chiamata da scheduler_algorithm dopo aver scelto il prossimo processo da eseguire -*/ -void writeFeedback(pid_t pid, char name[], pid_t padre, int mode, int prio) -{ - char start[] = "start"; - int brake = 0; - - //analizzo se nome del PID passato come argomento corrisponde al comando START - for (int i = 0; i < countChar(name) && brake == 0; i++) { - if ((start[i] != name[i]) || oldPid == pid || oldPid == padre || countChar(name) != countChar(start)) { //brake a 0 anche se viene rilevata una start che non è stata lanciata da terminale ma è in esecuzione de un po - brake = 1; - } - } - - //questo ci serve per andare a salvare il pid di una nuova start lanciata da terminale - //il primissimo start viene detectato OR detecta uno start con un pid nuovo MA con mio padre diverso dal creatore della sessione attuale o finita (oldPid) - if ((oldPid == -1 && brake == 0) || (oldPid != -1 && brake == 0 && oldPid != pid && oldPid != padre)) { - oldPid = pid; - } - - //Se prima volta e' start bene, proseguiamo siccome brake e' zero, - //le successive brake NON zero ma count > 0 poiche start passato in precedenza - //Opportuno controllo per non sforare il MAX_STORAGE della struttura dati che utilizziamo - if (count != MAX_STORAGE && (count != 0 || brake == 0)) { - //REGISTRAZIONE PID IN BUFFER in modalita start SENZA parametri - PID_BUFFER[count] = pid; - PID_PRIO[count] = prio; - strcpy(PID_NAME[count], name); - count++; - } - - //QUI SE BUFFER PIENO SCRIVO SU FILE - - if (count == MAX_STORAGE) { - mode_t flag = 000777; - char buffer[BUFFER_SIZE]; - const char *namef = "/home/user/feedback.txt"; - offset = sizeof(char) * 34; //PER SCRITTURA MODALITA - char temp[6]; //max PID 99999 - char temp_prio[4]; - char rr[] = "ROUND ROBIN\n"; - char priority[] = "HIGH PRIORITY FIRST\n"; - char cfs[] = "FAIR SHARE\n"; - char testo[] = "\nPID PRIO NAME\n"; - - // NOTE: You should check if the file exists, or create it, during the boot - // phase of the system. Choose a place where to put it, a location like - // `/var/scheduling_feedback.txt`. - vfs_file_t *file = vfs_open(namef, O_RDWR, flag); - - if (file == NULL) { - printf("Error: Failed to open feedback file."); - } - - if (mode == 1) { - offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, rr, offset, sizeof(char) * countChar(rr)); - } else if (mode == 2) { - offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, priority, offset, sizeof(char) * countChar(priority)); - } else { - offset += vfs_write(file, " ", offset, sizeof(char)); - offset += vfs_write(file, cfs, offset, sizeof(char) * countChar(cfs)); - } - - /* - offset += vfs_write(file, "\n", offset, sizeof(char)); - offset += vfs_write(file, "\n", offset, sizeof(char)); - offset += sizeof(char)* (13);*/ - - offset += vfs_write(file, testo, offset, sizeof(char) * countChar(testo)); - - for (int i = 0; i < MAX_STORAGE; i++) { - itoa(temp, PID_BUFFER[i], 10); - itoa(temp_prio, PID_PRIO[i], 10); - offset += vfs_write(file, temp, offset, sizeof(char) * countChar(temp)); - offset += vfs_write(file, " ", offset, sizeof(char) * 3); - offset += vfs_write(file, temp_prio, offset, sizeof(char) * countChar(temp_prio)); - offset += vfs_write(file, " ", offset, sizeof(char) * 3); - offset += vfs_write(file, PID_NAME[i], offset, sizeof(char) * countChar(PID_NAME[i])); - offset += vfs_write(file, "\n", offset, sizeof(char)); - //ripristino array temp - for (int j = 0; j < 5; j++) { - temp[j] = 0; - } - } - vfs_close(file); - count = 0; - err = 1; - } - - if (!strcmp(name, "error") && err) { - wipe(); - err--; - } -} - -/* -Funzione che pulisce la sessione -*/ -void wipe() -{ - mode_t flag = 000777; - const char *namef = "/home/user/feedback.txt"; - vfs_file_t *file = vfs_open(namef, O_RDWR, flag); - count = 0; - offset += sizeof(char) * 100; //overkill - - for (int i = 34 * sizeof(char); i < offset; i += sizeof(char)) { - //NB: se riusciamo a creare un file nostro e scrivere non solo sugli spazi - //questo costrutto non funziona, del sovrascrivere finche count non e' zero - vfs_write(file, " ", i, sizeof(char)); - } - vfs_close(file); -} - -/* -Funzione che conta caratteri del array di char passato -*/ - -int countChar(char name[]) -{ - int ct = 0; - while (name[ct] != '\0') { - ct++; - } - return ct; -} +/// @brief +struct statistic { + pid_t pid; + char name[20]; + unsigned long occur; +} arr_stats[PID_MAX_LIMIT]; int scheduler_feedback_init() { - // - //mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - // - //vfs_file_t *feedback = vfs_creat(FEEDBACK_FILENAME, mode); - //if (feedback == NULL) - // pr_debug("non va"); - + // Create the feedback file, if necessary. + int ret = vfs_mkdir("/var", 0644); + if ((ret < 0) && (-ret != EEXIST)) { + pr_err("Failed to create the `/var` directory.\n"); + pr_err("Error: %s\n", strerror(errno)); + return 0; + } + // Create the feedback file, if necessary. + vfs_file_t *feedback = vfs_open(FEEDBACK_FILENAME, O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (feedback == NULL) { + pr_err("Failed to create the feedback file.\n"); + pr_err("Error: %s\n", strerror(errno)); + return 0; + } + // Get the length of the headr. + ssize_t header_len = strlen(FEEDBACK_HEADER); + // Reset the offset. + offset = 0; + // Write the header. + vfs_write(feedback, FEEDBACK_HEADER, offset, header_len); + // Move the offset. + offset += header_len; + // Close the file. + vfs_close(feedback); + // Initialize the stat array. + for (size_t i = 0; i < PID_MAX_LIMIT; ++i) { + arr_stats[i].pid = -1; + arr_stats[i].occur = 0; + } + // Set when the first logging should happen. + next_log = timer_get_seconds() + LOG_INTERVAL; + // Initialize the number of occurrences. + total_occurrences = 0; return 1; } + +void scheduler_feedback_update(task_struct *next) +{ + 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; + } + 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, + 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; + } + } + } +} From 6aa814f30ade5b2906daa2a378efd97687ec0875 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Wed, 19 Apr 2023 10:22:14 +0200 Subject: [PATCH 22/26] Improve scheduler feedback. --- mentos/inc/process/scheduler_feedback.h | 18 ++- mentos/src/process/scheduler.c | 6 +- mentos/src/process/scheduler_algorithm.c | 5 +- mentos/src/process/scheduler_feedback.c | 141 ++++++++++++----------- 4 files changed, 95 insertions(+), 75 deletions(-) diff --git a/mentos/inc/process/scheduler_feedback.h b/mentos/inc/process/scheduler_feedback.h index 10326be..25335ab 100644 --- a/mentos/inc/process/scheduler_feedback.h +++ b/mentos/inc/process/scheduler_feedback.h @@ -7,9 +7,21 @@ #include "sys/types.h" #include "process/process.h" -/// @brief Function which is called by scheduler_algorithm after choosing the -/// next task, and updates the sceduling statistics. -void scheduler_feedback_update(task_struct * next); +/// @brief Updates the scheduling statistics for the given task. +/// @param task the task for which we update the statistics. +void scheduler_feedback_update(); + +/// @brief Add the given task to the feedback system. +/// @param task the task we need to add. +void scheduler_feedback_task_add(task_struct * task); + +/// @brief Removes the given task from the feedback system. +/// @param pid the pid of the task we need to remove. +void scheduler_feedback_task_remove(pid_t pid); + +/// @brief Updates the scheduling statistics for the given task. +/// @param task the task for which we update the statistics. +void scheduler_feedback_task_update(task_struct * task); /// @brief Initialize the scheduler feedback system. /// @return 1 on success, 0 on failure. diff --git a/mentos/src/process/scheduler.c b/mentos/src/process/scheduler.c index 23af5c3..0906601 100644 --- a/mentos/src/process/scheduler.c +++ b/mentos/src/process/scheduler.c @@ -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. diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 055dd34..89aa381 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -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; } diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index ef0e595..c549e33 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -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; } From cf0001fca6a83be7b0d42676de717a2646f1a3a3 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Wed, 19 Apr 2023 14:02:49 +0200 Subject: [PATCH 23/26] Clean up the comments concerning the scheduler feedback. --- mentos/inc/process/scheduler_feedback.h | 20 +-- mentos/src/process/scheduler_feedback.c | 171 +++++++++++++----------- 2 files changed, 101 insertions(+), 90 deletions(-) diff --git a/mentos/inc/process/scheduler_feedback.h b/mentos/inc/process/scheduler_feedback.h index 25335ab..d18cd18 100644 --- a/mentos/inc/process/scheduler_feedback.h +++ b/mentos/inc/process/scheduler_feedback.h @@ -1,19 +1,19 @@ /// @file scheduler_feedback.h /// @author Enrico Fraccaroli (enry.frak@gmail.com) -/// @brief +/// @brief #pragma once #include "sys/types.h" #include "process/process.h" -/// @brief Updates the scheduling statistics for the given task. -/// @param task the task for which we update the statistics. -void scheduler_feedback_update(); +/// @brief Initialize the scheduler feedback system. +/// @return 1 on success, 0 on failure. +int scheduler_feedback_init(); /// @brief Add the given task to the feedback system. -/// @param task the task we need to add. -void scheduler_feedback_task_add(task_struct * task); +/// @param task the task we need to add. +void scheduler_feedback_task_add(task_struct *task); /// @brief Removes the given task from the feedback system. /// @param pid the pid of the task we need to remove. @@ -21,8 +21,8 @@ void scheduler_feedback_task_remove(pid_t pid); /// @brief Updates the scheduling statistics for the given task. /// @param task the task for which we update the statistics. -void scheduler_feedback_task_update(task_struct * task); +void scheduler_feedback_task_update(task_struct *task); -/// @brief Initialize the scheduler feedback system. -/// @return 1 on success, 0 on failure. -int scheduler_feedback_init(); +/// @brief Updates the scheduling statistics for the given task. +/// @param task the task for which we update the statistics. +void scheduler_feedback_update(); diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index c549e33..b3ca4fe 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -2,6 +2,27 @@ /// @brief Manage the current PID for the scheduler feedback session /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @details +/// all'avvio di MentOS, usa comando start, verrai avvisato su terminale quando la +/// sessione sarà terminata. Puoi verificare i risultati a video lanciando il +/// comando cat sul file del desktop (feedback.txt) +/// +/// es: +/// ~ start +/// ~ cat feedback.txt +/// +/// Questa e' una versione di prova in cui registriamo una brevissima sessione di +/// soli 10 pid. (Funzionante per ora solo con lo scheduler RR) Istruzioni relative +/// ai parametri della funzione start (che sono work in progress) sono in start.c + +#include "process/scheduler_feedback.h" +#include "hardware/timer.h" +#include "strerror.h" +#include "fs/vfs.h" +#include "assert.h" +#include "string.h" +#include "fcntl.h" +#include "stdio.h" // Include the kernel log levels. #include "sys/kernel_levels.h" @@ -9,40 +30,12 @@ #define __DEBUG_HEADER__ "[SCHFBK]" /// Set the log level. #define __DEBUG_LEVEL__ LOGLEVEL_DEBUG - -/* -HOW TO: -all'avvio di MentOS, usa comando start, verrai avvisato su terminale quando la sessione sarà terminata. -Puoi verificare i risultati a video lanciando il comando cat sul file del desktop (feedback.txt) - -es: -~ start -~ cat feedback.txt - -Questa e' una versione di prova in cui registriamo una brevissima sessione di soli 10 pid. -(Funzionante per ora solo con lo scheduler RR) -Istruzioni relative ai parametri della funzione start (che sono work in progress) sono in start.c -*/ - -#include "process/scheduler_feedback.h" -#include "hardware/timer.h" -#include "strerror.h" #include "io/debug.h" -#include "fs/vfs.h" -#include "assert.h" -#include "string.h" -#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_SEC 1 +/// @brief How often the feedback is shown. +#define LOG_INTERVAL_SEC 0.5 +/// @brief The name of the scheduling policy. #if defined(SCHEDULER_RR) #define POLICY_NAME "RR " #elif defined(SCHEDULER_PRIORITY) @@ -59,22 +52,66 @@ Istruzioni relative ai parametri della funzione start (che sono work in progress #error "You should enable a scheduling algorithm!" #endif +/// @brief If uncommented, it writes the logging on file. +//#define WRITE_ON_FILE + #ifdef WRITE_ON_FILE +/// @brief Name of the file where the feedback statistics are saved. +#define FEEDBACK_FILENAME "/var/schedfb" +/// @brief The header shown +#define FEEDBACK_HEADER "\n[PID[] | NAME | -> (CPU UTILIZATION)\n\0" /// @brief ssize_t offset; #endif -/// @brief +/// @brief When the next log should be displayed/saved, in CPU ticks. unsigned long next_log; -/// @brief +/// @brief The total number of context-switches since the starting of the log +/// session. size_t total_occurrences; -/// @brief +/// @brief A structure that keeps track of scheduling statistics. struct statistic { task_struct *task; unsigned long occur; } arr_stats[PID_MAX_LIMIT]; +/// @brief Logs the scheduling statistics either on file or on the terminal. +static inline void __scheduler_feedback_log() +{ + 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] | %-24s | -> TCPU: %.2f%% \n", + arr_stats[i].task->pid, + arr_stats[i].task->name, + tcpu); +#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 +} + int scheduler_feedback_init() { #ifdef WRITE_ON_FILE @@ -115,52 +152,6 @@ int scheduler_feedback_init() return 1; } -void scheduler_feedback_update() -{ - 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] | %-24s | -> TCPU: %.2f%% \n", - arr_stats[i].task->pid, - arr_stats[i].task->name, - tcpu); -#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."); @@ -171,6 +162,7 @@ void scheduler_feedback_task_add(task_struct *task) void scheduler_feedback_task_remove(pid_t pid) { assert(pid < PID_MAX_LIMIT && "We received a wrong pid."); + total_occurrences -= arr_stats[pid].occur; arr_stats[pid].occur = 0; arr_stats[pid].task = NULL; } @@ -181,3 +173,22 @@ void scheduler_feedback_task_update(task_struct *task) arr_stats[task->pid].occur += 1; total_occurrences += 1; } + +void scheduler_feedback_update() +{ + // If it is not yet time for the next reset, skip. + if (next_log >= timer_get_ticks()) { + return; + } + // Dump on the feedback before reset. + __scheduler_feedback_log(); + // Reset the occurences. + 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; +} From 6ca621d5068f93c431d268fbd7113901b48d19ff Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Wed, 19 Apr 2023 14:24:32 +0200 Subject: [PATCH 24/26] Finalize the scheduling test program. --- mentos/src/process/scheduler_feedback.c | 12 --- programs/CMakeLists.txt | 2 - programs/start.c | 111 ------------------------ programs/startERR.c | 5 -- programs/tests/CMakeLists.txt | 11 ++- programs/tests/myProg.c | 7 -- programs/tests/t_schedfb.c | 22 +++++ 7 files changed, 27 insertions(+), 143 deletions(-) delete mode 100644 programs/start.c delete mode 100644 programs/startERR.c delete mode 100644 programs/tests/myProg.c create mode 100644 programs/tests/t_schedfb.c diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index b3ca4fe..dbecb02 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -2,18 +2,6 @@ /// @brief Manage the current PID for the scheduler feedback session /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. -/// @details -/// all'avvio di MentOS, usa comando start, verrai avvisato su terminale quando la -/// sessione sarà terminata. Puoi verificare i risultati a video lanciando il -/// comando cat sul file del desktop (feedback.txt) -/// -/// es: -/// ~ start -/// ~ cat feedback.txt -/// -/// Questa e' una versione di prova in cui registriamo una brevissima sessione di -/// soli 10 pid. (Funzionante per ora solo con lo scheduler RR) Istruzioni relative -/// ai parametri della funzione start (che sono work in progress) sono in start.c #include "process/scheduler_feedback.h" #include "hardware/timer.h" diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 2395326..5e36d4c 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -69,8 +69,6 @@ set(PROGRAMS poweroff.c rm.c shell.c - start.c - startERR.c uname.c cat.c echo.c diff --git a/programs/start.c b/programs/start.c deleted file mode 100644 index e4244ec..0000000 --- a/programs/start.c +++ /dev/null @@ -1,111 +0,0 @@ -/// @file start.c -/// @brief Start the scheduler feedback session -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. -#include -#include -#include - -#include -#include -#include -#include - -/* -Start, funzionamento: L'utente scrivendo start da shell (interna a MentOS) avviera' la registrazione di un numero -fissato di PID. -Tre tipologie di parametri/flag accettati dalla start: - - -start --> avvia la recording senza alcun parametro (ci aspettiamo file con PID 1 e 2 alternati) - -start -p --> avvia la recording utilizzando anche la funzione fork, cosi da far vedere nel file PID diversi (almeno inizialmente) - -start -f file.c --> avvia la recording lanciando prima il file passato come parametro - -*/ - -//int clonaccio(int, char *); - -int main(int argc, char *argv[]) -{ - int flag = 0; - - if(argc == 1){ - printf("Start Recording\n"); - printf("End Recording\n"); - return 0; - } - else if(argc == 2 && !(strcmp(argv[1],"-p"))){ - - printf("Start Recording\n"); - - for(int i = 0; i < 5; i++){ - - if(fork()==0){ - exit(1); - } - - } - - for(int i = 0; i < 5; i++){ - wait(NULL); - } - - printf("End Recording\n"); - return 0; - - } - else if( argc==3 && !strcmp(argv[1],"-f") ){ - - char destination[] = "../../bin/tests/"; - strcat(destination,argv[2]); - if(fork()==0){ - flag = execl(destination, "customProgram", NULL, NULL); - if(flag == -1){ - execl("../../bin/startERR","error", NULL, NULL); - } - } - wait(NULL); - - /* - if(flag != -1) - { - printf("Start Recording\n"); - printf("End Recording\n"); - }*/ - - int fd; - mode_t flag1 = 000111; - char destination1[] = "../../bin/tests/"; - strcat(destination1,argv[2]); - fd = open(destination1, S_IRUSR, flag1); - if( fd != -1 ){ - printf("Start Recording\n"); - printf("End Recording\n"); - close(fd); - } - else{ - printf("start: file '%s' not found!\n\n", destination1); - } - - - return 0; - } - - if(argc != 1){ - //se arriviamo qui, significa che sono stati passati parametri errati - if(strcmp(argv[1],"-f")){ - printf("start: start has no command '%s'\n\n", argv[1]); - execl("../../bin/startERR","error", NULL, NULL); - } - else{ - printf("start: missing FILE for OPTION '%s'\n\n", argv[1]); - execl("../../bin/startERR","error", NULL, NULL); - } - } - - - /* - if(argc > 1 && (strcmp(argv[1],"-p") && strcmp(argv[1],"-f"))){ //da rafforzare - - }*/ - -} \ No newline at end of file diff --git a/programs/startERR.c b/programs/startERR.c deleted file mode 100644 index ebe8be1..0000000 --- a/programs/startERR.c +++ /dev/null @@ -1,5 +0,0 @@ - -int main(void) -{ - return -1; -} \ No newline at end of file diff --git a/programs/tests/CMakeLists.txt b/programs/tests/CMakeLists.txt index e961136..0055a4e 100644 --- a/programs/tests/CMakeLists.txt +++ b/programs/tests/CMakeLists.txt @@ -61,17 +61,17 @@ set(MENTOS_TESTS_DIR ${CMAKE_SOURCE_DIR}/files/bin/tests) set(TESTS t_mem.c t_fork.c - # Real-time programs + # Test real-time programs. t_periodic1.c t_periodic2.c t_periodic3.c - # Exec + # Testing task execution. t_exec.c t_exec_callee.c # Test environmental variables. t_setenv.c t_getenv.c - # Test: signals. + # Test signals. t_stopcont.c t_sigusr.c t_abort.c @@ -85,9 +85,8 @@ set(TESTS t_kill.c t_itimer.c t_gid.c - - # Testing my program - myProg.c + # Test scheduling feedback tests. + t_schedfb.c ) foreach(TEST ${TESTS}) diff --git a/programs/tests/myProg.c b/programs/tests/myProg.c deleted file mode 100644 index 598de09..0000000 --- a/programs/tests/myProg.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main(void) -{ - printf("File di test\n"); - return 0; -} diff --git a/programs/tests/t_schedfb.c b/programs/tests/t_schedfb.c new file mode 100644 index 0000000..81cf020 --- /dev/null +++ b/programs/tests/t_schedfb.c @@ -0,0 +1,22 @@ +/// @file t_schedfb.c +/// @brief Start the scheduler feedback session. +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + pid_t cpid; + printf("First test, the child will sleep, thus, they will not be scheduled.\n"); + for (int i = 0; i < 10; ++i) { + if ((cpid = fork()) == 0) { + execl("/bin/tests/t_alarm", "t_alarm", NULL); + return 0; + } + } + while (wait(NULL) != -1) continue; + return 0; +} \ No newline at end of file From 8adfe8d8872cd6e16ce87a342ab8051a4f2195d0 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Thu, 20 Apr 2023 09:00:04 +0200 Subject: [PATCH 25/26] Update comments. --- mentos/src/process/scheduler_algorithm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mentos/src/process/scheduler_algorithm.c b/mentos/src/process/scheduler_algorithm.c index 89aa381..c3f8153 100644 --- a/mentos/src/process/scheduler_algorithm.c +++ b/mentos/src/process/scheduler_algorithm.c @@ -23,8 +23,6 @@ /// @param task the task to update. static void __update_task_statistics(task_struct *task); -void feedback(pid_t pid, char name[], pid_t padre, int mode, int prio); - /// @brief Checks if the given task is actually a periodic task. /// @param task the task to check. /// @return true if the task is periodic, false otherwise. @@ -34,12 +32,12 @@ static inline bool_t __is_periodic_task(task_struct *task) return task->se.is_periodic && !task->se.is_under_analysis; } -/// @brief Employs time-sharing, giving each job a timeslice, and is also +/// @brief Employs time-sharing, giving each job a time-slot, and is also /// preemptive since the scheduler forces the task out of the CPU once -/// the timeslice expires. +/// the time-slot expires. /// @param runqueue list of all processes. -/// @param skip_periodic tells the algorithm if there are periodic processes in -/// the list, and in that case it needs to skip them. +/// @param skip_periodic tells the algorithm that periodic processes in the list +/// should be skipped. /// @return the next task on success, NULL on failure. static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_periodic) { From 4e9d0ebaf2fcfea990a8e7e78ed3ec7dea9f8284 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Fri, 21 Apr 2023 16:41:01 +0200 Subject: [PATCH 26/26] Clean up the logging code for the scheduler feedback. --- mentos/src/process/scheduler_feedback.c | 31 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/mentos/src/process/scheduler_feedback.c b/mentos/src/process/scheduler_feedback.c index e062f03..5644844 100644 --- a/mentos/src/process/scheduler_feedback.c +++ b/mentos/src/process/scheduler_feedback.c @@ -64,10 +64,23 @@ struct statistic { unsigned long occur; } arr_stats[PID_MAX_LIMIT]; +/// @brief Updates when the logging should happen. +static inline void __scheduler_feedback_deadline_advance() +{ + next_log = timer_get_ticks() + (LOG_INTERVAL_SEC * TICKS_PER_SECOND); +} + +/// @brief Checks if the deadline is passed. +/// @return 1 if the deadline is passed, 0 otherwise. +static inline int __scheduler_feedback_deadline_check() +{ + return (next_log < timer_get_ticks()); +} + /// @brief Logs the scheduling statistics either on file or on the terminal. static inline void __scheduler_feedback_log() { - pr_debug("Scheduling Statistics (%s)\n", POLICY_NAME); + pr_info("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); @@ -82,10 +95,10 @@ static inline void __scheduler_feedback_log() 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] | %-24s | -> TCPU: %.2f%% \n", - arr_stats[i].task->pid, - arr_stats[i].task->name, - tcpu); + pr_info("[%3d] | %-24s | -> TCPU: %.2f%% \n", + arr_stats[i].task->pid, + arr_stats[i].task->name, + tcpu); #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); @@ -133,8 +146,8 @@ int scheduler_feedback_init() arr_stats[i].task = NULL; arr_stats[i].occur = 0; } - // Set when the first logging should happen. - next_log = timer_get_ticks() + (LOG_INTERVAL_SEC * TICKS_PER_SECOND); + // Update when in the future, the logging should happen. + __scheduler_feedback_deadline_advance(); // Initialize the number of occurrences. total_occurrences = 0; return 1; @@ -165,7 +178,7 @@ void scheduler_feedback_task_update(task_struct *task) void scheduler_feedback_update() { // If it is not yet time for the next reset, skip. - if (next_log >= timer_get_ticks()) { + if (!__scheduler_feedback_deadline_check()) { return; } // Dump on the feedback before reset. @@ -176,7 +189,7 @@ void scheduler_feedback_update() 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); + __scheduler_feedback_deadline_advance(); // Reset the number of occurrences. total_occurrences = 0; }