memmant.c


/*************************************************************************
*                                                                        *
*   Memory Management Trap Handler                                       *
*                                                                        *
*   realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96             *
*                                                                        *
*   Lorenzo     Claudio       Valerio    Riccardo    Emiliano            *
*   Coronati    Lanconelli    Paolini    Solmi       Trentini            *
*                                                                        *
**************************************************************************/

#include "../h/supconst.h"
#include "../h/tproc.h"
#include "../h/memory.h"

#include "../h/services.e"
#include "../h/supglobals.e"

/***
 * Il memmant e` uno per ogni T-process e si occupa di intercettare le
 * trap causate dagli accessi in memoria non validi. Quando riceve il
 * controllo guarda il tipo di trap ricevuta. Notare che l'unica trap
 * recuperabile e` "page missing", in tutti gli altri casi termina il
 * T-process (dopo aver stampato un messaggio di errore sul terminale).
 * In caso di "page missing" ricava il SEGNO e il PAGENO dal registro
 * PS2; se il SEGNO e` 0 o 1 termina il T-process anche in questo caso
 * poiche` significa un accesso illegittimo ai dati del nucleo. In caso
 * contrario ricava il puntatore al PD della pagina che ha causato la
 * trap e forma un msg da spedire al page_process (processo servente)
 * che contiene il puntatore al page descriptor, e le informazioni per
 * determinare il blocco immagine all'interno dell'area di scambio.
 * Attende la risposta dal processo servente.
 * Risveglia il thread che ha causato la trap.
 ***/ 

extern thr_t *pager_proc;

void
memmant()
{
    register thr_t *sender;     /* R4 */
    register union {state_t *st; pgmsg_t *pm} msg;   /* R3 */
    register int term_no;       /* R2 inizializzato al numero di terminale */
    pgmsg_t pagemsg;
    thr_t *client;
    tproc_t *tproc;

    /* inizializzazione dati del gestore */
    tproc = tprocTable + term_no;

    while(TRUE)
    {
        sender = ANYSENDER;
        DO_MSGRECV();
        client = sender;

        switch (msg.st->s_ps2.p2_mm.mm_typ)
        {
        case PAGEMISS:
            if (msg.st->s_ps2.p2_mm.mm_seg > SUP1SEG)
            {
                if (msg.st->s_ps2.p2_mm.mm_seg == PRIVSEG)
                {
                    pagemsg.pd = tproc->T_segPpagetable + msg.st->s_ps2.p2_mm.mm_pg;
                    pagemsg.segidx = term_no + 1;
                }
                else
                {
                    pagemsg.pd = segSpagetable + msg.st->s_ps2.p2_mm.mm_pg;
                    pagemsg.segidx = 0;
                }
                pagemsg.pageno = msg.st->s_ps2.p2_mm.mm_pg;

                /* manda la richiesta al processo servente */
                sender = pager_proc;
                msg.pm = &pagemsg;

                DO_MSGSEND();
                DO_MSGRECV();
            }
            else
                killTerminal(term_no, "Support error: nucleus accessed");
            break;
        case ACCESSPROT:
            killTerminal(term_no, "Segmentation violation");
            break;
        case INVPAGE:
            killTerminal(term_no, "Invalid page number");
            break;
        case SEGMISS:
            killTerminal(term_no, "Segmentation fault");
            break;
        default:
            killTerminal(term_no, "Unknown memory trap");
            break;
        }

        sender = client;
        DO_MSGSEND();
    }
}



[INDICE CODICE]