Skip to content
This repository has been archived by the owner on Nov 2, 2022. It is now read-only.

Commit

Permalink
Aggiunte utility per pcb
Browse files Browse the repository at this point in the history
Lo scheduler può rimuovere dalla ready queue ed eliminare tutta progenie di un processo #12
  • Loading branch information
jjak0b committed Mar 21, 2020
1 parent 47059a8 commit a27138b
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 7 deletions.
3 changes: 2 additions & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ handler_f = handler_s + '/handler'
# PCB Module
#--------------------
pcb_f = pcb_s + '/pcb'
pcb_utils_f = pcb_s + '/utils'

# Scheduler Module
#--------------------
Expand Down Expand Up @@ -181,7 +182,7 @@ for i,x in enumerate(umps_headers_list):

# Source (NOEXT) lists
#-------------------
shared_noext_list = [main_f, p15test_f, test_f, shared_f, scheduler_f, pcb_f, handler_f, terminal_f, printer_f, device_f, asl_f]
shared_noext_list = [main_f, p15test_f, test_f, shared_f, scheduler_f, pcb_f, pcb_utils_f, handler_f, terminal_f, printer_f, device_f, asl_f]

# Per favore, lascia i file crtso____ e lib_____ per ultimi
uarm_noext_list = [uarm_shared_f, uarm_sysinit_f, crtso_uarm, libuarm, libdiv_uarm ]
Expand Down
18 changes: 18 additions & 0 deletions include/pcb/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <pcb/pcb.h>

/**
* @brief rimuove tutti i figli di old_parent, aggiungendoli a quelli di new_parent
* @PostCondition Se new_parent == NULL, allora i figli di old_parent saranno senza fratelli e senza padre
* @param old_parent genitore di cui si vuole rimuovere i figli
* @param new_parent il nuovo genitore dei figli
*/
void pcb_SetChildrenParent( pcb_t* old_parent, pcb_t* new_parent );

/**
* @brief Dealloca dopo aver rimosso il descrittore fornito e tutta la sua progenie dalla queue della sentinella fornita
* @PostCondition Non avviene alcuna rimozione nella lista dei fratelli e del padre di p.
*
* @param p descrittore del processo da cui partire a rimuovere la progenie
* @param head queue in cui deve essere rimosso p e tutta la sua progenie
*/
void pcb_RemoveProgenyQ( pcb_t* p, struct list_head *head );
19 changes: 17 additions & 2 deletions include/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ int scheduler_StateToReady( state_t* state );
int scheduler_StateToWaiting();

/**
* @brief Dealloca il descritto del processo che era in esecuzione
* @brief Dealloca il descrittore del processo che era in esecuzione
*
* @return int
* * 1 se non c'è alcun processo tracciato dallo scheduler in esecuzione
* * 0 altrimenti se è avvenuto tutto correttamente
* @param b_flag_terminate_progeny Se TRUE rimuove e dealloca dalla ready queue il descrittore del processo in esecuzione e tutta la sua progenie,
* Se FALSE rimuove e dealloca solo il descrittore in esecuzione, ma tutti i suoi figli non avranno padre e ogni figlio non avrà fratelli
* cioè saranno indipendenti tra loro
*/
int scheduler_StateToTerminate();
int scheduler_StateToTerminate( int b_flag_terminate_progeny );

/**
* @brief Crea un processo, aggiungendolo al ciclo di vita dello scheduler
Expand All @@ -82,4 +85,16 @@ int scheduler_CreateProcess( function_t func, int priority );
*/
void scheduler_AddProcess( pcb_t *p );

/**
* @brief wrapper di pcb_RemoveProgenyQ con passata la ready queue
* @PostCondition Se p è il processo in esecuzione allora viene deassociato nella struttura dello scheduler.
* Non avviene alcuna rimozione nella lista dei fratelli e del padre di p.
*
* @param p descrittore del processo da cui partire a rimuovere la progenie
* @return int
* * 1 Se p == NULL
* * 0 altrimenti
*/
int scheduler_RemoveProgeny( pcb_t* p );

#endif
41 changes: 41 additions & 0 deletions src/pcb/utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <pcb/pcb.h>
#include <pcb/utils.h>

void pcb_SetChildrenParent( pcb_t* old_parent, pcb_t* new_parent ) {

while( !emptyChild( old_parent ) ) {
pcb_t *child = removeChild( old_parent );
if( new_parent != NULL ){
insertChild( new_parent, child );
}
}
}

void pcb_RemoveProgenyQ( pcb_t* p, struct list_head *head ) {
if( p == NULL )
return;

/**
* Aggiunge ricorsivamente i figli di ogni processo ad uno stack di lavoro
* e poi elimina il padre sia dalla queue
* che dallo stack stesso, con conseguente deallocazione
*/
LIST_HEAD( pcb_stack );
list_add( &p->p_next, &pcb_stack );

while( !list_empty( &pcb_stack ) ) {
struct list_head *it_parent = list_next( &pcb_stack );
pcb_t *parent = container_of( it_parent, pcb_t, p_next );
while( !emptyChild( parent ) ){
pcb_t* child = removeChild( parent );

if( head != NULL ){
outProcQ( head, parent );
}

list_add( &child->p_next, &pcb_stack );
}
list_del( &parent->p_next );
freePcb( parent );
}
}
27 changes: 23 additions & 4 deletions src/scheduler/scheduler.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <scheduler.h>
#include <system/shared/shared.h>
#include <utilities/types.h>
#include <pcb/utils.h>

static scheduler_t *scheduler;

Expand Down Expand Up @@ -59,13 +60,32 @@ int scheduler_StateToWaiting() {
return 0;
}

int scheduler_StateToTerminate() {
int scheduler_StateToTerminate( int b_flag_terminate_progeny ) {
if( scheduler->running_p == NULL ){
return 1;
}

freePcb( scheduler->running_p );
scheduler->running_p = NULL;
if( b_flag_terminate_progeny ) {
scheduler_RemoveProgeny( scheduler->running_p );
}
else {
pcb_SetChildrenParent( scheduler->running_p, NULL );
freePcb( scheduler->running_p );
scheduler->running_p = NULL;
}

return 0;
}

int scheduler_RemoveProgeny( pcb_t* p ){
if( p == NULL ){
return 1;
}
else if( scheduler->running_p == p ){
scheduler->running_p = NULL; /* Rimuovo il tracciante di questo descrittore attivo */
}

pcb_RemoveProgenyQ( p, &scheduler->ready_queue );

return 0;
}
Expand All @@ -76,7 +96,6 @@ int scheduler_CreateProcess( function_t func, int priority ) {
return -1;
}
SetPC( &pcb->p_s, (memaddr)func );
SetLR( &pcb->p_s, (memaddr)scheduler_StateToTerminate ); /* Temporaneamente questo è l'indirizzo di ritorno */
/* TODO: SetSP( ); SP dovrebbe essere dinamicamente in base al gestore della memoria */
/* TODO: flag status, ecc ... */
EnableKernelMode( &pcb->p_s, FALSE );
Expand Down

0 comments on commit a27138b

Please sign in to comment.