HPlogo Interprocess Communication: Programmer's Guide: HP 3000 MPE/iX Computer Systems > Appendix D Sample Programs: Software Interrupts

SPL Examples

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

 » Index

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. 
Feedback to webmaster