ssi.c


/*************************************************************************
*                                                                        *
*   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();
    }
}


[INDICE CODICE]