From 81fac62aee2ef89292c2be4cc96ce78620d103bf Mon Sep 17 00:00:00 2001 From: jjak0b <32840785+jjak0b@users.noreply.github.com> Date: Tue, 5 May 2020 19:34:06 +0200 Subject: [PATCH] Aggiunti semafori con implementazione generica Aggiornato uso di semafori per handler uMPS #20 Aggiornato uso di semafori per Syscall 4-5 #19 Aggiunte funzioni P e V per semafori in utilities Aggiunta scheduler_RemoveProcess per rimuovere un preciso pcb dallo scheduler #12 --- SConstruct | 5 ++++- include/scheduler/scheduler.h | 10 ++++++++++ include/utilities/semaphore.h | 29 +++++++++++++++++++++++++++ src/handler/shared.c | 33 ++++++++++++------------------- src/handler/umps/handler.c | 11 ++++------- src/scheduler/scheduler.c | 11 +++++++++++ src/system/shared/device/device.c | 5 ++++- src/utilities/semaphore.c | 26 ++++++++++++++++++++++++ 8 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 include/utilities/semaphore.h create mode 100644 src/utilities/semaphore.c diff --git a/SConstruct b/SConstruct index 1b5138d..333036b 100644 --- a/SConstruct +++ b/SConstruct @@ -57,6 +57,7 @@ system_s = dir_s + '/system' handler_s = dir_s + '/handler' sysshared_s = system_s + '/shared' device_s = sysshared_s + '/device' +utilities_f = dir_s + '/utilities' # SOURCE dir specifiche per architettura uarm_s = dir_s + '/uarm' @@ -93,6 +94,8 @@ pcb_utils_f = pcb_s + '/utils' #-------------------- scheduler_f = scheduler_s + '/scheduler' +# Utilities Module +util_semaphore_f = utilities_f + '/semaphore' #System Module #-------------------- @@ -173,7 +176,7 @@ for i,x in enumerate(umps_headers_list): # Source (NOEXT) lists #------------------- -shared_noext_list = [main_f, p2test_f, test_f, handler_f, scheduler_f, pcb_f, pcb_utils_f, asl_f, shared_device_f ] +shared_noext_list = [main_f, p2test_f, test_f, handler_f, scheduler_f, pcb_f, pcb_utils_f, asl_f, shared_device_f, util_semaphore_f ] # Per favore, lascia i file crtso____ e lib_____ per ultimi uarm_noext_list = [uarm_shared_f, uarm_handler_f, uarm_sysinit_f, crtso_uarm, libuarm, libdiv_uarm] diff --git a/include/scheduler/scheduler.h b/include/scheduler/scheduler.h index 19d603a..2c00bf6 100644 --- a/include/scheduler/scheduler.h +++ b/include/scheduler/scheduler.h @@ -143,6 +143,16 @@ int scheduler_CreateProcess( memaddr func, int priority ); */ void scheduler_AddProcess( pcb_t *p ); +/** + * @brief Rimuove il descrittore di processo dalla ready queue ed eventualmente disassocia il processo attuale, se è lo stesso pcb fornito + * + * @param p pcb da rimuovere dallo scheduler + * @return int + * TRUE se è stato rimosso con successo + * FALSE se non è presente nella ready queue + */ +int scheduler_RemoveProcess( pcb_t *p ); + /** * @brief wrapper di pcb_RemoveProgenyQ con passata la ready queue dello scheduler * @PostCondition Se p è il processo in esecuzione allora viene deassociato nella struttura dello scheduler e deallocato. diff --git a/include/utilities/semaphore.h b/include/utilities/semaphore.h new file mode 100644 index 0000000..ceb8941 --- /dev/null +++ b/include/utilities/semaphore.h @@ -0,0 +1,29 @@ +#ifndef _UTIL_SEMAPHORE_ +#define _UTIL_SEMAPHORE_ + +#include + +/** + * @brief Decrementa il valore del semaforo, se diventa < 0, allora il processo indicato viene sospeso; + * cioè rimosso dalla ready queue dello scheduler e posto in attesa sulla coda del semaforo specificato + * @PreCondition semkey != NULL + * + * @param semkey + * @param p + * @return int + * FALSE se è stato sospeso correttamente + * TRUE se p == NULL oppure se non è stato possibile allocare un semd per il processo specificato + */ +int semaphore_P( int *semkey, pcb_t * p ); + +/** + * @brief Incrementa il valore del semaforo, se il suo valore diventa <= 0, allora il primo processo in coda + * associato al semaforo specificato è risvegliato; cioè aggiunto alla ready queue + * @PreCondition semkey != NULL + * + * @param semkey + * @return pcb_t* il puntatore al pcb risvegliato + */ +pcb_t *semaphore_V( int *semkey ); + +#endif \ No newline at end of file diff --git a/src/handler/shared.c b/src/handler/shared.c index 7df926f..84675df 100644 --- a/src/handler/shared.c +++ b/src/handler/shared.c @@ -24,6 +24,7 @@ #include #include #include +#include HIDDEN state_t specPassup[3]; /* stati del processore dedicati a handler di livello superiore specifici */ HIDDEN byte bitmap_specPassup; /* bitmap con i flag settati sulle i-esime posizioni se la specPassup[ i ] è assegnata */ @@ -126,26 +127,16 @@ int Sys3_TerminateProcess( void *pid ) { } void Sys4_Verhogen( int* semaddr ) { - pcb_t *blocked = removeBlocked( semaddr ); - if( blocked != NULL ) { - /* dovremmo ripristinare la priorità ? */ - scheduler_AddProcess( blocked ); - } - else { - (*semaddr) ++; - } + semaphore_V( semaddr ); + /* dovremmo ripristinare la priorità ? */ } void Sys5_Passeren( int* semaddr ) { - if( *semaddr <= 0 ) { - int b_result = scheduler_StateToWaiting( semaddr ); - // nel caso ritornasse 1 non può accadere perchè ad ogni processo può essere nella ASL al massimo 1 volta - // infatti se non fosse disponibile un semd, non esisterebbe neanche questo processo - if( b_result == 1 ) scheduler_StateToTerminate( FALSE ); - // sia in caso ritorni 0 o -1 lo scheduler deve proseguire - } - else { - (*semaddr) --; + int status = semaphore_P( semaddr, scheduler_GetRunningProcess() ); + // nel caso ritornasse 1 non può accadere perchè ad ogni processo può essere nella ASL al massimo 1 volta + // infatti se non fosse disponibile un semd, non esisterebbe neanche questo processo + if( status == 1 ) { + scheduler_StateToTerminate( FALSE ); } } @@ -155,9 +146,12 @@ void Sys6_DoIO( word command, word *devregAddr, int subdevice ) { device_GetInfo( devreg, &devLine, &devNo ); int *semKey = device_GetSem( devLine, devNo, subdevice ); - if( *semKey > 0 ) { - --(*semKey); + // un semaforo di un device è sempre almeno inizializzato a 0, e quindi è sempre sospeso + int b_error = semaphore_P( semKey, scheduler_GetRunningProcess() ); + if( b_error ) { + scheduler_StateToTerminate( FALSE ); } + if( devLine == IL_TERMINAL ) { if( subdevice ) { devreg->term.transm_command = command; @@ -169,7 +163,6 @@ void Sys6_DoIO( word command, word *devregAddr, int subdevice ) { else { devreg->dtp.command = command; } - scheduler_StateToWaiting( semKey ); } int Sys7_SpecPassup( state_t* currState, int type, state_t *old_area, state_t *new_area ) { diff --git a/src/handler/umps/handler.c b/src/handler/umps/handler.c index 6d3b3f9..aaf0d5f 100644 --- a/src/handler/umps/handler.c +++ b/src/handler/umps/handler.c @@ -26,6 +26,7 @@ #include #include +#include int get_interrupting_line( state_t *request ); @@ -145,13 +146,9 @@ void Handler_Interrupt(void) { } int *sem = device_GetSem( line, dev, GET_SEM_OFFSET(dev_reg, line) ); /*sem associated with device*/ - if(++(*sem) <= 0){ /*V on this sem*/ - pcb_t *p = removeBlocked(sem); - if(p!=NULL){ - p->p_s.reg_v0 = dev_status; - /*add process to ready queue*/ - scheduler_AddProcess(p); - } + pcb_t *p = semaphore_V( sem ); + if( p != NULL ){ + p->p_s.reg_v0 = dev_status; } scheduler_schedule(FALSE); } diff --git a/src/scheduler/scheduler.c b/src/scheduler/scheduler.c index 0790d01..38befd0 100644 --- a/src/scheduler/scheduler.c +++ b/src/scheduler/scheduler.c @@ -171,3 +171,14 @@ int scheduler_CreateProcess( memaddr func, int priority ) { void scheduler_AddProcess( pcb_t *p ) { insertProcQ( &scheduler->ready_queue, p ); } + +int scheduler_RemoveProcess( pcb_t *p ) { + if( scheduler->running_p == p ) { /* rimuove quello attuale */ + scheduler->running_p = NULL; + scheduler->b_force_switch = TRUE; + return TRUE; + } + else { /* rimuove dalla coda */ + return NULL != outProcQ( &(scheduler->ready_queue), p ); + } +} \ No newline at end of file diff --git a/src/system/shared/device/device.c b/src/system/shared/device/device.c index 27f1cae..076cf53 100644 --- a/src/system/shared/device/device.c +++ b/src/system/shared/device/device.c @@ -4,7 +4,10 @@ HIDDEN int _semdev[SEM_DEV_N]; void device_init() { - + /* semafori device inizializzati a 0, in modo che attendano fino alla risposta (interrupt) */ + int i; + for( i = 0; i < SEM_DEV_N; i++ ) + _semdev[ i ] = 0; } void device_GetInfo( devreg_t *devreg, int *_line, int *_devNo ) { diff --git a/src/utilities/semaphore.c b/src/utilities/semaphore.c new file mode 100644 index 0000000..d24d340 --- /dev/null +++ b/src/utilities/semaphore.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +int semaphore_P( int *semkey, pcb_t * p ) { + int b_error = FALSE; + if( p == NULL ) + return !b_error; + + if( --(*semkey) < 0 ) { + scheduler_RemoveProcess( p ); + b_error = insertBlocked( semkey, p ); + } + return b_error; +} + +pcb_t *semaphore_V( int *semkey ) { + pcb_t *p = NULL; + if( ++(*semkey) <= 0 ) { + p = removeBlocked( semkey ); + if( p != NULL ) + scheduler_AddProcess( p ); + } + return p; +} \ No newline at end of file