HP 3000 Manuals

Sample ProgramUse of Software Interrupts [ Interprocess Communication:Programmer's Guide ] MPE/iX 5.0 Documentation


Interprocess Communication:Programmer's Guide

Sample Program--Use of Software Interrupts 

The following sample program illustrates software interrupts and the use
of the intrinsics discussed earlier in this chapter.  It contains four
sections:  an interrupt handler procedure, a section that arms software
interrupts and passes the plabel of this interrupt handler, the main
processing loop, and a section to disarm software interrupts.

You should note several things about this program.  First, the "main
processing loop" is just a "placeholder" for purposes of illustration; in
a real IPC situation, this section of the program would perform actual
work.  Second, note the use of a "flag" in the disarm section of the
program to prevent the interrupt handler from starting another read of
the message file when interrupts are re-enabled after being postponed.
If you don't use a flag of this sort, your program may go into a
continuous loop in this situation.  For more examples, refer to Appendix
D.

     $uslinit$
     $standard_level 'HP_PASCAL'$
     {
        SOFTWARE INTERRUPT FRAGMENT

        Program including a software interrupt handler, software
        interrupt set-up, and software interrupt shutdown.

     }

     program intfrag1(input,output);

        type
           int = -32768..32767;
           rec = packed array [1..80] of char;

        var
           error,msg_file_num,plabel,dummy : int;
           msg_file_name : packed array [1..8] of char;
           done,need_another_read : boolean;
           msg_rec : rec;
           length : real;

     function fopen : int; intrinsic;
     procedure quit; intrinsic;
     procedure fcheck; intrinsic;
     procedure fintstate; intrinsic;
     procedure fintexit; intrinsic;
     procedure iowait; intrinsic;
     procedure fread; intrinsic;
     procedure fcontrol; intrinsic;
     procedure fclose; intrinsic;
     procedure pause; intrinsic;

     {  INTERRUPT HANDLER ROUTINE  }

     procedure inthandler(local_msg_file_num : int);
        begin

           {  Complete the read on the message file  }
           iowait(local_msg_file_num,msg_rec);
           if ccode <> 2 then
              begin
                 fcheck(msg_file_num,error);
                 quit(error);
              end;

           {  Perform any processing on the incoming record.  }
           writeln(msg_rec);

           {  Restart the read on the message file if needed.  }
           if need_another_read then
              fread(local_msg_file_num,msg_rec,-80);

           {  Re-enable interrupts when handler routine exits.}
           {  Same effect as FINTEXIT(-1).                    }
           fintexit;
        end;

     begin
        need_another_read := true;

        {  INTERRUPT INITIALIZATION  }

        {  Open the file with FOPTION = old, ascii, }
        {   and AOPTION = read only }

        msg_file_name := 'MSGFILE1';
        msg_file_num := fopen(msg_file_name,5,0);
        if ccode <> 2 then
           begin
              fcheck(msg_file_num,error);
              quit(error);
           end;

        {  Arm software interrupts and pass interrupt handler}
        {  procedure address for THIS file.                  }
        plabel := waddress(inthandler);
        fcontrol(msg_file_num,48,plabel);
        if ccode <> 2 then
           begin
              fcheck(msg_file_num,error);
              quit(error);
           end;

        {Enable software interrupts for ALL files with software}
        {interrupts armed by this program.  (-1 = enable)      }
        fintstate(-1);

     { Start first read on message file.  This read acts }
     { like NOWAIT read (no data returned until IOWAIT called) }
     { because software interrupts are armed on this file. }
        fread(msg_file_num,msg_rec,-80);
        if ccode <> 2 then
           begin
              fcheck(msg_file_num,error);
              quit(error);
           end;

        {  MAIN PROCESSING OF PROGRAM  }

        done := false;
        length := 1.0;
        repeat
           begin
              writeln('Another pass through the main processing
               loop.');
              pause(length);
              length := length + 1.0;
              if length = 60.0 then done := true;
           end
        until (done);

        {  DISARMING SOFTWARE INTERRUPTS  }

        done := false;
        repeat
           begin

              { Request MPE to disarm software interrupts.  }
              plabel := 0;
              fcontrol(msg_file_num,48,plabel);

              if ccode = 1 then  { CCL }
                 begin

     {  MPE could not disarm software interrupts because an  }
     {  I/O was started and never completed.  Abort the I/O. }
                    fcontrol(msg_file_num,43,dummy);

                    if ccode = 0 then  { CCG }

        { The I/O has progressed too far to abort.  The only }
        { way this can happen is if software interrupts were }
        { disabled and the interrupt postponed.  Re-enable   }
        { interrupts.  The interrupt will occur immediately. }
        { A flag is set to prevent the interrupt handler     }
        { from starting yet another read.                    }
                       begin
                          need_another_read := false;
                          fintstate(-1);
                       end;
                 end
              else  {Software interrupts successfully disarmed.}
                 done := true;
           end
        until (done);
         { We will never go through this loop more than twice.}

     {  Software interrupts are turned off for this file.  We  }
     {  could do standard FREADs on the file at this point.    }

        fclose(msg_file_num,0,0);
        if ccode <> 2 then
           begin
              fcheck(msg_file_num,error);
              quit(error);
           end;
     end.


MPE/iX 5.0 Documentation