sendrecv.c


/*************************************************************************
*                                                                        *
*   Modulo di gestione dei messaggi                                      *
*                                                                        *
*   realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96             *
*                                                                        *
*   Lorenzo     Claudio       Valerio    Riccardo    Emiliano            *
*   Coronati    Lanconelli    Paolini    Solmi       Trentini            *
*                                                                        *
**************************************************************************/

#include "../h/types.h"
#include "../h/nucconst.h"

#include "../h/globals.e"
#include "../h/scheduler.e"
#include "../h/msgqueue.e"

void
msgSend(from, to, message)
thr_t *from, *to;
int message;
{
    register state_t *sts;   /* R4 */
    register  msg_t *msg;
    register thr_t *dest = to;

#ifdef  NUC_DEBUG
    if (from == NULL || dest == NULL || !EVEN(dest) || dest < BEGINKERNEL)
        panic("msgSend(): bad parameters");
#endif

    /* controllo che il destinatario sia valido */
    if (dest->t_process != NULL)
    {
        /* il destinatario e' in attesa di un nostro messaggio */
        if (dest->t_waitfrom == from)
        {
            dest->t_s.s_r[4] = from;
            dest->t_s.s_r[3] = message;
            if (from != SSI)
                outWaitThread(&from->t_replyqueue, dest);
            wakeupProc(dest);
        }
        else if (dest->t_waitfrom == ANYSENDER)
        {
            dest->t_s.s_r[4] = from;
            dest->t_s.s_r[3] = message;
            wakeupProc(dest);
        }
        /*
         * il destinatario attende che il gestore di trap finisca il
         * proprio lavoro
         */
        else if (dest->t_waitfrom == ANYTRAP && dest->t_handler == from)
        {
            wakeupProc(dest);
        }
        /*
         * il destinatario non e' in attesa ed il messaggio viene
         * messo in coda
         */
        else if ((msg = allocMessage()) != NULL)
        {
            msg->m_sender = from;
            msg->m_message = message;
            insertMessage(&dest->t_msgqueue, msg);
        }
        else
            panic("No more messages");
    }
    /* caso in cui il destinatario sia stato terminato */
    else
    {

#ifdef  NUC_DEBUG
        error("Message sent to died thread");
#endif

        /*
         * controlla che il mittente non sia proprio il gestore delle
         * program trap
         */

        if (from == from->t_process->p_prgtrap)
            from->t_process->p_prgtrap = NULL;

        sts->s_ps2.p2_pr.pr_typ = SENDTODEADTHR;
        msg = PROGTRAP;
        passup();
    }
}

void
msgRecv()
{
    register state_t *sts;   /* R4 ** passato dalla OnSys() */
    register  msg_t *msg;
    register thr_t *from = sts->s_r[4];

    /* controlla se il messaggio che attendiamo e' arrivato */
    msg = (from == ANYSENDER) ?
        removeMessage(&run_thread->t_msgqueue) :
        keyMessage(&run_thread->t_msgqueue, from);

    /*
     * se il messaggio che attende non e' gia' arrivato, si mette in
     * attesa
     */
    if (msg == NULL)
    {
        if (from == ANYSENDER || from == ANYTRAP)
        {
            SAVESTATE();
            sleepProc(from);
            schedule();
            NEWSTATE();
            LOADTIMER();
            DISPATCH();
        }
        /* controlla che il thread da cui attendiamo non sia morto */
        else if (from->t_process != NULL)
        {
            SAVESTATE();
            if (from != SSI)
                insWaitThread(&from->t_replyqueue, run_thread);
            sleepProc(from);
            schedule();
            NEWSTATE();
            LOADTIMER();
            DISPATCH();
        }
        else
        {
#ifdef  NUC_DEBUG
            error("Waiting from dead thread");
#endif
            sts->s_ps2.p2_pr.pr_typ = RECVFROMDEADTHR;
            msg = PROGTRAP;
            passup();
        }
    }
    else
    {
        sts->s_r[3] = msg->m_message;
        sts->s_r[4] = msg->m_sender;
        freeMessage(msg);
    }
}


[INDICE CODICE]