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

Commit

Permalink
Migliorata gestione scheduler #12, gestione SpecPassup
Browse files Browse the repository at this point in the history
Refactoring di alcune funzioni dello scheduler
Parizialmente implementata System call 6 #19
Aggiunta System call 7 SpecPassup #19
Aggiunta gestione SpecPassup dove necessario negli handler
  • Loading branch information
jjak0b committed Apr 30, 2020
1 parent 9e2cff5 commit 0c4bd68
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 95 deletions.
6 changes: 6 additions & 0 deletions include/handler/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ void Handler_SysCall(void);
* @param request Puntatore alla SYS/BP New Area
*/
void handle_syscall(state_t *request);

/**
* @brief Gestore specifico per BREAKPOINT.
* @param request Puntatore alla SYS/BP New Area
*/
void handle_breakpoint(state_t *request);
//-------------------------------------------------------

// Trap Handler functions and define
Expand Down
44 changes: 41 additions & 3 deletions include/handler/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,49 @@

#include <system/system.h>

#define SYSNO2INDEX( n )( (n)-1 )

#define SYS_SPECPASSUP_TYPE_SYSBK 0
#define SYS_SPECPASSUP_TYPE_TLB 1
#define SYS_SPECPASSUP_TYPE_PGMTRAP 2

void SpecPassup_init();

/**
* @brief Indica se è stato definito un handler superiore del tipo fornito
*
* @param type
* @return int boooleano
*/
int IsSetSpecPassup( int type );

/**
* @brief Imposta l'area fornita come handler superiore del tipo fornito
*
* @param type
* @param area
* @return int
* - 0 se è l'area stata impostata correttamente
* - -1 se il tipo fornito non è gestito, area == NULL, oppure se è già stata assegnata un'area all'handler del tipo specifiato
*/
int SetSpecPassup( int type, state_t *area );

/**
* @brief Restituisce il puntatore dello stato dell'handler superiore, associato al tipo specificato
*
* @param type
* @return state_t*
* - NULL se IsSetSpecPassup avrebbe restituito TRUE
* - l'area altrimenti
*/
state_t *GetSpecPassup( int type );

