services.c


/*************************************************************************
*                                                                        *
*   Modulo: services.c                                                   *
*                                                                        *
*   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/memory.h"
#include "../h/ssimsg.h"
#include "../h/supglobals.e"

extern thr_t *SSI;

int
drum_io(fp, r_w)
frame_t *fp;
int r_w;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    register devreg_t *devaddr = DRUM(0);
    ssimsg_t ssi_msg;

    devaddr->d_badd = (char *)(fp->f_frameno * PAGESIZE);
    devaddr->d_sect = fp->f_segidx * NOPAGES + fp->f_pageno;
    devaddr->d_op = r_w;

    ssi_msg.s.service = WAITIO;
    ssi_msg.s.param = (int)devaddr;
    sender = SSI;
    msg = &ssi_msg;
    DO_MSGSEND();
    DO_MSGRECV();
    if (ssi_msg.io.io_sta != NORMAL)
    {
        /* drum malfunction */
    }
    return ssi_msg.io.io_sta;
}

#ifdef  DISK_ON
/* disk I/O asincrono */
void
adisk_io(ssimsgp, buff, sect_no, r_w)
ssimsg_t *ssimsgp;
char *buff;
int sect_no, r_w;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    register devreg_t *devaddr = DISK(0);

    devaddr->d_badd = buff;
    devaddr->d_sect = sect_no;
    devaddr->d_op = r_w;

    ssimsgp->s.service = WAITIO;
    ssimsgp->s.param = (int)devaddr;
    sender = SSI;
    msg = ssimsgp;
    DO_MSGSEND();
}

/* disk Seek asincrono */
void
adisk_seek(track_no)
int track_no;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    register devreg_t *devaddr = DISK(0);
    static ssimsg_t ssi_msg;

    devaddr->d_track = track_no;
    devaddr->d_op = IOSEEK;

    ssi_msg.s.service = WAITIO;
    ssi_msg.s.param = (int)devaddr;
    sender = SSI;
    msg = &ssi_msg;
    DO_MSGSEND();
}
#endif

int
term_in(term_no, buff)
int term_no;
char *buff;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    register devreg_t *devaddr = TERMINAL(term_no);
    ssimsg_t ssi_msg;

    devaddr->d_badd = buff;
    devaddr->d_op = IOREAD;  

    ssi_msg.s.service = WAITIO;
    ssi_msg.s.param = (int)devaddr;
    sender = SSI;
    msg = &ssi_msg;
    DO_MSGSEND();
    DO_MSGRECV();

    if (ssi_msg.io.io_sta == NORMAL ||
            (ssi_msg.io.io_sta == ENDOFINPUT && ssi_msg.io.io_len > 0))
        return ssi_msg.io.io_len;
    else
        return -ssi_msg.io.io_sta;
}

int
term_out(term_no, buff, count)
int term_no;
char *buff;
int count;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    register devreg_t *devaddr = TERMINAL(term_no);
    ssimsg_t ssi_msg;

    devaddr->d_badd = buff;
    devaddr->d_amnt = count;
    devaddr->d_op = IOWRITE; 

    ssi_msg.s.service = WAITIO;
    ssi_msg.s.param = (int)devaddr;
    sender = SSI;
    msg = &ssi_msg;
    DO_MSGSEND();
    DO_MSGRECV();

    if (ssi_msg.io.io_sta == NORMAL)
        return ssi_msg.io.io_len;
    else    
        return -ssi_msg.io.io_sta;
}

thr_t *
s_service(service, param)
int service;
int param;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    ssimsg_t ssi_msg;

    ssi_msg.s.service = service;
    ssi_msg.s.param = param;
    msg = &ssi_msg;
    sender = SSI;
    DO_MSGSEND();
    DO_MSGRECV();

    return ssi_msg.tres;
}

void
do_terminate(term_no)
int term_no;
{
    register thr_t *sender;     /* R4 */
    register ssimsg_t *msg;     /* R3 */
    ssimsg_t ssi_msg;

    /* segnala al processo inizializzatore la terminazione */
    sender = tprocTable[term_no].T_parent;
    msg = term_no;
    DO_MSGSEND();

    /* richiede la terminazione all'SSI */
    ssi_msg.s.service = TERMPROC;
    sender = SSI;
    msg = &ssi_msg;
    DO_MSGSEND();

    /* attende di essere terminato */
    DO_MSGRECV();
}

void
killTerminal(term_no, str)
register int term_no;
register char *str;
{
    term_out(term_no, str, strlen(str));
    do_terminate(term_no);
}

HIDDEN int
strlen(s)
char *s;
{
    register int i = 0;

    while (*s++)
        i++;

    return i;
}



[INDICE CODICE]