HP 3000 Manuals

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


Interprocess Communication:Programmer's Guide

Pascal Examples 

The following group of programs (Examples D-4 through D-6) show the use
of message files and soft interrupts for Interprocess Communication.  For
a simpler example, see the sample Pascal program in Chapter 6.

Example D-4. 

     $uslinit$
     program mon(input,output);
     {
        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.
     }

     type
        int = -32768..32767;
        timer = packed record
              hour : 0..255;
              min : 0..255;
              sec : 0..255;
              tenth : 0..255;
           end;
        data_rec = record
                 dataline : packed array [1..28] of char;
                 sequence : int;
                 time : timer;
               end;

     var
        I : int;
        outdata : data_rec;
        pause_val : real;
        file_num : int;
        file_name : packed array [1..10] of char;
        error : int;

     procedure dateline; intrinsic;
     procedure pause; intrinsic;
     function fopen:int; intrinsic;
     procedure fwrite;intrinsic;
     procedure quit; intrinsic;
     procedure fcheck;intrinsic;
     function clock:timer;external;
     begin
     {
        Open message file.
     }
        file_name:='montolog  ';
        file_num := fopen(file_name,5,193);
        if ccode <> 2 then
           begin
              fcheck(file_num,error);
              quit(error);
           end
           else writeln('Opened OK');
        pause_val := 2.0;
        for i:=1 to 100 do
           begin
              outdata.sequence := i;
              dateline(outdata.dataline);
              outdata.time:=clock;
              fwrite(file_num,outdata,-34,0);
              if ccode<>2 then
                 begin
                    fcheck(file_num,error);
                    quit(error);
                 end;
              pause(pause_val);
           end;
     end.

Example D-5. 

     $uslinit$
     $standard_level 'HP3000'$
     {
        LOG

        Pascal 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.
     }
     program log(input,output);

     type
        int = -32768..32767;

     {
        TIMER is a record type which corresponds to the return from
        the CLOCK intrinsic.
     }
        timer = packed record
              hour : 0..255;
              min : 0..255;
              sec : 0..255;
              tenth : 0..255;
           end;

     {
        DATA_REC is a record type which corresponds to the record
        written by the MON program.
     }
        data_rec = record
                 dataline : packed array [1..28] of char;
                 sequence : int;
                 time : timer;
               end;

     var
        fle : text;
        i,lth,addr,parm : int;
        file_num_0,file_num,file_num_1 : int;
        logfile,file_name,file_name_1 : packed array [1..10] of char;
        buff,buff1 : packed array [1..80] of char;
        error : int;

     procedure dateline; intrinsic;
     function fopen:int; intrinsic;
     procedure fwrite;intrinsic;
     procedure quit; intrinsic;
     procedure fcheck;intrinsic;
     procedure getprivmode;intrinsic;
     procedure fintexit;intrinsic;
     procedure fintstate;intrinsic;
     procedure getusermode;intrinsic;
     procedure iowait;intrinsic;
     procedure iodontwait;intrinsic;
     procedure fread;intrinsic;
     procedure fcontrol;intrinsic;
     function clock : timer; external;
     {
        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:int);
        var
           timestamp : timer;
           buffer : data_rec;
        begin
     {
           Get time of interrupt.
     }
           timestamp:=clock;
     {
           Complete I/O from message file.
     }
           iodontwait(filenum,buffer);
           writeln(fle,buffer.dataline,'  ',buffer.sequence);
           writeln(fle,'Time file written= ',buffer.time.hour,':',
                   buffer.time.min,':',buffer.time.sec,':',
                   buffer.time.tenth);
           writeln(fle,'Time interrupted= ',timestamp.hour,':',
                   timestamp.min,':',timestamp.sec,':',
                   timestamp.tenth);
     {
           Restart the message file read.
     }
           fread(filenum,buff,-34);

     {
           Re-enable interrupts when the handler routine exits. Same
           as FINTEXIT(1).  Interesting point--Pascal Boolean values
           are different from SPL logical values.  Pascal TRUE <> SPL TRUE.
     }
           fintexit;
        end;

     begin
     {
        Open LOGFILE as text file.

        LOGFILE is VERY IMPORTANT.  Soft interrupts may interrupt a
        GENERAL NOWAIT I/O as posted below.  However, they may not
        interrupt any other I/O in progress.  If we WRITELN to the
        terminal in the interrupt handler routine, that WRITELN will
        have to wait for the read I/O on the terminal to complete.  Since
        that wait is in the interrupt handler routine, it can't be
        further interrupted.  The bottom line here is that interrupts
        will not be processed except after the terminal I/O completes
        and before a new I/O is started.

        To avoid this, we write to LOGFILE.
     }
        logfile:='LOGFILE   ';
        rewrite(fle,logfile,'NOCCTL');
     {
        Set up interrupts for this program.

        Again, as stated above in the interrupt handler routine, SPL
        TRUE (which is how the intrinsic is defined) = %000001.  Pascal
        TRUE, for a Boolean variable, is %000400.  Therefore, we cannot
        use a Boolean variable here.
     }
        fintstate(1);
     {
        Open the terminal for nowait I/O.
     }
        file_name_1 := 'TERM      ';
        getprivmode;
        file_num_1 := fopen(file_name_1,36,2048);
        if ccode <> 2 then
           begin
              getusermode;
              fcheck(file_num_1,error);
              quit(error);
           end
           else writeln('Opened terminal OK');
        getusermode;

     {
        Open the message file.
     }
        file_name:='montolog  ';
        file_num := fopen(file_name,5,192);
        if ccode <> 2 then
           begin
              fcheck(file_num,error);
              quit(error);
           end
           else writeln('Opened MSGFILE OK');
     {
        Set up soft interrupts.
     }
        addr := waddress(inthandler);
        fcontrol(file_num,48,addr);
     {
        Set up EXTENDED WAIT.  If we don't do this, the read of the
        message file will continually 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 to 100 do
           begin
              fread(file_num_1,buff1,-80);
     {
           The only way we will interrupt an IOWAIT is if we post a
           GENERAL IOWAIT (using 0 for the file number).

           In this case, we don't care to get the return since we know
           which file had a read posted against it.
     }
              file_num_0:=0;
              iowait(file_num_0,buff1,lth);
           end;
        close(fle,'SAVE');
     end.

Example D-6. 

     $uslinit$
     {
        PARENT

        This program is the parent process for MON and LOG.
     }
     program daddy(input,output);
     type
        int = -32768..32767;
     var
        prog_1,prog_2 : packed array[1..10] of char;
        pin,pin1,error,error1 : int;
        nums,items : array[1..5] of int;

     procedure createprocess;intrinsic;
     procedure quit;intrinsic;
     procedure activate;intrinsic;

     begin
        prog_1 := 'mon       ';
        prog_2 := 'log       ';
        nums[1]:=3;
        items[1]:=1;
        nums[2]:=0;
        items[2]:=0;
        createprocess(error,pin,prog_1,nums,items);
        if error<>0 then quit(error);
        activate(pin);
        writeln('Process MON created');
        nums[2]:=10;
        items[2]:=2;
        nums[3]:=0;
        items[3]:=0;
        createprocess(error1,pin1,prog_2,nums,items);
        if error<>0 then quit(error);
     end.



MPE/iX 5.0 Documentation