HPlogo Interprocess Communication: Programmer's Guide: HP 3000 MPE/iX Computer Systems > Chapter 6 Software Interrupts

Sample Program--Use of Software Interrupts

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

 » Index

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