comp.lang.ada
 help / color / mirror / Atom feed
* Interrupt problem in GNAT
@ 1999-05-19  0:00 Joerg Kienzle
  1999-05-19  0:00 ` David C. Hoos, Sr.
  0 siblings, 1 reply; 4+ messages in thread
From: Joerg Kienzle @ 1999-05-19  0:00 UTC (permalink / raw)



Hi,

I am running gnat 3.11w on Solaris, and I am trying to use interrupts to
perform a periodic operation. I have declared the following package:

with Ada.Interrupts; use Ada.Interrupts;
with Ada.Interrupts.Names; use Ada.Interrupts.Names;

package Clocks is

   protected Clock is
      procedure Tick;
      pragma Interrupt_Handler (Tick);
      pragma Attach_Handler (Tick, SIGALRM);
   end Clock;

end Clocks;

And the body:

package body Clocks is

   protected body Clock is

      procedure Tick is
      begin
	--  Do something here
      end Tick;

   end Clock;

end Clocks;

As you can see in the spec, I am trying to attach the Tick procedure
to the SIGALRM signal. In my main procedure, I use the operating
system functions timer_create and timer_settime to tell the OS to
send SIGALRM to my process every x seconds.
This works; the process gets a SIGALRM signal, but my handler function
in not called! Instead, "Alarm clock" is printed on the terminal and
the process exits...
The same thing happens if I use the "alarm" function to send
the SIGALRM signal:

with Interfaces.C;
with Clocks;

procedure Main is

   procedure Alarm (Sec : C.Unsigned);
   pragma Import (C, Alarm, "alarm");

   procedure Set_Alarm (I : in Natural);

   procedure Set_Alarm (I : in Natural) is
   begin
      Alarm (C.Unsigned (I));
   end Set_Alarm;

begin

   Set_Alarm (5);

   while True loop
      null;
   end loop;

end Main;


I tried other signals, but I still doesn't work.
What am I doing wrong?

- J�rg

-- 
---------------------------------------------------------------------------
- Joerg Kienzle - Swiss Federal Institue of Technology - CH-1015
Lausanne -
- email : Joerg.Kienzle@epfl.ch    WWW :
http://lglwww.epfl.ch/~jkienzle/ -
- phone : ++41 21 693 42 37        fax : ++41 21 693 50
79                -




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Interrupt problem in GNAT
  1999-05-19  0:00 Interrupt problem in GNAT Joerg Kienzle
@ 1999-05-19  0:00 ` David C. Hoos, Sr.
  1999-05-20  0:00   ` Joerg Kienzle
  0 siblings, 1 reply; 4+ messages in thread
From: David C. Hoos, Sr. @ 1999-05-19  0:00 UTC (permalink / raw)



Joerg Kienzle wrote in message <3742DC0D.B8F07A52@epfl.ch>...
>
<large snip>
You did not say on which platform you are trying to do this, so
I'm assuming sparc and not x86 Solaris.

There is a problem with what you're trying to do.

   First, if you use the dynamic attach instead of the static (pragma),
   you will find that Interrupt 14 (Sigalrm) is reserved, and Program_Error
   is raised.  Apparently with the static attach, it just silently fails.

   I have always used the dynamic attach myself, but I just tried your
   program with SIGTERM and SIGWINCH, by outputting a line of
   text in the Tick procedure.  Both of those signals work with either
   static or dynamic attach on a SPARCstation-10 with SunOS 5.5.1,
   sending the signals with kill <PID> or kill -WINCH <PID>.

Have you ever considered just using the facilities of Ada to do
what you want?

Using the package for which I have appended source code
to this message (courtesy of Burns and Wellings),

you can have a signal handler that pends at the entry call
Wait.  Then, when the signal arrives it can do its thing, and
loop back to pend on the Wait call again.

Meanwhile, you have a task which does nothing but loop
delaying 6.0 seconds, then calling the Send entry of the
signal on which your handler is pending.

Just a thought -- but such an approach is much more
likely to be portable.

David C. Hoos, Sr.

-- begin source code --
package Persistent_Signals is
   protected type Signal_Type is
      procedure Send;
      entry Wait;
   private
      Signal_Arrived : Boolean := False;
   end Signal_Type;
end Persistent_Signals;

package body Persistent_Signals is
   protected body Signal_Type is
      procedure Send is
      begin
         Signal_Arrived := True;
      end Send;
      entry Wait when Signal_Arrived is
      begin
         Signal_Arrived := False;
      end Wait;
   end Signal_Type;
end Persistent_Signals;
-- end source code --








^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Interrupt problem in GNAT
  1999-05-19  0:00 ` David C. Hoos, Sr.
@ 1999-05-20  0:00   ` Joerg Kienzle
  1999-05-20  0:00     ` David C. Hoos, Sr.
  0 siblings, 1 reply; 4+ messages in thread
From: Joerg Kienzle @ 1999-05-20  0:00 UTC (permalink / raw)



