Re: Mars Rover Controlled By Java

From: James Rogers (jimmaureenrogers_at_att.net)
Date: 01/23/04


Date: Fri, 23 Jan 2004 04:04:41 GMT

nmm1@cus.cam.ac.uk (Nick Maclaren) wrote in
news:bup5f4$4pv$1@pegasus.csx.cam.ac.uk:

> In article <40101402.D7909770@yahoo.com>,
> CBFalconer <cbfalconer@worldnet.att.net> wrote:
>>Nick Maclaren wrote:
>>>
>>... snip ...
>>>
>>> I know of no major language that specifies semantics down to the
>>> level needed for asynchronous signal handling, unfortunately.
>>
>>Ada.
>
> When I last looked, it didn't, not even remotely. I don't know whether
> the designers of that aspect didn't understand the issues, or knew
> that they were so foul that they deliberately did not permit them.
> There were probably some people in each category :-)

Ada does not use the volatile semantics for asynchronous signal handling.
Ada does define a pragma volatile. It is used to force direct writes to
memory. Unfotunately, that is not enough to properly support concurrent
access to a shared memory. A task may be interrupted in the middle of
a read or write, leaving the memory region in an invalid state, while
another task attempts to access the memory region.

Ada provides pragma atomic to specify that the programmer wants all
reads and writes to a memory region to be atomic. Unfortunately, only
data types the size of a word on the execution platform can support
atomic operations.

When handling signals Ada provides a higher level abstraction that
works remarkably well in a concurrent environment.

A procedure of a protected object is associated with a particular
signal. That procedure will be called when the signal is caught by
the Ada program. The procedure will have exclusive access to the
data members of the protected object. That protected object will
also contain an entry. The entry will be called by the signal servicing
task. The task will suspend until the signal is caught.

I believe an example is needed.

-----------------------------------------------------------------------
-- Package Handler
-- Defines the interface for a signal handler
-----------------------------------------------------------------------
with Ada.Interrupts.Names;
use Ada.Interrupts.Names;

package Handler is
   protected Int_Handler is
      procedure Increment;
      entry Wait_For_Interrupt;
      pragma Attach_Handler(Increment, Sigint);
   private
      Counter : Natural := 0;
   end Int_Handler;
   
   task Responder is
      entry Stop;
   end Responder;
end Handler;

-----------------------------------------------------------------------
-- Package Body Handler
-- Defines implementation of the signal handler
-----------------------------------------------------------------------
with Ada.Text_Io;

package body Handler is
   protected body Int_Handler is
      procedure Increment is
      begin
         Counter := Counter + 1;
      end Increment;
      entry Wait_For_Interrupt when Counter > 0 is
      begin
         Counter := Counter - 1;
      end Wait_For_Interrupt;
   end Int_Handler;

   task body Responder is
      Num_Ints : Natural := 0;
   begin
      loop
         select
            Int_Handler.Wait_For_Interrupt;
            Num_Ints := Num_Ints + 1;
            Ada.Text_Io.Put_Line("Handled interrupt number" &
               Natural'Image(Num_Ints));
         or
            delay 0.001;
            select
               accept Stop;
               exit;
            or
               delay 0.0;
            end select;
         end select;
      end loop;
   end Responder;
end Handler;

Every time the signal Sigint is caught the procedure Increment is
executed. Increment simply increments Counter. At the same time we
have the task Responder. Responder calls Wait_For_Interrupt. If
the Counter member of Int_Handler is greater than 0 the task
immediately prints its message and loops back to handle another
interrupt. Wait_For_Interrupt decrements Counter so that each
interrupt is handled only once. If Counter is 0 the Responder task
will suspend. Inside the Responder task the call to Wait_For_Interrupt
is performed conditionally within a select structure. If the 0.001
second delay expires before the interrupt occurs the call to
Wait_For_Interrupt is cancelled and the task checks its Stop
entry to see if some other task has called Stop. If so, the loop
exits and the task terminates. If not, the task immediately
again calls Wait_For_Interrupt.

An example of using this package is the following procedure:

-----------------------------------------------------------------------
-- Procedure Handler_Test
-- This is a program demonstrating interrupt handling
-----------------------------------------------------------------------
with Ada.Text_Io;
with Handler;

procedure Handler_Test is
begin
   for Num in 1..20 loop
      Ada.Text_Io.Put_Line("Iteration" & Integer'Image(Num));
      delay 0.5;
   end loop;
   Handler.Responder.Stop;
end Handler_Test;

Note that volatile attributes are not used. Instead, the Ada
approach is to use an implementation of a monitor, with the
procedure attached to a specified interrupt.

Jim Rogers



Relevant Pages

  • Re: Using SetConsoleCtrlHandler
    ... you rely on recursive lock acqusition in your "signal handler" - hard to ... POSIX signals to POSIX processes". ... "Kernel mode APCs interrupt a thread and execute a procedure without ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Using SetConsoleCtrlHandler
    ... "bare minimum" principal should work even in multithreaded POSIX apps, ... you rely on recursive lock acqusition in your "signal handler" - hard to ... POSIX signals to POSIX processes". ... "Kernel mode APCs interrupt a thread and execute a procedure without ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Using SetConsoleCtrlHandler
    ... Assuming the signal handler does the minimum (ie. set a global, ... Only a single-threaded POSIX ... POSIX signals to POSIX processes". ... "Kernel mode APCs interrupt a thread and execute a procedure without the ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Gforth and Unix signal handling
    ... ' (handler) signal# signal handler ... complicated by the ONESHOT nature of linux signals. ... (alarm) re-alarm do stuff here; ... systematic cleanup of open files, dynamic memory, etc., on interrupt. ...
    (comp.lang.forth)
  • Re: SetConsoleCtrlHandler
    ... This modified handler does not call ... signals. ... This allows the service to continue running after the user logs ... If the service installs its own console control handler, ...
    (microsoft.public.win32.programmer.kernel)