/**
* @brief Chiamante di system call che dati dei parametri forniti, chiama la specifica system call con i parametri dati
* @PostCondition valgono tutte le PostCondition delle system call
* inoltre, se è gestita internamente saranno passati solo i paramentri necessari alla system call,
* altrimenti se definita una SPECPASSUP saranno passati tutti i paramentri forniti
* altrimenti se definita una SPECPASSUP, sarà caricato il contesto specificato sul processore
* Se la syscall ritorna un valore, il suo valore è assegnato a returnValueAddr;
* @PreCondition returnValueAddr != NULL
* @param sysno codice identificativo della system call
* @param currState ultimo stato del processo in esecuzione
Expand All @@ -32,11 +70,11 @@ int Sys3_TerminateProcess( void *pid );

void Sys4_Verhogen( int* semaddr );

void Sys5_Passeren( state_t* currState, int* semaddr );
void Sys5_Passeren( int* semaddr );

int Sys6_DoIO( word command, word *devreg, int subdevice );

int Sys7_SpecPassup( int type, state_t *old_area, state_t *new_area );
int Sys7_SpecPassup( state_t* currState, int type, state_t *old_area, state_t *new_area );

int Sys8_GetPID( void **pid, void **ppid );
#endif
51 changes: 35 additions & 16 deletions include/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
/*
Ciclo di vita dello scheduler:
(Per # si intende un evento che genera l'interruzione dell'esecuzione )
(Per @ si intende una possibile gestione dell'evento)
-> scheduler_init()
-> scheduler_main()
-> scheduler_StateToRunning() -> # -> scheduler_StateToTerminate()
^ |
| |
scheduler_StateToready() <----|
-> scheduler_schedule() -> # -> scheduler_UpdateContext() -> V
^ |
| @ ----> scheduler_StateToTerminate()
-------------------------------scheduler_StateToReady<-@
^ :
| :
scheduler_StateToWaiting<-@
*/
struct scheduler_t {
Expand All @@ -26,6 +30,9 @@ struct scheduler_t {
/* puntatore al descrittore del processo in esecuzione */
pcb_t* running_p;

/* booleano indicante se il processo attuale non può continuare lo scheduling (TRUE) oppure continuare mantenere il processo schedulato (FALSE) */
int b_force_switch;

};
typedef struct scheduler_t scheduler_t;

Expand All @@ -44,50 +51,62 @@ void scheduler_init();
int scheduler_main();

/**
* @brief Avvia l'esecuzione del prossimo processo nella ready queue per un TIME_SLICE, impostando tale valore al Interrupt Timer
* @brief Aggiorna lo stato del processo tracciato in esecuzione, con quello fornito
*
* @param state
*/
void scheduler_UpdateContext( state_t* state );

/**
* @brief Avvia l'esecuzione dell'algoritmo dello scheduler che in base alle circostanze può:
* - continuare l'esecuzione del processo attuale;
* - sospendere il processo attuale e scegliere ed avviare il prossimo processo nella ready queue per un TIME_SLICE, impostando tale valore al Interrupt Timer
* Se la coda dei processi ready non è vuota,
* Sceglie il processo dalla ready queue con priorità più alta
* Imposta l' interrupt timer a TIME_SLICE
* e carica lo stato del processo sul processore
* Dopo questo la funzione non dovrebbe restituire poichè il controllo dell'esecuzione è passato al processo
* Se ciò avviene è dovuto ad un errore di LDST.
* @PreCondition Prima di chiamare questa funzione, è necessario chiamare scheduler_StateToReady o scheduler_StateToTerminate
* per aggiornare il contesto dell'ultimo processo eseguito
* @PreCondition Prima di chiamare questa funzione, è necessario chiamare scheduler_UpdateContext() per aggiornare il contesto del processo attuale
*
* @param b_force_switch se TRUE lo scheduler è forzato a cambiare il processo da eseguire
* @return int
* * manda Il sistema in HALT se la coda dei processi è vuota
* * -1 se non è stato caricato lo stato di un nuovo processo, senza cambiare il controllo di esecuzione ( malfunzionamento LDST )
*/
int scheduler_StateToRunning();
int scheduler_schedule( int b_force_switch );

/**
* @brief Aggiorna lo stato del processo fornito al processo corrente;
* effettua un azione di aging per tutti gli elementi nella ready queue;
* ripristina la priorità originale del processo che era in esecuzione
* @brief Ripristina la priorità originale del processo che era in esecuzione
* Disassocia il processo in esecuzione dallo scheduler
* @PostCondition Dopo questo stato è necessario richiamare scheduler_StateToRunning per procedere con la schedulazione dei processi
* @PreCondition Prima di chiamare questa funzione, è necessario chiamare scheduler_UpdateContext() per aggiornare il contesto del processo attuale
* @PostCondition Dopo questo stato è necessario richiamare scheduler_schedule per procedere con la schedulazione dei processi
*
* @param state stato del processo che era in esecuzione
* @return int
* * 1 se non c'è alcun processo tracciato dallo scheduler in esecuzione
* * 0 altrimenti se l'inserimento in ready queue è avvenuto correttamente
*/
int scheduler_StateToReady( state_t* state );
int scheduler_StateToReady();

/**
* @brief aggiunge il processo corrente alla ASL con associato la chiave fornita
*
* @param state stato del processo attuale da aggiornare
* @PreCondition Prima di chiamare questa funzione, è necessario chiamare scheduler_UpdateContext() per aggiornare il contesto del processo attuale
* @PostCondition Dopo questo stato è necessario richiamare scheduler_schedule per procedere con la schedulazione dei processi
* @param semKey chiave da associare al semaforo
* @return int
* * -1 se nessun processo è attualmente assegnato come processo corrente
* * 0 se l'operazione è stata effettuata correttamente
* * 1 se non è stato possibile aggiungere il processo corrente alla ASL (impossibile allocare semaforo)
*/
int scheduler_StateToWaiting( state_t *state, int* semKey );
int scheduler_StateToWaiting( int* semKey );

/**
* @brief Dealloca il descrittore del processo che era in esecuzione, rimuovendo eventualmente la sua progenie
*
* @PreCondition Prima di chiamare questa funzione, è necessario chiamare scheduler_UpdateContext() per aggiornare il contesto del processo attuale
* @PostCondition Dopo questo stato è necessario richiamare scheduler_schedule per procedere con la schedulazione dei processi
* @return int
* * 1 se non c'è alcun processo tracciato dallo scheduler in esecuzione
* * 0 altrimenti se è avvenuto tutto correttamente
Expand Down
1 change: 0 additions & 1 deletion include/umps/umpsconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#define RAMSIZE *((unsigned int *)BUS_REG_RAM_SIZE)
#define RAM_TOP (RAMBASE + RAMSIZE)

#define FRAMESIZE (4096)

#define STATUS_NULL 0x00000000
#define INTERRUPT_ON (STATUS_IEp)
Expand Down
98 changes: 83 additions & 15 deletions src/handler/shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,35 @@
#include <asl/asl.h>
#include <pcb/pcb.h>

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 */

void SpecPassup_init() {
bitmap_specPassup = 0;
}

int IsSetSpecPassup( int type ) {
byte mask_specPassup_type = 1 << type;
return (bitmap_specPassup & mask_specPassup_type) == mask_specPassup_type;
}

int SetSpecPassup( int type, state_t *area ) {
if( area != NULL && ( type >= 0 && type <= 2 ) && !IsSetSpecPassup( type ) ) {
/* copia la area corrispondente e imposta l'i-esmi bit della bitmap relativo al tipo fornito*/
moveState(area, &specPassup[ type ]);
bitmap_specPassup |= (1 << type);
return TRUE;
}
return FALSE;
}

state_t *GetSpecPassup( int type ) {
if( IsSetSpecPassup( type ) ) {
return &specPassup[ type ];
}
return NULL;
}

word Syscaller( state_t *state, word sysNo, word param1, word param2, word param3, word *returnValue ) {
int b_hasReturnValue = FALSE;
switch( sysNo ) {
Expand All @@ -42,23 +71,32 @@ word Syscaller( state_t *state, word sysNo, word param1, word param2, word param
Sys4_Verhogen( (int*)param1 );
break;
case PASSEREN:
Sys5_Passeren( state, (int*)param1 );
Sys5_Passeren( (int*)param1 );
break;
case WAITIO:
b_hasReturnValue = TRUE;
*returnValue = (int) Sys6_DoIO( param1, (word*)param2, (int)param3 );
break;
case SPECPASSUP:
b_hasReturnValue = TRUE;
*returnValue = (int) Sys7_SpecPassup( (int)param1, (state_t*)param2, (state_t*)param3 );
*returnValue = (int) Sys7_SpecPassup( state, (int)param1, (state_t*)param2, (state_t*)param3 );
break;
case GETPID:
b_hasReturnValue = TRUE;
*returnValue = (int) Sys8_GetPID( (void**)param1, (void**)param2 );
break;
default:
// TODO: rendere gestibile da handler di SPECPASSUP
default: {
state_t *area = GetSpecPassup( SYS_SPECPASSUP_TYPE_SYSBK );
if( area != NULL ) {
LDST( area );
}
else {
b_hasReturnValue = TRUE;
*returnValue = -1;
scheduler_StateToTerminate( FALSE );
}
break;
}
}

return b_hasReturnValue;
Expand All @@ -75,12 +113,13 @@ int Sys2_CreateProcess( state_t *state, int priority, void **cpid ) {

int Sys3_TerminateProcess( void *pid ) {
if( pid != NULL ) {
// TODO: da cambiare gestione
// TODO: da cambiare gestione usando PID
scheduler_StateToTerminate(TRUE);
scheduler_StateToRunning();
return 0;
}
else {
// TODO
scheduler_StateToTerminate(TRUE);
return 0;
}

return -1;
Expand All @@ -97,27 +136,56 @@ void Sys4_Verhogen( int* semaddr ) {
}
}

void Sys5_Passeren( state_t* state, int* semaddr ) {
void Sys5_Passeren( int* semaddr ) {
if( *semaddr <= 0 ) {
scheduler_StateToWaiting( state, semaddr );
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
scheduler_StateToRunning();
}
else {
(*semaddr) --;
}
}

int Sys6_DoIO( word command, word *devreg, int subdevice ) {
// TODO
int DeviceIsTerminal( devreg_t *devreg ) {
int i;
for( i = 0; i < N_EXT_IL; i++ ) {
devreg_t *test = (devreg_t*)DEV_REG_ADDR( IL_TERMINAL, i );
if( devreg == test ) {
return TRUE;
}
}
return FALSE;
}

int Sys6_DoIO( word command, word *devregAddr, int subdevice ) {

devreg_t * devreg = (devreg_t*)devregAddr;
if( subdevice || DeviceIsTerminal( devreg ) ) {
if( subdevice ) {
devreg->term.transm_command = command;
}
else {
devreg->term.recv_command = command;
}
}
else {
devreg->dtp.command = command;
}

// TODO inserire questo processo in coda di attesa del device
return -1;
}

int Sys7_SpecPassup( int type, state_t *old_area, state_t *new_area ) {
// TODO
int Sys7_SpecPassup( state_t* currState, int type, state_t *old_area, state_t *new_area ) {
if( SetSpecPassup( type, new_area ) ) {
moveState( currState, old_area );
return 0;
}

scheduler_StateToTerminate( FALSE );
return -1;
}

Expand Down
Loading

0 comments on commit 0c4bd68

Please sign in to comment.