First of all, thanks for your reply!

"David C. Hoos, Sr." wrote:
> 
> Joerg Kienzle wrote in message <3742DC0D.B8F07A52@epfl.ch>...
> >
> <large snip>
> You did not say on which platform you are trying to do this, so
> I'm assuming sparc and not x86 Solaris.

Yes, it's on a Ultra 1 Sparc.

> 
> There is a problem with what you're trying to do.
> 
>    First, if you use the dynamic attach instead of the static (pragma),
>    you will find that Interrupt 14 (Sigalrm) is reserved, and Program_Error
>    is raised.  Apparently with the static attach, it just silently fails.

Well, on my machine, even when using dynamic attach, there's no
Program_Error.

>    I have always used the dynamic attach myself, but I just tried your
>    program with SIGTERM and SIGWINCH, by outputting a line of
>    text in the Tick procedure.  Both of those signals work with either
>    static or dynamic attach on a SPARCstation-10 with SunOS 5.5.1,
>    sending the signals with kill <PID> or kill -WINCH <PID>.

You are right! It also works on my machine, if I send the signals from
outside via kill! Hmm... Seems like the signals are delivered in a
different
way... Here's the code I use to set up the signals:

procedure Main is

   type Timespec is record
      Tv_Sec : C.Long;
      TV_nsec : C.Long;
   end record;
   pragma Convention (C, Timespec);

   type Itimerspec is record
      It_Interval : Timespec;
      It_Value : Timespec;
   end record;
   pragma Convention (C, Itimerspec);

   type Sigevent is record
      Sigev_Notify : C.Int;
      Sigev_Signo : C.Int;
      Sigev_Value : C.Long;
   end record;
   pragma Convention (C, Sigevent);

   procedure Timer_Create (Clock_Id : C.Int;
                           Evp : Sigevent;
                           Timerid : out C.Int);
   pragma Import (C, Timer_Create, "timer_create");

   My_Timer : C.Int;

   procedure Create_Timer;

   procedure Create_Timer is
      S : Sigevent;
   begin
      S.Sigev_Notify := C.Int (2);    --  This specifies SIGEV_SIGNAL
      S.Sigev_Signo := C.Int (SIGTERM);
      Timer_Create (C.Int (0), S, My_Timer);
   end Create_Timer;

   procedure Timer_Settime (Timer_Id : C.Int;
                            Flags : C.Int;
                            Value : Itimerspec;
                            Ovalue : in out Itimerspec);
   pragma Import (C, Timer_Settime, "timer_settime");

   procedure Set_Time (I : in Natural) is
      New_Value : Itimerspec;
      Old_Value : Itimerspec;
   begin
      New_Value.It_Interval.Tv_Sec := C.Long (I);
      New_Value.It_Interval.Tv_NSec := C.Long (0);
      New_Value.It_Value.Tv_Sec := C.Long (I);
      New_Value.It_Value.Tv_NSec := C.Long (0);
      Timer_Settime (My_Timer, C.Int (0),
                     New_Value, Old_Value);
   end Set_Timetimer;

begin

   Create_Timer;
   Set_Time (6);

   while True loop
      delay 1.0;
   end loop;

end Main;

> Have you ever considered just using the facilities of Ada to do
> what you want?

Of course, this would be the best way to do it... It's just that someone
asked me if I can do it with interrupts...

- J�rg


-- 
---------------------------------------------------------------------------
- Joerg Kienzle - Swiss Federal Institue of Technology - CH-1015
Lausanne -
- email : Joerg.Kienzle@epfl.ch    WWW :
http://lglwww.epfl.ch/~jkienzle/ -
- phone : ++41 21 693 42 37        fax : ++41 21 693 50
79                -




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Interrupt problem in GNAT
  1999-05-20  0:00   ` Joerg Kienzle
@ 1999-05-20  0:00     ` David C. Hoos, Sr.
  0 siblings, 0 replies; 4+ messages in thread
From: David C. Hoos, Sr. @ 1999-05-20  0:00 UTC (permalink / raw)



Joerg Kienzle <Joerg.Kienzle@epfl.ch> wrote in message
news:3743CB6E.AA029CDC@epfl.ch...
>
<large snip>
I use the florist implementation of the POSIX/Ada bindings
(available from
http://www.cs.fsu.edu/~baker/ftp/pub/PART/FLORIST/

the current version is florist990327.tar.gz

for portability of OS-related things.

The procedure Posix.Signals.Send_Signal (N), can be used to
send any signal to the current process.

There is a full repertoire of Signal facilities in that package.

It's much cleaner than "rolling your own" binding.






^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1999-05-20  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-05-19  0:00 Interrupt problem in GNAT Joerg Kienzle
1999-05-19  0:00 ` David C. Hoos, Sr.
1999-05-20  0:00   ` Joerg Kienzle
1999-05-20  0:00     ` David C. Hoos, Sr.

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox