/*************************************************************************
* *
* Modulo di gestione delle richieste di servizio *
* *
* realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96 *
* *
* Lorenzo Claudio Valerio Riccardo Emiliano *
* Coronati Lanconelli Paolini Solmi Trentini *
* *
**************************************************************************/
#include "../h/thrqueue.h"
#include "../h/nucconst.h"
#include "../h/globals.e"
#include "../h/proctree.e"
#ifdef NUC_PROFILE
int ssi_count;
#endif
/* corpo del processo S.S.I. (costituito da un solo thread) */
void
ssi_main()
{
register thr_t *sender; /* R4 */
register ssimsg *msg; /* R3 */
register ioreply_t *iorp;
long s_time0, s_time1;
int reply_now; /* se TRUE il msg di risposta va inviato
* prima della prossima MSGRECV */
while (TRUE)
{
reply_now = TRUE;
/* ricezione richieste di servizio */
sender = ANYSENDER;
DO_MSGRECV();
/*
* disabilita le interruzioni per assicurarsi la mutua
* esclusione nell'accedere ai dati del nucleo
*/
DISABLEINTR();
STCK(&s_time0);
#ifdef NUC_PROFILE
ssi_count++;
#endif
/* esegue il servizio richiesto */
switch (msg->s.service)
{
case CREAPROC:
msg->thr = createProc(sender, (state_t *) msg->s.ssip);
break;
case TERMPROC:
termProc(sender);
reply_now = FALSE;
sender = NULL;
break;
case CREATHREAD:
msg->thr = createThread(sender, (state_t *) msg->s.ssip);
break;
case TERMTHREAD:
termThread(sender);
reply_now = FALSE;
sender = NULL;
break;
case SETPRGTRAP:
sender->t_process->p_prgtrap = (thr_t *) msg->s.ssip;
break;
case SETMEMTRAP:
sender->t_process->p_memtrap = (thr_t *) msg->s.ssip;
break;
case SETSYSTRAP:
sender->t_process->p_systrap = (thr_t *) msg->s.ssip;
break;
case WAITIO:
iorp = io_reply + DEVNO(msg->s.ssip);
if (iorp->status == NONE)
{
no_wait++;
iorp->u.r.sender = sender;
iorp->u.r.msg = msg;
iorp->status = WAIT;
reply_now = FALSE;
}
else
{
#ifdef NUC_DEBUG
if (iorp->status == WAIT)
panic("Nested I/O request");
#endif
msg->d.sts = iorp->u.d.sts;
msg->d.len = iorp->u.d.len;
iorp->status = NONE;
}
break;
case WAITCLOCK:
#ifdef NUC_DEBUG
if (clock_reply != NULL)
panic("Nested pseudo clock request");
#endif
no_wait++;
clock_reply = sender;
reply_now = FALSE;
break;
case GETCPUTIME:
msg->l = sender->t_process->p_cputime;
break;
#ifdef NUC_DEBUG
default:
panic("Undefined service");
break;
#endif
}
/*
* addebita il tempo di esecuzione del servizio al thread
* richiedente.
*/
if (sender != NULL)
{
STCK(&s_time1);
sender->t_process->p_cputime += s_time1 - s_time0;
}
ENABLEINTR();
/* restituisce il risultato */
if (reply_now == TRUE)
DO_MSGSEND();
}
}