HP 3000 Manuals

SPL Examples [ Interprocess Communication:Programmer's Guide ] MPE/iX 5.0 Documentation


Interprocess Communication:Programmer's Guide

SPL Examples 

Examples D-1 through D-3 are a group of SPL programs showing the use of
software interrupts and message files in Interprocess Communication.  A
group of sample Pascal programs follows.

Example D-1. 

     begin
     <<
        MON

        This program opens message file MONTOLOG and writes a data record
        every 2 seconds. The data record is the dateline plus the 2-word
        return from the CLOCK intrinsic.
     >>
        integer i,file'num,error;
        double timer;
        integer array timer1(*)=timer;
        logical array outdata(0:16);
        integer sequence;
        byte array file'name(0:9):="MONTOLOG  ";
        byte array msg1(0:9):="Opened OK ";
        real pause'val;
        intrinsic print,dateline,pause,fopen,fwrite,quit,fcheck,clock;

     <<
        Open message file.
     >>
        file'num:=fopen(file'name,5,193);
        if <> then
           begin
              fcheck(file'num,error);
              quit(error);
           end
        else print(msg1,-10,0);
        pause'val:=2.0;
        for i:=1 until 100 do
           begin
              sequence:=i;
              timer:=clock;
              dateline(outdata);
              outdata(14):=sequence;
              outdata(15):=timer1(0);
              outdata(16):=timer1(1);
              fwrite(file'num,outdata,-34,0);
              if <> then
                 begin
                    fcheck(file'num,error);
                    quit(error);
                 end;
              pause(pause'val);
           end;
     end.

Example D-2. 

     $control uslinit
     <<

        LOG

        SPL program to demonstrate soft interrupts in a process
        handling environment.

        This program opens $STDIN nowait. It opens a message file
        (MONTOLOG) and enables soft interrupts. It then opens a log
        file (LOGFILE) to write progress messages from the interrupt
        handler.
     >>

     begin
        integer i,lth,addr,parm,error,file'num'0:=0;
        integer log'file'num,file'num,file'num'1;
        integer plabel;
        logical array buff(0:39),buff1(0:39);
        byte array file'name(0:9):="MONTOLOG  ";
        byte array file'name'1(0:9):="TERM      ";
        byte array log'file'name(0:9):="LOGFILE   ";
        logical array stat1(0:8):="Opened terminal OK";
        logical array stat2(0:8):="Opened MSGFILE OK ";
        logical array stat3(0:8):="Opened LOGFILE OK ";

        intrinsic dateline,pause,fopen,quit,fcheck,getprivmode,
                  fintexit,fintstate,getusermode,iowait,iodontwait,
                  fread,fcontrol,clock,ascii,print,fclose,fwrite;

        procedure getasc(num,temp);
           BYTE ARRAY num;
           INTEGER temp;
           begin
              integer lth;

              lth:=ascii(temp,10,num);
              if lth=1 then
                 begin
                    num(1):=num(0);
                    num(0):="0";
                 end;
           end; <<getasc>>

     <<
         INTERRUPT HANDLER ROUTINE

           When an interrupt occurs on the message file (filenum), we
           get the time of the interrupt using the CLOCK intrinsic.
           The time the record was written into the message file
           is written as part of the record in the message file.  We
           extract that time as well and write both times into our
           log file.
     >>
        procedure inthandler(filenum);
           VALUE filenum;
           integer filenum;

           begin
           logical array outdata(0:16);
     <<
        Since we must extract the bytes for the CLOCK intrinsic,
        we must equivalence an integer to the double integer returned
        by CLOCK. Could have used a byte array here, just didn't choose
        to.
     >>
           double timestamp;
           integer array time1(*)=timestamp;

           integer temp;
           byte array msg1(0:29),msg2(0:29),num(0:5);

     <<
           Get time of interrupt.
     >>
           timestamp:=clock;
     <<
           Complete I/O from message file.
     >>
           iodontwait(filenum,outdata);
           move msg1:="Time file written=   :  :  :   ";
           move msg2:="Time interrupted =   :  :  :   ";
     <<

           In this section, we convert the proper clock bits to times
           which can be printed as part of the above messages. Long
           and involved, but that's a problem with SPL.
     >>
     <<
           First we must extract the timestamp from the message file
           record.
     >>

     <<
           Extract hour.
     >>
                 temp:=outdata(15).(0:8);
                 getasc(num,temp);
                 move msg1(19):=num,(2);
     <<
           Extract minute.
     >>
                 temp:=outdata(15).(8:8);
                 getasc(num,temp);
                 move msg1(22):=num,(2);
     <<
           Extract second.
     >>
                 temp:=outdata(16).(0:8);
                 getasc(num,temp);
                 move msg1(25):=num,(2);
     <<
           Extract tenth-of-second.
     >>
                 temp:=outdata(16).(8:8);
                 getasc(num,temp);
                 move msg1(28):=num,(2);
     <<
        END of processing for TIME FILE WRITTEN message.
     >>
           fwrite(log'file'num,msg1,-30,0);
           fwrite(log'file'num,outdata,-28,0);
     <<
        Begin processing TIME OF INTERRUPT message.
     >>
     <<
           Extract hour.
     >>
                 temp:=time1(0).(0:8);
                 getasc(num,temp);
                 move msg2(19):=num,(2);
     <<
           Extract minute.
     >>
                 temp:=time1(0).(8:8);
                 getasc(num,temp);
                 move msg2(22):=num,(2);
     <<
           Extract second.
     >>
                 temp:=time1(1).(0:8);
                 getasc(num,temp);
                 move msg2(25):=num,(2);

     <<
           Extract tenth-of-second.
     >>
                 temp:=time1(1).(8:8);
                 getasc(num,temp);
                 move msg2(28):=num,(2);
     <<
        END of processing for TIME OF INTERRUPT message.
     >>
           fwrite(log'file'num,msg2,-30,0);
     <<
        Re-post the message file read.
     >>
           fread(filenum,buff,-34);
     <<
        Re-enable interrupts when the handler routine exits.
        Same effect as FINTEXIT(TRUE).
     >>
           fintexit;
           end;

     <<
        MAINLINE
     >>
        fintstate(1);
     <<
        OPEN $STDIN with NOWAIT I/O.
     >>
        getprivmode;
        file'num'1:=fopen(file'name'1,36,2048);
        if <> then
           begin
              getusermode;
              fcheck(file'num'1,error);
              quit(error);
           end
           else print(stat1,-18,0);
        getusermode;
     <<
        OPEN MONTOLOG as a message file.
     >>
        file'num:=fopen(file'name,5,192);
        if<> then
           begin
              fcheck(file'num,error);
              quit(error);
           end
           else print(stat2,-18,0);

     <<
        OPEN LOGFILE as an OLD ASCII file.

        LOGFILE is VERY IMPORTANT.  If the messages in the interrupt
        routine are posted to the terminal (via PRINT), then we will
        have to wait for the FREAD on the terminal to complete before
        the write will complete.  The IOWAIT can be interrupted when done
        as shown below, but the PRINT cannot be interrupted!  This will
        keep us from processing further interrupts until the status
        messages from the first interrupt have been completed.

        By writing to a file, we avoid this problem.
     >>
        log'file'num:=fopen(log'file'name,5,1);
           if <> then
              begin
                 fcheck(log'file'num,error);
                 quit(error);
              end
           else print(stat3,-18,0);
     <<
        Set up FCONTROL to enable SOFT INTERRUPTS.
     >>
        plabel:=@inthandler;
        fcontrol(file'num,48,plabel);
     <<
        Set up EXTENDED WAIT. If we don't do this, the read of the
        message file will interrupt with FSERR 0 when empty.
     >>
        parm:=1;
        fcontrol(file'num,45,parm);
     <<
        Post read against message file.
     >>
        fread(file'num,buff,-34);
        for i:=1 until 100 do
           begin
              fread(file'num'1,buff1,-80);
     <<
        The only way we will interrupt an IOWAIT is if we post a GENERAL
        IOWAIT. In other words, we use a 0 for the file number.

        In our case here, we don't care to get the return since we know
        which file we posted a read on.
     >>
              iowait(0,,lth);
              print(buff1,-80,0);
           end;
        fclose(log'file'num,1,0);
     end.

Example D-3. 

     $control uslinit
     <<
        PARENT

        This program is the parent process for MON and LOG.

     >>
     begin
        integer array nums(0:5),items(0:5);
        integer pin,pin1,error,error1;
        byte array prog'1(0:9):="MON       ";
        byte array prog'2(0:9):="LOG       ";
        logical array msg1(0:9):="Process MON created ";
        intrinsic print,createprocess,quit,activate;

        nums(0):=3;
        items(0):=1;
        nums(1):=0;
        items(1):=0;
        createprocess(error,pin,prog'1,nums,items);
        if error <>0 then quit(error);
        activate(pin);
        print(msg1,-20,0);
        nums(1):=10;
        items(1):=2;
        nums(2):=0;
        items(2):=0;
        createprocess(error1,pin1,prog'2,nums,items);
        if error1<>0 then quit(error1);
     end.


MPE/iX 5.0 Documentation