home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / adav313.zip / gnat-3_13p-os2-bin-20010916.zip / emx / gnatlib / s-osinte.adb < prev    next >
Text File  |  2000-07-19  |  9KB  |  256 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                 GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS              --
  4. --                                                                          --
  5. --                   S Y S T E M . O S _ I N T E R F A C E                  --
  6. --                                                                          --
  7. --                                  B o d y                                 --
  8. --                                                                          --
  9. --                             $Revision: 1.10 $
  10. --                                                                          --
  11. --            Copyright (C) 1991-2000 Florida State University              --
  12. --                                                                          --
  13. -- GNARL is free software; you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNARL; see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNARL was developed by the GNARL team at Florida State University. It is --
  32. -- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
  33. -- State University (http://www.gnat.com).                                  --
  34. --                                                                          --
  35. ------------------------------------------------------------------------------
  36.  
  37. --  This is the OS/2 version of this package
  38.  
  39. pragma Polling (Off);
  40. --  Turn off polling, we do not want ATC polling to take place during
  41. --  tasking operations. It causes infinite loops and other problems.
  42.  
  43. with Interfaces.C.Strings;
  44. with Interfaces.OS2Lib.Errors;
  45. with Interfaces.OS2Lib.Synchronization;
  46.  
  47. package body System.OS_Interface is
  48.  
  49.    use Interfaces;
  50.    use Interfaces.OS2Lib;
  51.    use Interfaces.OS2Lib.Synchronization;
  52.    use Interfaces.OS2Lib.Errors;
  53.  
  54.    ------------------
  55.    -- Timer (spec) --
  56.    ------------------
  57.  
  58.    --  Although the OS uses a 32-bit integer representing milliseconds
  59.    --  as timer value that doesn't work for us since 32 bits are not
  60.    --  enough for absolute timing. Also it is useful to use better
  61.    --  intermediate precision when adding/substracting timing intervals.
  62.    --  So we use the standard Ada Duration type which is implemented using
  63.    --  microseconds.
  64.  
  65.    --  Shouldn't the timer be moved to a seperate package ???
  66.  
  67.    type Timer is record
  68.       Handle : aliased HTIMER := NULLHANDLE;
  69.       Event  : aliased HEV    := NULLHANDLE;
  70.    end record;
  71.  
  72.    procedure Initialize (T :    out Timer);
  73.    procedure Finalize   (T : in out Timer);
  74.    procedure Wait       (T : in out Timer);
  75.    procedure Reset      (T : in out Timer);
  76.  
  77.    procedure Set_Timer_For (T : in out Timer; Period : in Duration);
  78.    procedure Set_Timer_At  (T : in out Timer; Time   : in Duration);
  79.    --  Add a hook to locate the Epoch, for use with Calendar????
  80.  
  81.    -----------
  82.    -- Yield --
  83.    -----------
  84.  
  85.    --  Give up the remainder of the time-slice and yield the processor
  86.    --  to other threads of equal priority. Yield will return immediately
  87.    --  without giving up the current time-slice when the only threads
  88.    --  that are ready have a lower priority.
  89.  
  90.    --  ???  Just giving up the current time-slice seems not to be enough
  91.    --  to get the thread to the end of the ready queue if OS/2 does use
  92.    --  a queue at all. As a partial work-around, we give up two time-slices.
  93.  
  94.    --  This is the best we can do now, and at least is sufficient for passing
  95.    --  the ACVC 2.0.1 Annex D tests.
  96.  
  97.    procedure Yield is
  98.    begin
  99.       Delay_For (0);
  100.       Delay_For (0);
  101.    end Yield;
  102.  
  103.    ---------------
  104.    -- Delay_For --
  105.    ---------------
  106.  
  107.    procedure Delay_For (Period : in Duration_In_Millisec) is
  108.       Result : APIRET;
  109.  
  110.    begin
  111.       pragma Assert (Period >= 0, "GNULLI---Delay_For: negative argument");
  112.  
  113.       --  ??? DosSleep is not the appropriate function for a delay in real
  114.       --  time. It only gives up some number of scheduled time-slices.
  115.       --  Use a timer instead or block for some semaphore with a time-out.
  116.       Result := DosSleep (ULONG (Period));
  117.  
  118.       if Result = ERROR_TS_WAKEUP then
  119.  
  120.          --  Do appropriate processing for interrupted sleep
  121.          --  Can we raise an exception here?
  122.  
  123.          null;
  124.       end if;
  125.  
  126.       pragma Assert (Result = NO_ERROR, "GNULLI---Error in Delay_For");
  127.    end Delay_For;
  128.  
  129.    -----------
  130.    -- Clock --
  131.    -----------
  132.  
  133.    function Clock return Duration is
  134.  
  135.       --  Implement conversion from tick count to Duration
  136.       --  using fixed point arithmetic. The frequency of
  137.       --  the Intel 8254 timer chip is 18.2 * 2**16 Hz.
  138.  
  139.       Tick_Duration : constant := 1.0 / (18.2 * 2**16);
  140.       Tick_Count    : aliased QWORD;
  141.  
  142.    begin
  143.  
  144.       --  Read nr of clock ticks since boot time
  145.       Must_Not_Fail (DosTmrQueryTime (Tick_Count'Access));
  146.  
  147.       return Tick_Count * Tick_Duration;
  148.    end Clock;
  149.  
  150.    ----------------------
  151.    -- Initialize Timer --
  152.    ----------------------
  153.  
  154.    procedure Initialize (T : out Timer) is
  155.    begin
  156.       pragma Assert
  157.         (T.Handle = NULLHANDLE, "GNULLI---Timer already initialized");
  158.  
  159.       Must_Not_Fail (DosCreateEventSem
  160.         (pszName => Interfaces.C.Strings.Null_Ptr,
  161.          f_phev  => T.Event'Unchecked_Access,
  162.          flAttr  => DC_SEM_SHARED,
  163.          fState  => False32));
  164.    end Initialize;
  165.  
  166.    -------------------
  167.    -- Set_Timer_For --
  168.    -------------------
  169.  
  170.    procedure Set_Timer_For
  171.      (T         : in out Timer;
  172.       Period    : in Duration)
  173.    is
  174.       Rel_Time  : Duration_In_Millisec :=
  175.                     Duration_In_Millisec (Period * 1_000.0);
  176.  
  177.    begin
  178.       pragma Assert
  179.         (T.Event /= NULLHANDLE, "GNULLI---Timer not initialized");
  180.       pragma Assert
  181.         (T.Handle = NULLHANDLE, "GNULLI---Timer already in use");
  182.  
  183.       Must_Not_Fail (DosAsyncTimer
  184.         (msec      => ULONG (Rel_Time),
  185.          F_hsem    => HSEM (T.Event),
  186.          F_phtimer => T.Handle'Unchecked_Access));
  187.    end Set_Timer_For;
  188.  
  189.    ------------------
  190.    -- Set_Timer_At --
  191.    ------------------
  192.  
  193.    --  Note that the timer is started in a critical section to prevent the
  194.    --  race condition when absolute time is converted to time relative to
  195.    --  current time. T.Event will be posted when the Time has passed
  196.  
  197.    procedure Set_Timer_At
  198.      (T         : in out Timer;
  199.       Time      : in Duration)
  200.    is
  201.       Relative_Time : Duration;
  202.  
  203.    begin
  204.       Must_Not_Fail (DosEnterCritSec);
  205.  
  206.       begin
  207.          Relative_Time := Time - Clock;
  208.          if Relative_Time >  0.0 then
  209.             Set_Timer_For (T, Period => Time - Clock);
  210.          else
  211.             Sem_Must_Not_Fail (DosPostEventSem (T.Event));
  212.          end if;
  213.       end;
  214.  
  215.       Must_Not_Fail (DosExitCritSec);
  216.    end Set_Timer_At;
  217.  
  218.    ----------
  219.    -- Wait --
  220.    ----------
  221.  
  222.    procedure Wait (T : in out Timer) is
  223.    begin
  224.       Must_Not_Fail (DosWaitEventSem (T.Event, SEM_INDEFINITE_WAIT));
  225.       T.Handle := NULLHANDLE;
  226.    end Wait;
  227.  
  228.    -----------
  229.    -- Reset --
  230.    -----------
  231.  
  232.    procedure Reset (T : in out Timer) is
  233.       Dummy_Count : aliased ULONG;
  234.  
  235.    begin
  236.       if T.Handle /= NULLHANDLE then
  237.          Must_Not_Fail (DosStopTimer (T.Handle));
  238.          T.Handle := NULLHANDLE;
  239.       end if;
  240.  
  241.       Must_Not_Fail (DosResetEventSem (T.Event, Dummy_Count'Unchecked_Access));
  242.    end Reset;
  243.  
  244.    --------------
  245.    -- Finalize --
  246.    --------------
  247.  
  248.    procedure Finalize (T : in out Timer) is
  249.    begin
  250.       Reset (T);
  251.       Must_Not_Fail (DosCloseEventSem (T.Event));
  252.       T.Event := NULLHANDLE;
  253.    end Finalize;
  254.  
  255. end System.OS_Interface;
  256.