comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: How to terminate all running tasks?
  2020-06-10 11:14  6% How to terminate all running tasks? Gilbert Gosseyn
@ 2020-06-10 12:12  0% ` Niklas Holsti
  0 siblings, 0 replies; 138+ results
From: Niklas Holsti @ 2020-06-10 12:12 UTC (permalink / raw)


On 2020-06-10 14:14, Gilbert Gosseyn wrote:
> Hi,

It would be easier to understand your post if you started with the 
explanation and question, rather than throwing a bunch of uncommented 
code at the reader.

> -- package spezification
> package packp6 is
>     procedure tp6pm(N : Long_Integer);
> end packp6;
> 
> -- package body
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Task_Identification;
> package body packp6 is
>     procedure tp6pm(N : Long_Integer) is
>        use Ada.Task_Identification;
>        package LIO is new Integer_IO(Long_Integer);
>        solution_found : exception;
> 
>        task p6p;
>        task p6m;
> 
>        task body p6p is
>           pp,i : Long_Integer := 0;
>        begin
>           loop
>              i := i+1;
>              pp := 6*i+1;
>              if N mod pp = 0 then
>                 new_line;put("pp= ");LIO.put(pp);
>                 raise solution_found;
>              end if;
>           end loop;


This is the last point at which you can handle the "raise" above. If 
there is no handler here, WITHIN task p6p, the exception will try to 
propagate out of the task, which will terminate the task and STOP the 
propagation of the exception.

>        end p6p;
> 
>        task body p6m is
>           pm,i : Long_Integer := 0;
>        begin
>           loop
>              i := i+1;
>              pm := 6*i-1;
>              if N mod pm = 0 then
>                 new_line;put("pm= ");LIO.put(pm);
>                 raise solution_found;
>              end if;
>           end loop;


Same comment as above.

>        end p6m;
>     begin
>        null;
>     exception
>        when solution_found =>


This handler is never entered, because the "null" statement above does 
not raise solution_found.

>           Abort_Task(p6p'Identity);
>           Abort_Task(p6m'Identity);
>     end tp6pm;
> end packp6;


    [snip]

> When in a task the exception solution_found is raised, then I want
> all running tasks to be terminated immediately.

It is not possible to use an exception, raised in a task, to signal 
something outside the task in that way.

> Apparently this does not happen. How to improve?


You must use some other way to inform the main subprogram that a 
solution has been found. There are may ways, but for example you can use 
an synchronization object as follows:

    with Ada.Synchronous_Task_Control;
    ...
    solution_found : Ada.Synchronous_Task_Control.Suspension_Object;
    ...
    task body p6p
       ...
       Ada.Synchronous_Task_Control.Set_True (solution_found);
       -- Instead of the "raise".
    ...
    same for task p6m

and in the main subprogram, instead of the null statement and the 
exception handler:

    Ada.Synchronous_Task_Control.Suspend_Until_True (solution_found);
    abort p6p;
    abort p6m;

-- 
Niklas Holsti

niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[relevance 0%]

* How to terminate all running tasks?
@ 2020-06-10 11:14  6% Gilbert Gosseyn
  2020-06-10 12:12  0% ` Niklas Holsti
  0 siblings, 1 reply; 138+ results
From: Gilbert Gosseyn @ 2020-06-10 11:14 UTC (permalink / raw)


Hi,
-- package spezification
package packp6 is
   procedure tp6pm(N : Long_Integer);
end packp6;

-- package body
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Task_Identification;
package body packp6 is
   procedure tp6pm(N : Long_Integer) is
      use Ada.Task_Identification;
      package LIO is new Integer_IO(Long_Integer);
      solution_found : exception;

      task p6p;
      task p6m;

      task body p6p is
         pp,i : Long_Integer := 0;
      begin
         loop
            i := i+1;
            pp := 6*i+1;
            if N mod pp = 0 then
               new_line;put("pp= ");LIO.put(pp);
               raise solution_found;
            end if;
         end loop;
      end p6p;

      task body p6m is
         pm,i : Long_Integer := 0;
      begin
         loop
            i := i+1;
            pm := 6*i-1;
            if N mod pm = 0 then
               new_line;put("pm= ");LIO.put(pm);
               raise solution_found;
            end if;
         end loop;
      end p6m;
   begin
      null;
   exception
      when solution_found =>
         Abort_Task(p6p'Identity);
         Abort_Task(p6m'Identity);    
   end tp6pm;
end packp6;

-- test
with packp6; use packp6;
procedure P6_Test is
NN : Long_Integer := 11111111111111111;
begin
   tp6pm(NN);
end P6_Test;

-- test result:

pm=         2071723
pp=     5363222357


When in a task the exception solution_found is raised, then I want all running tasks to be terminated immediately. Apparently this does not happen. How to improve?

^ permalink raw reply	[relevance 6%]

* Re: Last chance handler on a PC
  2020-01-30 20:02  5%   ` Jeffrey R. Carter
@ 2020-01-30 20:26  0%     ` Niklas Holsti
  0 siblings, 0 replies; 138+ results
From: Niklas Holsti @ 2020-01-30 20:26 UTC (permalink / raw)


On 2020-01-30 22:02, Jeffrey R. Carter wrote:
> On 1/30/20 8:35 PM, ahlan@marriott.org wrote:
>>
>> To catch unhandled exceptions you only need to write a simple 
>> procedure and export it as __gnat_last_chance_handler.
>> This is linked into the program in preference to the default last 
>> chance handler provided by GNAT.
>> This procedure is called if nothing catches a raised exception.
>> Including those raised during package elaboration.
> 
> Doing
> 
> Ada.Task_Termination.Set_Specific_Handler
>     (T       => Ada.Task_Identification.Environment_Task,
>      Handler => Last_Chance'access);
> 
> should do the same thing more portably. It will be called when the 
> environment task terminates for any reason; you would only want it to 
> actually do something when Cause = Unhandled_Exception.

Looks good, but to catch all elaboration-time exceptions (in other 
packages) the package that executes that call, in its own elaboration 
code, must be elaborated before all other packages. Do you have some 
easy way to ensure that, without inserting elaboration pragmas in all 
other packages?

I had a similar elaboration problem some time ago in an embedded 
application, where I wanted to set up some HW error-trap handlers that I 
would like to be active also during elaboration, but I found no easy way 
to ensure that the trap-handling package would be elaborated before all 
other packages.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


^ permalink raw reply	[relevance 0%]

* Re: Last chance handler on a PC
  @ 2020-01-30 20:02  5%   ` Jeffrey R. Carter
  2020-01-30 20:26  0%     ` Niklas Holsti
  0 siblings, 1 reply; 138+ results
From: Jeffrey R. Carter @ 2020-01-30 20:02 UTC (permalink / raw)


On 1/30/20 8:35 PM, ahlan@marriott.org wrote:
> 
> To catch unhandled exceptions you only need to write a simple procedure and export it as __gnat_last_chance_handler.
> This is linked into the program in preference to the default last chance handler provided by GNAT.
> This procedure is called if nothing catches a raised exception.
> Including those raised during package elaboration.

Doing

Ada.Task_Termination.Set_Specific_Handler
    (T       => Ada.Task_Identification.Environment_Task,
     Handler => Last_Chance'access);

should do the same thing more portably. It will be called when the environment 
task terminates for any reason; you would only want it to actually do something 
when Cause = Unhandled_Exception.

-- 
Jeff Carter
"My mind is a raging torrent, flooded with rivulets of
thought, cascading into a waterfall of creative alternatives."
Blazing Saddles
89


^ permalink raw reply	[relevance 5%]

* Re: Finalization of library level tasks
  @ 2018-04-26  0:02  5%                                         ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2018-04-26  0:02 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1688 bytes --]

"J-P. Rosen" <rosen@adalog.fr> wrote in message 
news:pb6kuf$jgl$1@gioia.aioe.org...
> Le 17/04/2018 à 23:23, Dmitry A. Kazakov a écrit :
>> P.S. If "main subprogram complete" should mean "environment task
>> complete" that is OK to me. However insane the wording sounds to me only
>> the semantics counts.
> The paragraph you quote says "has completed", not "complete". Remember,
> the main subprogram is called by the environment task. So, the main
> subprogram completes and exits, then the environment task waits for
> dependents, at which point its 'callable becomes false.
>
>> Why could not "task complete" mean "will select
>> next terminate"? At least it would make some use out of having 
>> T'Callable.
> 'Callable is very useful for regular tasks. Your quote suggests that
> there might also be some use for it on the environment task, which is
> not obvious.

I invented that to get around Dmitry's original problem when I stumbled into 
it building Claw right after Ada 95 was finished. I was able to convince the 
ARG that the environment task ought to be completed once the main subprogram 
exits [that follows from the definition of the environment task], and that 
one should be able to use Ada.Task_Identification to query that. (You could 
do it even before the Environment_Task function, you just had to squirrel 
the environment task id during initial elaboration.) Several compilers 
didn't do this right, but one of the first things I added to the ACATS after 
taking over was a test of this case (once the ARG approved the idea, of 
course). So all modern compilers support the idiom of testing Callable of 
the environment task.

                       Randy.



^ permalink raw reply	[relevance 5%]

* Re: Finalization of library level tasks
  2018-04-15 20:09  0%                 ` Dmitry A. Kazakov
@ 2018-04-25 23:49  0%                   ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2018-04-25 23:49 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:pb0bho$p1e$1@gioia.aioe.org...
> On 2018-04-15 21:32, Egil H H wrote:
>> On Sunday, April 15, 2018 at 7:40:38 PM UTC+2, Dmitry A. Kazakov wrote:
>>>
>>> Terminate alternative is almost always useless because it cannot be
>>> mixed with "else" or "delay". If there were a way to check within the
>>> task if its completion has been requested
>>
>> For library level tasks:
>>
>> loop
>>     select
>>        accept Some_Rendezvous;
>>     or
>>        delay Some_Interval;
>>     end select;
>>      exit when not Ada.Task_Identification.Is_Callable
>>        (Ada.Task_Identification.Environment_Task);
>>      end loop;
>
> Yes, that is what I was looking for. T'Callable on the task itself does 
> the trick. Apparently task being terminated is not callable.

Callable becomes False when a task is completed. That happens before 
finalization and before termination.

The environment task completes when the main subprogram exits, and you can 
test that as above.

            Randy.


^ permalink raw reply	[relevance 0%]

* Re: Finalization of library level tasks
    @ 2018-04-25 23:46  5%         ` Randy Brukardt
  1 sibling, 0 replies; 138+ results
From: Randy Brukardt @ 2018-04-25 23:46 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:pavqa6$1qdj$1@gioia.aioe.org...
...
> Yes. The problem is the order of finalization. For some unclear reason the 
> task's access type is attempted before the object that contains that 
> access type because they are in the same scope.

It's not unclear - tasks have to terminate before objects are finalized so 
that the tasks aren't trying to use finalized objects. If the object is a 
protected object, that could be a really bad deal (remember that finalizing 
a protected object raises tasking error in any queued task and prevents 
future calls).

We ran into this with Claw, and eventually had the Ada.Task_Identification 
solution ingrained into the Standard. (I believe you found it from some 
other messages that I saw previously, so I won't describe it here.)

                Randy.



^ permalink raw reply	[relevance 5%]

* Re: Finalization of library level tasks
  2018-04-15 19:32  7%               ` Egil H H
@ 2018-04-15 20:09  0%                 ` Dmitry A. Kazakov
  2018-04-25 23:49  0%                   ` Randy Brukardt
  0 siblings, 1 reply; 138+ results
From: Dmitry A. Kazakov @ 2018-04-15 20:09 UTC (permalink / raw)


On 2018-04-15 21:32, Egil H H wrote:
> On Sunday, April 15, 2018 at 7:40:38 PM UTC+2, Dmitry A. Kazakov wrote:
>>
>> Terminate alternative is almost always useless because it cannot be
>> mixed with "else" or "delay". If there were a way to check within the
>> task if its completion has been requested
> 
> For library level tasks:
> 
> loop
>     select
>        accept Some_Rendezvous;
>     or
>        delay Some_Interval;
>     end select;
>      
>     exit when not Ada.Task_Identification.Is_Callable
>        (Ada.Task_Identification.Environment_Task);
>      	
> end loop;

Yes, that is what I was looking for. T'Callable on the task itself does 
the trick. Apparently task being terminated is not callable.

Thanks.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Finalization of library level tasks
  @ 2018-04-15 19:32  7%               ` Egil H H
  2018-04-15 20:09  0%                 ` Dmitry A. Kazakov
    1 sibling, 1 reply; 138+ results
From: Egil H H @ 2018-04-15 19:32 UTC (permalink / raw)


On Sunday, April 15, 2018 at 7:40:38 PM UTC+2, Dmitry A. Kazakov wrote:
> 
> Terminate alternative is almost always useless because it cannot be 
> mixed with "else" or "delay". If there were a way to check within the 
> task if its completion has been requested 

For library level tasks:

loop
   select
      accept Some_Rendezvous;
   or
      delay Some_Interval;
   end select;
    
   exit when not Ada.Task_Identification.Is_Callable
      (Ada.Task_Identification.Environment_Task);
    	    
end loop;


^ permalink raw reply	[relevance 7%]

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 22:43  4% ` Randy Brukardt
@ 2017-12-02 11:12  0%   ` AdaMagica
  0 siblings, 0 replies; 138+ results
From: AdaMagica @ 2017-12-02 11:12 UTC (permalink / raw)


Am Freitag, 1. Dezember 2017 23:43:25 UTC+1 schrieb Randy Brukardt:
> When 
> the main program exits, of course the environment task completes and then 
> terminates. It's the completion of the environment task that starts 
> library-level finalization. (Indeed, you can use Ada.Task_Identification to 
> figure out that this is happening -- that is how Claw shuts down its tasks, 
> otherwise they would wait forever for operations that aren't ever going to 
> happen.) The termination of the environment tasks causes the entire program 
> to exit (normally or via exception).

Just to refresh my memory:
The main subprogram is the master of any library tasks. It may be empty (I just confirmed this with a little test) and thus does not exit until all library tasks are terminated or waiting on a terminate alternative.

with Lib;  -- in the elaboration sequence, there are some tasks
procedure Main is
begin
  null;  -- waiting here for tasks to terminate
end Main;


^ permalink raw reply	[relevance 0%]

* Re: How to tell whether program finalization can be suppressed
  @ 2017-12-01 22:43  4% ` Randy Brukardt
  2017-12-02 11:12  0%   ` AdaMagica
  0 siblings, 1 reply; 138+ results
From: Randy Brukardt @ 2017-12-01 22:43 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lyzi729lh2.fsf@pushface.org...
...
> Amongst other things, I can test for specific restrictions, and I'm
> wondering whether No_Task_Termination would be appropriate for this?
> (I'm assuming that the environment task mustn't terminate, even if the
> main program exits; and in this RTS, exceptions can't be propagated).

I don't know enough about the details of GNAT to say anything useful about 
it specifically, but the above seems confused from an Ada perspective. When 
the main program exits, of course the environment task completes and then 
terminates. It's the completion of the environment task that starts 
library-level finalization. (Indeed, you can use Ada.Task_Identification to 
figure out that this is happening -- that is how Claw shuts down its tasks, 
otherwise they would wait forever for operations that aren't ever going to 
happen.) The termination of the environment tasks causes the entire program 
to exit (normally or via exception).

In an embedded system that is supposed to run forever, one would expect that 
the main subprogram would never exit. If it did exit, the system would shut 
itself off, which probably would lead to task waiting and then library-level 
finalization. After that, one would try to restart the system from scratch. 
I suppose someone could build a system that did something else on such an 
exit (which always represents a catostrophic failure), but it wouldn't be 
very Ada-like - finalization would not get performed on objects that are 
expecting that (potentially leaving things in unusual states). Such a system 
would have to start-up making no assumptions at all, even the ones that 
usually could be made at power-up -- which sounds painful.

                                         Randy.


^ permalink raw reply	[relevance 4%]

* Read-write mutex sometimes fails on deadlock
@ 2017-10-28 20:02  4% pascal.malaise
  0 siblings, 0 replies; 138+ results
From: pascal.malaise @ 2017-10-28 20:02 UTC (permalink / raw)


Hi,

[long post because it includes the full sources and output, sorry]

I have a package that implements several kinds of mutexes, including a
read-write mutex. Here is the full source (spec and body) with only the
read-write part.

mutexes.ads
-----------

private with Ada.Task_Identification;
-- Mutex (single and Read_Write) management
package Mutexes is

  -- Kind of mutex
  -- Read_Write allows several readers but one writer at a time.
  --  This implementation is fair but somewhat CPU-consuming because
  --  the arrival of a reader while writer(s) are waiting triggers a
  --  re-evaluation to let it pass if it has a higher (task) priority.
  -- Kind of requested access for a Read_Write mutex
  type Access_Kind is (Read, Write);

  -- Mutex object, free at creation
  type Mutex is tagged limited private;

  -- Get access to a mutex.
  -- With RW mutex (Read_Write), simultaneous read are possible,
  --  but there is only one writer at a time and no reader at that time.
  -- If delay is negative, wait until mutex is got,
  -- If delay is null, try and give up if not free,
  -- If delay is positive, try during the specified delay.
  -- Raises Already_Got if the current task if it has already got the RW mutex
  --  for write.
  -- Note that there is no check of "Read then Write" deadlock.
  Already_Got : exception;
  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean;
  -- Get access to a mutex : infinite wait.
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read);
  function Get (A_Mutex : in out Mutex) return Boolean;


  -- Release access to a mutex.
  -- Raises Not_Owner if current task doesn't own the the RW mutex for write
  --  (no check when releasing RW mutex aquired for read).
  Not_Owner : exception;
  procedure Release (A_Mutex : in out Mutex);

  -- Is current task the "owner" (access got) of a simple mutex
  -- Is it the writer in case of a RW mutex
  function Is_Owner (A_Mutex : in Mutex) return Boolean;

private

  -- Read/write mutex
  -- We want to queue all requests (read and write) within the same queue
  --  to ensure fairness (avoid starvation).
  -- But the condition for read is "no writer" (not Writer)
  --  and for write it is "no writer and no reader"
  --  (not Writer and then Readers = 0)
  -- So the guard of the common queue is "no writer", but a writer may pass it
  --  while there are reader. In this case, we would like to requeue it in the
  --  same queue and in the beginning of it; note that "requeue" requeues at
  --  the end :-(. The artifact is to requeue the task, and all other
  --  tasks queueing after it as well, in an alternate queue (Swapping).
  -- Benefit: a new reader may enter while writer(s) are queueing, if its
  --  priority is better. Fairness ++.
  -- Drawback: each new reader while writer(s) are queueing triggers an open
  --  then a swap of the queues. Perfo --.

  -- So there are two queues
  type Queue_Range is mod 2;

  -- The read/write access lock and queues. No time.
  protected type Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    entry Mutex_Get (Kind : in Access_Kind);

    -- Releases the lock
    procedure Mutex_Release;

    -- Is current task write owner of the lock
    function Mutex_Owns return Boolean;
  private
    -- Number of readers
    Readers : Natural := 0;
    -- Writer identification
    Owner : Ada.Task_Identification.Task_Id;
    -- Numer of times it has got the write lock
    Writer : Natural := 0;

    -- Two queues, one is active at a time
    entry Queues (Queue_Range) (Kind : in Access_Kind);
    Current_Queue : Queue_Range := Queue_Range'First;
    -- The status of the queue:
    -- Swapping or not
    Swapping : Boolean := False;
    -- If not swapping, is the mutex open or not
    -- if swapping, will it be open or not
    Open : Boolean := True;

  end Rw_Mutex_Protect;

  -- The general purpose mutex
  type Mutex is tagged limited record
    Rw_Mutex : Rw_Mutex_Protect;
  end record;
end Mutexes;


mutexes.adb
-----------

with Ada.Text_Io;
package body Mutexes is

  use type Ada.Task_Identification.Task_Id;
  function Image (Id : in Ada.Task_Identification.Task_Id) return String
           renames Ada.Task_Identification.Image;

  Debug_Set : Boolean := False;
  Debug_On : Boolean := False;
  procedure Trace (Id : in Ada.Task_Identification.Task_Id;
                   Msg : in String) is
  begin
    if not Debug_Set then
      -- Initial setup
      Debug_Set := True;
      Debug_On := True;
    end if;
    if Debug_On then
      Ada.Text_Io.Put_Line (Msg & " " & Image (Id));
    end if;
  end Trace;

  -- The protected object which implements the read/write mutex
  protected body Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    -- Do not let a new request be inserted in the middle of a queue while
    -- we are swapping queues.
    entry Mutex_Get (Kind : in Access_Kind) when not Swapping is
    begin
      -- Are we already the writer
      if Writer /= 0 and then Mutex_Get'Caller = Owner then
        raise Already_Got;
      end if;

      -- Queue the request in the active queue
      Trace (Mutex_Get'Caller, "Read_Write get queueing");
      requeue Queues(Current_Queue) with abort;
    end Mutex_Get;

    -- Releases the lock. No Check of kind but the lock must have been
    -- got.
    procedure Mutex_Release is
    begin
      if Readers > 0 then
        -- There are readers, one of them is releasing the lock
        Readers := Readers - 1;
        if Readers = 0 then
          -- The last reader leaves, so the lock becomes available
          --  for writers
          Trace (Ada.Task_Identification.Current_Task, "Last reader releases");
          Open := True;
        else
          Trace (Ada.Task_Identification.Current_Task, "Reader releases");
        end if;
      elsif Writer /= 0
      and then Ada.Task_Identification.Current_Task = Owner then
        -- The writer is releasing the lock
        if Writer /= 1 then
          Writer := Writer - 1;
          return;
        end if;
        -- Really releasing
        Trace (Ada.Task_Identification.Current_Task, "Writer releases");
        Writer := 0;
        Open := True;
      else
        -- Called while no lock was got or not called by the writer
        raise Not_Owner;
      end if;
    end Mutex_Release;

    function Mutex_Owns return Boolean is
      (Writer /= 0 and then Ada.Task_Identification.Current_Task = Owner);

    -- Two queues, one active at a time
    -- Passes when swapping queues or else when open
    entry Queues (for Queue in Queue_Range) (Kind : in Access_Kind)
          when Queue = Current_Queue
          and then (Swapping or else Open) is
    begin
      if Swapping then
        -- Swapping queueing tasks from one queue to the other
        Trace (Queues'Caller, "Swapping");
        if Queues(Queue)'Count = 0 then
          -- This is the last task: end of swapping
          -- Open remains unchanged (maybe open by a release)
          Swapping := False;
          Current_Queue := Current_Queue + 1;
          Trace (Queues'Caller, "End swapping");
        end if;
        -- Requeue the task on the other queue
        requeue Queues(Queue + 1) with abort;
      else
        -- The queue is open: The lock is either free or allocated to reader(s)
        if Kind = Read then
          Trace (Queues'Caller, "Another reader");
          -- Read lock
          Readers := Readers + 1;
        else
          -- Write lock:
          -- If we are here, it means that the gate is open so no writer
          --  has already got the lock
          -- Either we get the lock (queue is closed until we release)
          -- or we queue (no currently queueing read can pass)
          -- so in both case, the queue is closed
          -- Note that a new request may re-open the queue and enter
          --  before us if it as a better prio
          Open := False;
          if Readers = 0 then
            -- No reader => we get the write lock
            Writer := 1;
            Owner := Queues'Caller;
            Trace (Queues'Caller, "Writer has got lock");
          else
            -- We have to wait until last reader releases the lock
            -- If we are alone, requeue ourself. Otherwise
            --  requeue in the alternate queue this task, then all the other
            --  queueing tasks, so we remain first (if same prios)
            Swapping := Queues(Queue)'Count > 0;
            if Swapping then
              Trace (Queues'Caller, "Start swapping");
              requeue Queues(Queue + 1) with abort;
            else
              Trace (Queues'Caller, "Writer waits for current reader");
              requeue Queues(Queue) with abort;
            end if;
          end if;
        end if;
      end if;
    end Queues;

  end Rw_Mutex_Protect;

  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean is
    Result : Boolean;
  begin
    if Waiting_Time < 0.0 then
      -- Negative delay : unconditional waiting
      A_Mutex.Rw_Mutex.Mutex_Get (Kind);
      Result := True;
    else
      select
        A_Mutex.Rw_Mutex.Mutex_Get (Kind);
        Result := True;
      or
        delay Waiting_Time;
        Result := False;
      end select;
    end if;
    return Result;
  end Get;

  function Get (A_Mutex : in out Mutex) return Boolean is
    (Get (A_Mutex, -1.0, Read));

  -- Get a mutex : infinite wait
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read) is
    Dummy : Boolean;
  begin
    Dummy := Get (A_Mutex, -1.0, Kind);
  end Get;

  -- Release a mutex
  procedure Release (A_Mutex : in out Mutex) is
  begin
    -- Request releasing
    A_Mutex.Rw_Mutex.Mutex_Release;
  end Release;

  -- Does current task own the mutex (for write)
  function Is_Owner (A_Mutex : Mutex) return Boolean is
  begin
    return A_Mutex.Rw_Mutex.Mutex_Owns;
  end Is_Owner;

end Mutexes;



Finally, I have a test program of the read-write mutex, which creates 10 tasks,
each of them taking the mutex, for read or write, during some time. The tasks
randomly terminate, and when all of them are done then the test is OK.


t_read_write.adb
----------------
with Ada.Text_Io, Ada.Command_Line, Ada.Calendar, Ada.Task_Identification,
     Ada.Numerics.Float_Random;
with Gnat.Calendar;
with Mutexes;
-- Test Read-Write mutex
procedure T_Read_Write is
  pragma Priority(10);

  -- True if gnat, otherwise remove usage of Gnat.Calendar
  Has_Gnat : constant Boolean := True;

  -- The number of tasks
  subtype Range_Actor is Natural range 0 .. 10;
  Main_Index : constant Range_Actor := 0;
  subtype Range_Task is Positive range 1 .. Range_Actor'Last;

  -- Date of last output of a task
  Last_Time : Ada.Calendar.Time;
  use type Ada.Calendar.Time;
  -- Delay of inactivity
  Inactivity : constant Duration := 5.0;

  -- Random generator
  Gen : Ada.Numerics.Float_Random.Generator;
  function Random (Mini : in Integer := 0;
                   Maxi : in Integer := 1) return Integer is
    F : Float;
    Res : Integer;
  begin
    F := Float(Mini) + Ada.Numerics.Float_Random.Random(Gen)
                       * Float(Maxi - Mini);
    Res := Integer (F);
    while Res > Maxi and then Res > Mini loop
      Res := Res - 1;
    end loop;
    return Res;
  end Random;

  -- Image of a date 
  function Image (Date : Ada.Calendar.Time) return String is
    Year   : Ada.Calendar.Year_Number;
    Month  : Ada.Calendar.Month_Number;
    Day    : Ada.Calendar.Day_Number;

    Hour       : Gnat.Calendar.Hour_Number;
    Minute     : Gnat.Calendar.Minute_Number;
    Second     : Gnat.Calendar.Second_Number;
    Sub_Second : Gnat.Calendar.Second_Duration;
    function Img (D : Gnat.Calendar.Second_Duration) return String is
      S : constant String := D'Img;
    begin
      return S(3 .. S'Last);
    end Img;
    Dur    : Ada.Calendar.Day_Duration;
    function Img (N : Integer) return String is
      S : constant String := N'Img;
    begin
      if S'Last = 2 then
        -- " d", 1 digit => "0" & d
        return "0" & S(2);
      else
        -- " dd", d
        return S(2 .. S'Last);
      end if;
    end Img;
    
  begin
    if Has_Gnat then
      Gnat.Calendar.Split (Date, Year, Month, Day, Hour, Minute, Second,
                           Sub_Second);
      return Img (Year) & "-" & Img (Month) & "-" & Img (Day) & "T"
           & Img (Hour) & ":" & Img (Minute) & ":" & Img (Second)
           & Img (Sub_Second);

    else
      Ada.Calendar.Split (Date, Year, Month, Day, Dur);
      return Img (Year) & "/" & Img (Month) & "/" & Img (Day) & Dur'Img;
    end if;
  end Image;

  -- Put a task activity
  procedure Put_Line (Index : in Range_Actor; Msg : in String) is
  begin
    Last_Time := Ada.Calendar.Clock;
    declare
      Date : constant String := Image (Last_Time);
      Str : constant String
          := (if Index in Range_Task then Index'Img else "Main")
           & " " & Msg;
    begin
      Ada.Text_Io.Put_Line (Date & " " & Str);
    end;
  end Put_Line;
  Lock : access Mutexes.Mutex;

  -- The client tasks
  task type T is
   pragma Priority(10);
    entry Num (I : in Range_Task);
    entry Done;
  end T;

  function Image (D : Duration) return String is
    Str : constant String := D'Img;
  begin
    return Str (1 .. 4);
  end Image;

  task body T is
    Index : Range_Task;
    Dur : Duration;
    Kind : Mutexes.Access_Kind;
    subtype Str5 is String (1 .. 5);
    Kind_Strs : constant array (Mutexes.Access_Kind) of Str5 := (
      Mutexes.Read  => " Read",
      Mutexes.Write => "Write");
    Res : Boolean;
  begin
    -- Get name
    accept Num (I : in Range_Task) do
      Index := I;
    end Num;
    Put_Line (Index ,
      "Task started, id "
    & Ada.Task_Identification.Image (Ada.Task_Identification.Current_Task));
    -- Work until termination requested in Critical
    loop
      delay 0.01;
      -- Wait from -0.1 to 0.5
      Dur := Duration (Random (-1, 5)) / 10.0;
      -- 10% chances to write
      if Random (0, 9) = 0 then
        Kind := Mutexes.Write;
      else
        Kind := Mutexes.Read;
      end if;
      -- Get lock
      Put_Line (Index, "get " & Kind_Strs(Kind) & " " & Image(Dur));
      Res := Lock.Get (Dur, Kind);
      -- Trace result
      if Res then
        Put_Line (Index, "OK");
      else
        Put_Line (Index, "NOK");
      end if;

      if Res then
        -- Got it: Work (wait) from 0.1 to 0.5
        Put_Line (Index, "waiting");
        delay Duration (Random (1, 5)) / 10.0;
        Put_Line (Index, "waited");

        -- Release lock
        Put_Line (Index, "release");
        Lock.Release;
      end if;

      -- 10% chances to terminate
      exit when Random (0, 9) = 0;
    end loop;
    Put_Line (Index, "terminate");
    -- Ready to end
    accept Done;
  end T;

  Tasks : array (Range_Task) of T;
  Runs  : array (Range_Task) of Boolean;
  Nb_Run : Natural;

-- The main: activate and monitor the tasks
begin
  Lock := new Mutexes.Mutex;

  -- Randomize
  Ada.Numerics.Float_Random.Reset (Gen, 
    Integer (Ada.Calendar.Seconds (Ada.Calendar.Clock)));

  -- Give to each actor it's name
  Put_Line (Main_Index, "Starting");
  Nb_Run := 0;
  for I in Range_Task loop
    Tasks(I).Num (I);
    Runs(I) := True;
    Nb_Run := Nb_Run + 1;
  end loop;

  -- Wait until termination of all tasks
  Main: while Nb_Run /= 0 loop

    -- Try to terminate tasks: wait 1s altogether
    for I in Range_Task loop
      if Runs(I) then
        select
          Tasks(I).Done;
          Runs(I) := False;
          Nb_Run := Nb_Run - 1;
        or
          delay 1.0 / Duration(Nb_Run);
        end select;
      end if;
    end loop;

    -- Monitor activity
    if Ada.Calendar.Clock - Last_Time > Inactivity then
      -- Deadlock detected => abort tasks
      Put_Line (Main_Index, "Deadlock detected, aborting");
      Ada.Command_Line.Set_Exit_Status (1);
      for I in Range_Task loop
        if Runs(I) then
          abort Tasks(I);
          -- This will exit Main
          Nb_Run := Nb_Run - 1;
        end if;
      end loop;
    end if;
  end loop Main;

  Put_Line (Main_Index, "Done");

end T_Read_Write;


Most of the time it works, but from time to time (every 100 to 1000 iterations)
the test fails: the main detects a deadlock because of no output activity during
more than 5 secs, and exits on error.
You can test on Unix with the following scripts (launch "./Loop"):

trw
---
#!/bin/bash
./t_read_write >out 2>err

Loop
----
#!/bin/bash

# Loop until failure
res=0
let n=0+1
while [ $res -eq 0 ] ; do
  echo `date +"%Y-%m-%dT%H:%M:%S"`" Iteration "$n":"
  ./trw
  if [ $? -ne 0 ] ; then
    echo "Failed!"
    exit 1
  fi
  let n=$n+1
done



When everything is OK all the tasks terminate one after the other, but in case
of failure, here is the output:

2017-10-28T21:15:21.139556000 Main Starting
2017-10-28T21:15:21.139602000  1 Task started, id tasks(1)_0000000000E63F10
2017-10-28T21:15:21.139618000  2 Task started, id tasks(2)_0000000000E68040
2017-10-28T21:15:21.139644000  3 Task started, id tasks(3)_0000000000E6B650
2017-10-28T21:15:21.139662000  4 Task started, id tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.139679000  5 Task started, id tasks(5)_0000000000E72270
2017-10-28T21:15:21.139695000  6 Task started, id tasks(6)_0000000000E75880
2017-10-28T21:15:21.139709000  7 Task started, id tasks(7)_0000000000E78E90
2017-10-28T21:15:21.139732000  8 Task started, id tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.139752000  9 Task started, id tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.139759000  10 Task started, id tasks(10)_0000000000E830C0
2017-10-28T21:15:21.149687000  1 get  Read  0.0
2017-10-28T21:15:21.149690000  3 get Write  0.1
2017-10-28T21:15:21.149700000  2 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149744000  5 get  Read  0.0
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149782000  4 get Write  0.5
Read_Write get queueing tasks(3)_0000000000E6B650
Writer waits for current reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.149804000  8 get  Read  0.1
2017-10-28T21:15:21.149786000  1 OK
2017-10-28T21:15:21.149769000  6 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.149825000  9 get  Read  0.5
2017-10-28T21:15:21.149829000  2 NOK
Read_Write get queueing tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.149855000  10 get  Read  0.0
2017-10-28T21:15:21.149875000  7 get  Read  0.2
2017-10-28T21:15:21.149816000  1 waiting
Read_Write get queueing tasks(4)_0000000000E6EC60
Read_Write get queueing tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(6)_0000000000E75880
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.149917000  6 NOK
2017-10-28T21:15:21.149926000  5 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
Read_Write get queueing tasks(7)_0000000000E78E90
2017-10-28T21:15:21.149940000  10 NOK
2017-10-28T21:15:21.159909000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.159990000  5 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.160006000  10 get  Read  0.5
2017-10-28T21:15:21.159993000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.160032000  6 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.170103000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.249871000  3 NOK
2017-10-28T21:15:21.249967000  8 NOK
2017-10-28T21:15:21.259960000  2 NOK
2017-10-28T21:15:21.259964000  3 get  Read  0.1
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.260036000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.270048000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.270066000  2 NOK
2017-10-28T21:15:21.280139000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.349953000  1 waited
2017-10-28T21:15:21.349976000  1 release
Last reader releases tasks(1)_0000000000E63F10
Another reader tasks(9)_0000000000E7FAB0
Start swapping tasks(4)_0000000000E6EC60
Swapping tasks(7)_0000000000E78E90
2017-10-28T21:15:21.350007000  9 OK
2017-10-28T21:15:21.350051000  9 waiting
Swapping tasks(5)_0000000000E72270
2017-10-28T21:15:21.360060000  1 get  Read  0.0
Swapping tasks(10)_0000000000E830C0
Swapping tasks(6)_0000000000E75880
Swapping tasks(8)_0000000000E7C4A0
Swapping tasks(2)_0000000000E68040
End swapping tasks(2)_0000000000E68040
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.360109000  3 NOK
2017-10-28T21:15:21.360121000  1 NOK
2017-10-28T21:15:21.370195000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.370204000  1 get Write  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.370242000  1 NOK
2017-10-28T21:15:21.380223000  2 NOK
2017-10-28T21:15:21.380324000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.390298000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.460071000  5 NOK
2017-10-28T21:15:21.470153000  5 get  Read  0.0
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.470170000  5 NOK
2017-10-28T21:15:21.480242000  5 get  Read  0.1
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.570194000  6 NOK
2017-10-28T21:15:21.580275000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.580293000  6 NOK
2017-10-28T21:15:21.580321000  5 NOK
2017-10-28T21:15:21.590365000  2 NOK
2017-10-28T21:15:21.590374000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.590401000  5 get  Read  0.2
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.600438000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.649962000  4 NOK
2017-10-28T21:15:21.660056000  4 get  Read  0.2
Read_Write get queueing tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.660107000  10 NOK
2017-10-28T21:15:21.670184000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.670203000  10 NOK
2017-10-28T21:15:21.670286000  3 NOK
2017-10-28T21:15:21.680277000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.680365000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750125000  9 waited
2017-10-28T21:15:21.750140000  9 release
Last reader releases tasks(9)_0000000000E7FAB0
Another reader tasks(8)_0000000000E7C4A0
Another reader tasks(1)_0000000000E63F10
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:21.750191000  1 OK
2017-10-28T21:15:21.750202000  6 OK
Another reader tasks(5)_0000000000E72270
2017-10-28T21:15:21.750215000  6 waiting
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:21.750166000  8 OK
2017-10-28T21:15:21.750251000  5 OK
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.750264000  5 waiting
2017-10-28T21:15:21.750275000  4 OK
2017-10-28T21:15:21.750286000  2 OK
2017-10-28T21:15:21.750298000  2 waiting
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:21.750287000  4 waiting
2017-10-28T21:15:21.750254000  8 waiting
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750353000  9 terminate
2017-10-28T21:15:21.750356000  3 OK
2017-10-28T21:15:21.750205000  1 waiting
2017-10-28T21:15:21.750381000  3 waiting
2017-10-28T21:15:21.750338000  10 OK
2017-10-28T21:15:21.750420000  10 waiting
2017-10-28T21:15:21.950478000  3 waited
2017-10-28T21:15:21.950503000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960583000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960607000  3 OK
2017-10-28T21:15:21.960615000  3 waiting
2017-10-28T21:15:22.150289000  6 waited
2017-10-28T21:15:22.150308000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.150351000  5 waited
2017-10-28T21:15:22.150361000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.150377000  2 waited
2017-10-28T21:15:22.150386000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.150411000  4 waited
2017-10-28T21:15:22.150425000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.150444000  8 waited
2017-10-28T21:15:22.150453000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.150488000  10 waited
2017-10-28T21:15:22.150498000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160386000  5 get  Read  0.3
2017-10-28T21:15:22.160388000  6 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
Another reader tasks(5)_0000000000E72270
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.160455000  2 get  Read  0.1
2017-10-28T21:15:22.160498000  4 get  Read  0.2
2017-10-28T21:15:22.160457000  6 OK
2017-10-28T21:15:22.160517000  6 waiting
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:22.160433000  5 OK
2017-10-28T21:15:22.160542000  8 get  Read  0.0
2017-10-28T21:15:22.160547000  5 waiting
Another reader tasks(2)_0000000000E68040
Read_Write get queueing tasks(4)_0000000000E6EC60
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.160580000  2 OK
2017-10-28T21:15:22.160611000  4 OK
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.160578000  10 get  Read  0.4
2017-10-28T21:15:22.160624000  4 waiting
Another reader tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160615000  2 waiting
2017-10-28T21:15:22.160655000  8 OK
2017-10-28T21:15:22.160674000  10 OK
2017-10-28T21:15:22.160692000  8 waiting
2017-10-28T21:15:22.160702000  10 waiting
2017-10-28T21:15:22.250462000  1 waited
2017-10-28T21:15:22.250475000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260551000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260571000  1 OK
2017-10-28T21:15:22.260579000  1 waiting
2017-10-28T21:15:22.260775000  10 waited
2017-10-28T21:15:22.260785000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270860000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270879000  10 OK
2017-10-28T21:15:22.270887000  10 waiting
2017-10-28T21:15:22.360594000  6 waited
2017-10-28T21:15:22.360619000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.360646000  1 waited
2017-10-28T21:15:22.360658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.360684000  4 waited
2017-10-28T21:15:22.360686000  3 waited
2017-10-28T21:15:22.360696000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.360706000  3 release
2017-10-28T21:15:22.360723000  4 terminate
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.360743000  2 waited
2017-10-28T21:15:22.360767000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.370699000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.370720000  6 OK
2017-10-28T21:15:22.370728000  6 waiting
2017-10-28T21:15:22.370735000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.370754000  1 OK
2017-10-28T21:15:22.370762000  1 waiting
2017-10-28T21:15:22.370817000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.370835000  3 OK
2017-10-28T21:15:22.370838000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.370843000  3 waiting
2017-10-28T21:15:22.370866000  2 OK
2017-10-28T21:15:22.370882000  2 waiting
2017-10-28T21:15:22.460633000  5 waited
2017-10-28T21:15:22.460653000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.460667000  5 terminate
2017-10-28T21:15:22.560780000  8 waited
2017-10-28T21:15:22.560798000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570880000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570902000  8 OK
2017-10-28T21:15:22.570911000  8 waiting
2017-10-28T21:15:22.570949000  2 waited
2017-10-28T21:15:22.570959000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.581035000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.581054000  2 OK
2017-10-28T21:15:22.581062000  2 waiting
2017-10-28T21:15:22.670800000  6 waited
2017-10-28T21:15:22.670856000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.680902000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.680930000  6 OK
2017-10-28T21:15:22.680938000  6 waiting
2017-10-28T21:15:22.770837000  1 waited
2017-10-28T21:15:22.770857000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.770938000  3 waited
2017-10-28T21:15:22.770939000  10 waited
2017-10-28T21:15:22.770951000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.770965000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.780936000  1 get  Read  0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.780975000  1 OK
2017-10-28T21:15:22.780983000  1 waiting
2017-10-28T21:15:22.781041000  3 get  Read  0.2
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.781059000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.781059000  3 OK
2017-10-28T21:15:22.781092000  10 OK
2017-10-28T21:15:22.781102000  3 waiting
2017-10-28T21:15:22.781112000  10 waiting
2017-10-28T21:15:22.881010000  6 waited
2017-10-28T21:15:22.881023000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.891099000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.891118000  6 OK
2017-10-28T21:15:22.891126000  6 waiting
2017-10-28T21:15:22.981185000  3 waited
2017-10-28T21:15:22.981200000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991277000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991297000  3 OK
2017-10-28T21:15:22.991305000  3 waiting
2017-10-28T21:15:23.070985000  8 waited
2017-10-28T21:15:23.071001000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081054000  1 waited
2017-10-28T21:15:23.081066000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.081078000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081098000  8 OK
2017-10-28T21:15:23.081106000  8 waiting
2017-10-28T21:15:23.081130000  2 waited
2017-10-28T21:15:23.081139000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.091142000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.091162000  1 OK
2017-10-28T21:15:23.091170000  1 waiting
2017-10-28T21:15:23.091220000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.091242000  2 OK
2017-10-28T21:15:23.091250000  2 waiting
2017-10-28T21:15:23.091369000  3 waited
2017-10-28T21:15:23.091379000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:23.091391000  3 terminate
2017-10-28T21:15:23.181190000  10 waited
2017-10-28T21:15:23.181206000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191284000  10 get  Read  0.4
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191304000  10 OK
2017-10-28T21:15:23.191312000  10 waiting
2017-10-28T21:15:23.291193000  6 waited
2017-10-28T21:15:23.291207000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.291316000  2 waited
2017-10-28T21:15:23.291329000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.301282000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.301302000  6 OK
2017-10-28T21:15:23.301310000  6 waiting
2017-10-28T21:15:23.301406000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.301442000  2 OK
2017-10-28T21:15:23.301450000  2 waiting
2017-10-28T21:15:23.381183000  8 waited
2017-10-28T21:15:23.381228000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391314000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391339000  8 OK
2017-10-28T21:15:23.391347000  8 waiting
2017-10-28T21:15:23.501526000  2 waited
2017-10-28T21:15:23.501556000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.511639000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.511663000  2 OK
2017-10-28T21:15:23.511671000  2 waiting
2017-10-28T21:15:23.591239000  1 waited
2017-10-28T21:15:23.591261000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.591417000  8 waited
2017-10-28T21:15:23.591432000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601334000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.601356000  1 OK
2017-10-28T21:15:23.601365000  1 waiting
2017-10-28T21:15:23.601513000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601535000  8 OK
2017-10-28T21:15:23.601544000  8 waiting
2017-10-28T21:15:23.691386000  10 waited
2017-10-28T21:15:23.691426000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701508000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701530000  10 OK
2017-10-28T21:15:23.701538000  10 waiting
2017-10-28T21:15:23.801385000  6 waited
2017-10-28T21:15:23.801402000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.811480000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.811501000  6 OK
2017-10-28T21:15:23.811509000  6 waiting
2017-10-28T21:15:23.901439000  1 waited
2017-10-28T21:15:23.901452000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.901611000  10 waited
2017-10-28T21:15:23.901623000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.901637000  10 terminate
2017-10-28T21:15:23.911529000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.911553000  1 OK
2017-10-28T21:15:23.911561000  1 waiting
2017-10-28T21:15:23.911744000  2 waited
2017-10-28T21:15:23.911758000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.921835000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.921856000  2 OK
2017-10-28T21:15:23.921864000  2 waiting
2017-10-28T21:15:24.101621000  8 waited
2017-10-28T21:15:24.101640000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111575000  6 waited
2017-10-28T21:15:24.111589000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.111717000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111737000  8 OK
2017-10-28T21:15:24.111745000  8 waiting
2017-10-28T21:15:24.121665000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.121684000  6 OK
2017-10-28T21:15:24.121692000  6 waiting
2017-10-28T21:15:24.211634000  1 waited
2017-10-28T21:15:24.211658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221736000  6 waited
2017-10-28T21:15:24.221737000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221767000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.221793000  1 OK
2017-10-28T21:15:24.221834000  1 waiting
2017-10-28T21:15:24.221931000  2 waited
2017-10-28T21:15:24.221941000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.231875000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.231895000  6 OK
2017-10-28T21:15:24.231903000  6 waiting
2017-10-28T21:15:24.232011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.232030000  2 OK
2017-10-28T21:15:24.232037000  2 waiting
2017-10-28T21:15:24.411815000  8 waited
2017-10-28T21:15:24.411839000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421919000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421940000  8 OK
2017-10-28T21:15:24.421948000  8 waiting
2017-10-28T21:15:24.431974000  6 waited
2017-10-28T21:15:24.431986000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.442064000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.442087000  6 OK
2017-10-28T21:15:24.442094000  6 waiting
2017-10-28T21:15:24.521907000  1 waited
2017-10-28T21:15:24.521922000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.531998000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.532018000  1 OK
2017-10-28T21:15:24.532026000  1 waiting
2017-10-28T21:15:24.532108000  2 waited
2017-10-28T21:15:24.532119000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.542201000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.542224000  2 OK
2017-10-28T21:15:24.542232000  2 waiting
2017-10-28T21:15:24.622024000  8 waited
2017-10-28T21:15:24.622040000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632119000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632139000  8 OK
2017-10-28T21:15:24.632147000  8 waiting
2017-10-28T21:15:24.832096000  1 waited
2017-10-28T21:15:24.832133000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842170000  6 waited
2017-10-28T21:15:24.842188000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.842214000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842235000  1 OK
2017-10-28T21:15:24.842243000  1 waiting
2017-10-28T21:15:24.852266000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.852287000  6 OK
2017-10-28T21:15:24.852295000  6 waiting
2017-10-28T21:15:24.932222000  8 waited
2017-10-28T21:15:24.932238000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942304000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942309000  2 waited
2017-10-28T21:15:24.942346000  8 OK
2017-10-28T21:15:24.942357000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.942367000  8 waiting
2017-10-28T21:15:24.952453000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.952480000  2 OK
2017-10-28T21:15:24.952488000  2 waiting
2017-10-28T21:15:25.052369000  6 waited
2017-10-28T21:15:25.052384000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.062461000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.062481000  6 OK
2017-10-28T21:15:25.062489000  6 waiting
2017-10-28T21:15:25.162556000  6 waited
2017-10-28T21:15:25.162575000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.172668000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.172689000  6 OK
2017-10-28T21:15:25.172697000  6 waiting
2017-10-28T21:15:25.242313000  1 waited
2017-10-28T21:15:25.242329000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252407000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252428000  1 OK
2017-10-28T21:15:25.252436000  1 waiting
2017-10-28T21:15:25.342454000  8 waited
2017-10-28T21:15:25.342491000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352573000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352594000  8 OK
2017-10-28T21:15:25.352602000  8 waiting
2017-10-28T21:15:25.452564000  2 waited
2017-10-28T21:15:25.452584000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.452672000  8 waited
2017-10-28T21:15:25.452686000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462663000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.462683000  2 OK
2017-10-28T21:15:25.462691000  2 waiting
2017-10-28T21:15:25.462762000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462781000  8 OK
2017-10-28T21:15:25.462789000  8 waiting
2017-10-28T21:15:25.572774000  6 waited
2017-10-28T21:15:25.572789000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.582868000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.582889000  6 OK
2017-10-28T21:15:25.582897000  6 waiting
2017-10-28T21:15:25.662860000  8 waited
2017-10-28T21:15:25.662894000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672970000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672993000  8 OK
2017-10-28T21:15:25.673001000  8 waiting
2017-10-28T21:15:25.752510000  1 waited
2017-10-28T21:15:25.752531000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762609000  1 get  Read  0.3
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762630000  1 OK
2017-10-28T21:15:25.762638000  1 waiting
2017-10-28T21:15:25.862708000  1 waited
2017-10-28T21:15:25.862720000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.862732000  1 terminate
2017-10-28T21:15:25.862767000  2 waited
2017-10-28T21:15:25.862783000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.872861000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.872882000  2 OK
2017-10-28T21:15:25.872890000  2 waiting
2017-10-28T21:15:26.073070000  8 waited
2017-10-28T21:15:26.073087000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.082972000  6 waited
2017-10-28T21:15:26.082988000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.083163000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.083181000  8 OK
2017-10-28T21:15:26.083189000  8 waiting
2017-10-28T21:15:26.093071000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:26.093095000  6 OK
2017-10-28T21:15:26.093103000  6 waiting
2017-10-28T21:15:26.172971000  2 waited
2017-10-28T21:15:26.172987000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.183059000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.183080000  2 OK
2017-10-28T21:15:26.183106000  2 waiting
2017-10-28T21:15:26.383260000  8 waited
2017-10-28T21:15:26.383286000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.383301000  8 terminate
2017-10-28T21:15:26.393182000  6 waited
2017-10-28T21:15:26.393198000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.393212000  6 terminate
2017-10-28T21:15:26.483178000  2 waited
2017-10-28T21:15:26.483208000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.493292000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.493316000  2 OK
2017-10-28T21:15:26.493325000  2 waiting
2017-10-28T21:15:26.993401000  2 waited
2017-10-28T21:15:26.993437000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.003520000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.003542000  2 OK
2017-10-28T21:15:27.003550000  2 waiting
2017-10-28T21:15:27.203619000  2 waited
2017-10-28T21:15:27.203647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.213722000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.213746000  2 OK
2017-10-28T21:15:27.213754000  2 waiting
2017-10-28T21:15:27.513830000  2 waited
2017-10-28T21:15:27.513855000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.523934000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.523956000  2 OK
2017-10-28T21:15:27.523964000  2 waiting
2017-10-28T21:15:27.624041000  2 waited
2017-10-28T21:15:27.624061000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.634138000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.634166000  2 OK
2017-10-28T21:15:27.634175000  2 waiting
2017-10-28T21:15:28.034250000  2 waited
2017-10-28T21:15:28.034286000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.044367000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.044390000  2 OK
2017-10-28T21:15:28.044398000  2 waiting
2017-10-28T21:15:28.144463000  2 waited
2017-10-28T21:15:28.144477000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.154554000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.154574000  2 OK
2017-10-28T21:15:28.154582000  2 waiting
2017-10-28T21:15:28.554654000  2 waited
2017-10-28T21:15:28.554694000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.564788000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.564809000  2 OK
2017-10-28T21:15:28.564817000  2 waiting
2017-10-28T21:15:28.964892000  2 waited
2017-10-28T21:15:28.964930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.975011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.975033000  2 OK
2017-10-28T21:15:28.975041000  2 waiting
2017-10-28T21:15:29.375116000  2 waited
2017-10-28T21:15:29.375152000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.385233000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.385256000  2 OK
2017-10-28T21:15:29.385264000  2 waiting
2017-10-28T21:15:29.585340000  2 waited
2017-10-28T21:15:29.585369000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.595450000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.595472000  2 OK
2017-10-28T21:15:29.595499000  2 waiting
2017-10-28T21:15:29.995580000  2 waited
2017-10-28T21:15:29.995616000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.005699000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.005720000  2 OK
2017-10-28T21:15:30.005728000  2 waiting
2017-10-28T21:15:30.405807000  2 waited
2017-10-28T21:15:30.405841000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.415924000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.415949000  2 OK
2017-10-28T21:15:30.415957000  2 waiting
2017-10-28T21:15:30.916029000  2 waited
2017-10-28T21:15:30.916066000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.926148000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.926170000  2 OK
2017-10-28T21:15:30.926178000  2 waiting
2017-10-28T21:15:31.026251000  2 waited
2017-10-28T21:15:31.026271000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.036349000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.036370000  2 OK
2017-10-28T21:15:31.036378000  2 waiting
2017-10-28T21:15:31.436457000  2 waited
2017-10-28T21:15:31.436496000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.446579000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.446603000  2 OK
2017-10-28T21:15:31.446611000  2 waiting
2017-10-28T21:15:31.746681000  2 waited
2017-10-28T21:15:31.746717000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.756798000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.756820000  2 OK
2017-10-28T21:15:31.756828000  2 waiting
2017-10-28T21:15:32.056900000  2 waited
2017-10-28T21:15:32.056916000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.066994000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.067014000  2 OK
2017-10-28T21:15:32.067022000  2 waiting
2017-10-28T21:15:32.167094000  2 waited
2017-10-28T21:15:32.167110000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.177187000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:32.177207000  2 OK
2017-10-28T21:15:32.177214000  2 waiting
2017-10-28T21:15:32.477286000  2 waited
2017-10-28T21:15:32.477325000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.487402000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.487424000  2 OK
2017-10-28T21:15:32.487432000  2 waiting
2017-10-28T21:15:32.687509000  2 waited
2017-10-28T21:15:32.687547000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.697628000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.697651000  2 OK
2017-10-28T21:15:32.697659000  2 waiting
2017-10-28T21:15:32.897731000  2 waited
2017-10-28T21:15:32.897745000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.907822000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.907842000  2 OK
2017-10-28T21:15:32.907850000  2 waiting
2017-10-28T21:15:33.307919000  2 waited
2017-10-28T21:15:33.307952000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.318032000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.318071000  2 OK
2017-10-28T21:15:33.318080000  2 waiting
2017-10-28T21:15:33.718160000  2 waited
2017-10-28T21:15:33.718215000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.728307000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.728329000  2 OK
2017-10-28T21:15:33.728337000  2 waiting
2017-10-28T21:15:34.228412000  2 waited
2017-10-28T21:15:34.228445000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.238526000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.238548000  2 OK
2017-10-28T21:15:34.238556000  2 waiting
2017-10-28T21:15:34.538629000  2 waited
2017-10-28T21:15:34.538647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.548728000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.548752000  2 OK
2017-10-28T21:15:34.548761000  2 waiting
2017-10-28T21:15:34.948840000  2 waited
2017-10-28T21:15:34.948878000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.958963000  2 get Write  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:34.958987000  2 OK
2017-10-28T21:15:34.958995000  2 waiting
2017-10-28T21:15:35.259070000  2 waited
2017-10-28T21:15:35.259088000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.269165000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.269186000  2 OK
2017-10-28T21:15:35.269194000  2 waiting
2017-10-28T21:15:35.569274000  2 waited
2017-10-28T21:15:35.569311000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.579396000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.579420000  2 OK
2017-10-28T21:15:35.579428000  2 waiting
2017-10-28T21:15:35.879506000  2 waited
2017-10-28T21:15:35.879541000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.889623000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.889644000  2 OK
2017-10-28T21:15:35.889652000  2 waiting
2017-10-28T21:15:36.189721000  2 waited
2017-10-28T21:15:36.189744000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.199823000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.199844000  2 OK
2017-10-28T21:15:36.199852000  2 waiting
2017-10-28T21:15:36.599930000  2 waited
2017-10-28T21:15:36.599964000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.610050000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.610076000  2 OK
2017-10-28T21:15:36.610084000  2 waiting
2017-10-28T21:15:37.010162000  2 waited
2017-10-28T21:15:37.010200000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.020282000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.020305000  2 OK
2017-10-28T21:15:37.020313000  2 waiting
2017-10-28T21:15:37.420390000  2 waited
2017-10-28T21:15:37.420417000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.430498000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.430519000  2 OK
2017-10-28T21:15:37.430527000  2 waiting
2017-10-28T21:15:37.730596000  2 waited
2017-10-28T21:15:37.730633000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.740713000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.740754000  2 OK
2017-10-28T21:15:37.740762000  2 waiting
2017-10-28T21:15:38.140840000  2 waited
2017-10-28T21:15:38.140862000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.150942000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.150963000  2 OK
2017-10-28T21:15:38.150972000  2 waiting
2017-10-28T21:15:38.551046000  2 waited
2017-10-28T21:15:38.551084000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.561169000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.561193000  2 OK
2017-10-28T21:15:38.561201000  2 waiting
2017-10-28T21:15:38.761271000  2 waited
2017-10-28T21:15:38.761315000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.771407000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.771429000  2 OK
2017-10-28T21:15:38.771437000  2 waiting
2017-10-28T21:15:39.171511000  2 waited
2017-10-28T21:15:39.171539000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.181620000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.181645000  2 OK
2017-10-28T21:15:39.181653000  2 waiting
2017-10-28T21:15:39.381735000  2 waited
2017-10-28T21:15:39.381777000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.391859000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.391881000  2 OK
2017-10-28T21:15:39.391889000  2 waiting
2017-10-28T21:15:39.691968000  2 waited
2017-10-28T21:15:39.692008000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.702089000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.702111000  2 OK
2017-10-28T21:15:39.702119000  2 waiting
2017-10-28T21:15:40.002188000  2 waited
2017-10-28T21:15:40.002214000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.012293000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:40.012314000  2 OK
2017-10-28T21:15:40.012322000  2 waiting
2017-10-28T21:15:40.412390000  2 waited
2017-10-28T21:15:40.412415000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.422496000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.422517000  2 OK
2017-10-28T21:15:40.422525000  2 waiting
2017-10-28T21:15:40.822601000  2 waited
2017-10-28T21:15:40.822637000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.832719000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.832741000  2 OK
2017-10-28T21:15:40.832749000  2 waiting
2017-10-28T21:15:41.132824000  2 waited
2017-10-28T21:15:41.132845000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.142924000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.142945000  2 OK
2017-10-28T21:15:41.142953000  2 waiting
2017-10-28T21:15:41.443034000  2 waited
2017-10-28T21:15:41.443077000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.453160000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.453184000  2 OK
2017-10-28T21:15:41.453192000  2 waiting
2017-10-28T21:15:41.753267000  2 waited
2017-10-28T21:15:41.753306000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.763387000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.763426000  2 OK
2017-10-28T21:15:41.763434000  2 waiting
2017-10-28T21:15:41.863510000  2 waited
2017-10-28T21:15:41.863525000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.873605000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.873629000  2 OK
2017-10-28T21:15:41.873637000  2 waiting
2017-10-28T21:15:42.273708000  2 waited
2017-10-28T21:15:42.273741000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.283819000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.283844000  2 OK
2017-10-28T21:15:42.283853000  2 waiting
2017-10-28T21:15:42.583929000  2 waited
2017-10-28T21:15:42.583954000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.594034000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.594056000  2 OK
2017-10-28T21:15:42.594065000  2 waiting
2017-10-28T21:15:42.794142000  2 waited
2017-10-28T21:15:42.794182000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.804264000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.804287000  2 OK
2017-10-28T21:15:42.804296000  2 waiting
2017-10-28T21:15:43.104374000  2 waited
2017-10-28T21:15:43.104400000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.114481000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.114504000  2 OK
2017-10-28T21:15:43.114513000  2 waiting
2017-10-28T21:15:43.314585000  2 waited
2017-10-28T21:15:43.314605000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.324684000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.324707000  2 OK
2017-10-28T21:15:43.324715000  2 waiting
2017-10-28T21:15:43.724984000  2 waited
2017-10-28T21:15:43.725023000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.735103000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.735134000  2 OK
2017-10-28T21:15:43.735143000  2 waiting
2017-10-28T21:15:44.035217000  2 waited
2017-10-28T21:15:44.035255000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.045346000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.045369000  2 OK
2017-10-28T21:15:44.045377000  2 waiting
2017-10-28T21:15:44.245450000  2 waited
2017-10-28T21:15:44.245471000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.255551000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.255574000  2 OK
2017-10-28T21:15:44.255582000  2 waiting
2017-10-28T21:15:44.355662000  2 waited
2017-10-28T21:15:44.355703000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.365786000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.365812000  2 OK
2017-10-28T21:15:44.365821000  2 waiting
2017-10-28T21:15:44.565899000  2 waited
2017-10-28T21:15:44.565930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.576016000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.576041000  2 OK
2017-10-28T21:15:44.576050000  2 waiting
2017-10-28T21:15:44.876120000  2 waited
2017-10-28T21:15:44.876158000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.886240000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.886281000  2 OK
2017-10-28T21:15:44.886290000  2 waiting
2017-10-28T21:15:45.186362000  2 waited
2017-10-28T21:15:45.186384000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.196462000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.196483000  2 OK
2017-10-28T21:15:45.196492000  2 waiting
2017-10-28T21:15:45.296562000  2 waited
2017-10-28T21:15:45.296585000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.306664000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.306685000  2 OK
2017-10-28T21:15:45.306693000  2 waiting
2017-10-28T21:15:45.706766000  2 waited
2017-10-28T21:15:45.706804000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.706821000  2 terminate
2017-10-28T21:15:50.729534000 Main Deadlock detected, aborting
2017-10-28T21:15:50.729586000 Main Done

Task 7 did not terminate.
Last report of it was "21:15:21.149875000  7 get  Read  0.2"
At this time, 1 has got the lock for read, 3 is requesting it for write and
the other tasks are queueing for read or write (7 is queueing for read).
When 1 releases the lock: 017-10-28T21:15:21.349976000  1 release
the log of swapping shows that task 4, requesting for write, triggers the
swapping: Start swapping tasks(4)_0000000000E6EC60
At that time, all the queueing tasks are logged as being swapped except 7,
and task 7 seems to be blocked somewhere and is never activated.

Can you reproduce it? On Windows?
Is the bug in the test program, or in the mutex implementation, in Linux, or in Gnat?

Thanks

^ permalink raw reply	[relevance 4%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  @ 2017-09-23  9:16  5%           ` Jeffrey R. Carter
  0 siblings, 0 replies; 138+ results
From: Jeffrey R. Carter @ 2017-09-23  9:16 UTC (permalink / raw)


On 09/23/2017 10:09 AM, Dmitry A. Kazakov wrote:
> On 2017-09-23 00:15, Victor Porton wrote:
>>
>> In my opinion, it would be better to change RM phrasing from "null string"
>> to "empty string", because in some other languages (notably C) NULL means
>> something other. It is just confusing.
> 
> The adjective null and the noun null are distinct parts of speech. C's noun null 
> is an abbreviation of null pointer. If pointers can be null so strings can.

Another way to look at it: Ada has the formal concepts of:

* null access value ARM 4.2(9)
* null array 3.6.1(7)
* null constraint 3.2(7/2)
* null_exclusion 3.10(5.1/2)
* null extension 3.9.1(4.1/2)
* null procedure 6.7(3/3)
* null range 3.5(4)
* null record 3.8(15)
* null slice 4.1.2(7)
* null string literal 2.6(6)
* null value (of an access type) 3.10(13/2)
* null_statement 5.1(6)

not to mention the language-defined identifiers

Null_Address
    in System   13.7(12)
Null_Bounded_String
    in Ada.Strings.Bounded   A.4.4(7)
Null_Id
    in Ada.Exceptions   11.4.1(2/2)
Null_Occurrence
    in Ada.Exceptions   11.4.1(3/2)
Null_Ptr
    in Interfaces.C.Strings   B.3.1(7)
Null_Set
    in Ada.Strings.Maps   A.4.2(5)
    in Ada.Strings.Wide_Maps   A.4.7(5)
    in Ada.Strings.Wide_Wide_Maps   A.4.8(5/2)
Null_Task_Id
    in Ada.Task_Identification   C.7.1(2/2)
Null_Unbounded_String
    in Ada.Strings.Unbounded   A.4.5(5)

(Just look under N in the index.)

It's called overloading. Many of these cases refer to things that can have 
components and mean one with zero components: a null record has no components, a 
null array has no components ('Length = 0), a null string literal has no 
characters, a null set has no members, ... It should not be confusing.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14

^ permalink raw reply	[relevance 5%]

* Re: Real tasking problems with Ada.
  2017-08-03  8:03  0%     ` Simon Wright
@ 2017-08-04 23:16  0%       ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2017-08-04 23:16 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:ly4ltpqdrm.fsf@pushface.org...
> Robert Eachus <rieachus@comcast.net> writes:
>
>> Sigh! Get_Id as defined is heavy only because of the default initial 
>> value:
>>
>>    function Get_CPU
>>       (T   : Ada.Task_Identification.Task_Id :=
>>                  Ada.Task_Identification.Current_Task)
>>            return CPU_Range;
>
> Would it have been reasonable to have used Null_Task_Id to mean 'the
> current task'? (this is a trick used in FreeRTOS at least).

There are rules about when Current_Task is not well-defined (or can raise 
Program_Error, as it is a bounded error to call it in some places). By using 
that here, we don't have to repeat them in every place that might care about 
the current task. If  you used Null_Task_Id as a placeholder, you would have 
to say that Get_CPU is not well-defined (or even when it can raise 
Program_Error).

You'd also lose the null value for representing "no task", which seems to be 
a common requirement for any kind of type.

Thus, that's not the worst idea, but it would be a pain to define and 
possibly would cause issues for anything that needs to represent "no task" 
(such as the default initialization of a data structure).

                                     Randy.



^ permalink raw reply	[relevance 0%]

* Re: Real tasking problems with Ada.
  2017-08-02  3:44  4%   ` Robert Eachus
  2017-08-03  4:16  0%     ` Randy Brukardt
@ 2017-08-03  8:03  0%     ` Simon Wright
  2017-08-04 23:16  0%       ` Randy Brukardt
  1 sibling, 1 reply; 138+ results
From: Simon Wright @ 2017-08-03  8:03 UTC (permalink / raw)


Robert Eachus <rieachus@comcast.net> writes:

> Sigh! Get_Id as defined is heavy only because of the default initial value:
>
>    function Get_CPU
>       (T   : Ada.Task_Identification.Task_Id :=
>                  Ada.Task_Identification.Current_Task)
>            return CPU_Range;

Would it have been reasonable to have used Null_Task_Id to mean 'the
current task'? (this is a trick used in FreeRTOS at least).


^ permalink raw reply	[relevance 0%]

* Re: Real tasking problems with Ada.
  2017-08-02  3:44  4%   ` Robert Eachus
@ 2017-08-03  4:16  0%     ` Randy Brukardt
  2017-08-03  8:03  0%     ` Simon Wright
  1 sibling, 0 replies; 138+ results
From: Randy Brukardt @ 2017-08-03  4:16 UTC (permalink / raw)


"Robert Eachus" <rieachus@comcast.net> wrote in message 
news:f9e87130-3f08-43c4-8cc6-9e164a6da954@googlegroups.com...
On Tuesday, August 1, 2017 at 12:42:01 AM UTC-4, Randy Brukardt wrote:

>> Use a discriminant of type CPU and (in Ada 2020) an
>> iterated_component_association. (This was suggested way back in Ada 9x, 
>> left
>> out in the infamous "scope reduction", and then forgotten about until 
>> 2013.
>> See AI12-0061-1 or the draft RM
>> http://www.ada-auth.org/standards/2xaarm/html/AA-4-3-3.html).
>
>It is nice that this is in there, just in-time to be outmoded.  See my 
>previous post,
>on most desktop and server processors assigning to alternate processor IDs 
>is
> necessary.

Why would that be "outmoded"? What's wrong with:
    (for I in 1..Number_of_CPUs/2 => new My_Task (The_CPU => I*2));
if you need alternate CPUs? Or, even better, a function call to map the 
linear array indexes to CPUs? This is all dynamic code, after all, write 
anything you need.

>> Why do you say this? Ada doesn't require the task that calls a protected
>> object to execute it (the execution can be handdled by the task that
>> services the barriers - I don't know if any implementation actually does
>> this, but the language rules are written to allow it).

>Um, I say it because any other result is useless?  The use case is for the
>called task or protected object to be able to get the CPU number and
>do something with it.

But that's a nonsense use-case. You're not allowed to ask the Current_Task 
in an entry body or interrupt handler (see C.7.1(17/3) -- the operation is 
allowed to raise Program_Error or return an implementation-defined Task_Id). 
So it's nonsense to ask what CPU you're running on when you're not even 
allowed to ask what task is running.

> The simple case right now would be a protected object whose only purpose
> is to make sure task assignments are compatible with the architecture.

But that's backwards; you use a function to make those assignments when the 
tasks are created. (Again, if you're in a Ravenscar environment, you can't 
do that, but the code has to be tied to a particular CPU layout when it 
compiled, so there's nothing to check.)

...
>> Say what? You're using Get_Id, so clearly you're using something there.
>> Get_Id (like the rest of dispatching domains is likely to be expensive, 
>> so
>> you don't want it dragged into all programs. (And CPU is effectively part 
>> of
>> all programs.)
>
>Sigh! Get_Id as defined is heavy only because of the default initial value:
>
>   function Get_CPU
>     (T   : Ada.Task_Identification.Task_Id :=
>                 Ada.Task_Identification.Current_Task)
>          return CPU_Range;
>
>but a parameterless Get_CPU could compile to a single load instruction.

No chance. You have to make a kernel call to get any thread information 
(like affinities), and that's likely to be more expensive than any task id 
stuff. That "single load instruction" is protected on every archtecture I've 
dealt with, and the kernels don't let programs mess with those instructions 
(and rightly so).

You seem to be thinking of bare machine implementations of Ada, but none of 
those that have existed in the last decade or more have any tasking support. 
Customers aren't interested in such things so far as I can tell. (And I 
agree this is a sad state of affairs, but complaining about it isn't going 
to change anything. I've been told in ARG meetings not to worry about bare 
machine implementations for this reason.)

In any case, you can avoid any heaviness from the default parameter by 
actually providing the task id you need to know about.

...
>> So the capability already exists, but you don't like having to with an 
>> extra
>> package to use it? Have you lost your freaking mind? You want us to add
>> operations that ALREADY EXIST to another package, with all of the
>> compatibility problems that doing so would cause (especially for people 
>> that
>> had withed and used Dispatching_Domains)? When there are lots of problems
>> that can't be solved portably at all?
>
>No, I don't want compilers putting in extra code when it is not necessary. 
>If a
> task has a (static) CPU assignment then again, Get_CPU is essentially 
> free.

No way; you have to get that information from the kernel. So long as Set_CPU 
exists you have to assume that it could have been used. It's only free if 
you've put it into a well-known place (say the discriminant of the task 
type) and read it from there, because you know you didn't use Set_CPU. (Also 
note, at least in the cases of the systems I've worked on, that we don't 
store anything that can be changed by kernel operations in the Ada runtime 
system, so that if someone uses kernel operations to change the values, we 
actually report the real answer and not the one that the compiler knows 
about.)

>Is it cheaper than fishing some index out of main memory because it got
>flushed there? Probably.  Yes, I can make a function My_CPU which
>does this.  I'm just making too many of those workarounds right now.

I don't think this is a workaround. It's WAY cheaper to get this information 
yourself than it is to get it from the kernel.

>> >A function Cache_Line_Size in System or System.Multiprocessors seems 
>> >right.
>>
>> No,  it doesn't. It assumes a particular memory organization, and one 
>> thing
>> that's pretty clear is that whatever memory organization is common now 
>> will
>> not be common in a bunch of years. Besides, so many systems have multiple
>> layers of caches, that a single result won't be enough. And there is no 
>> way
>> for a general implementation to find this out (neither CPUs nor kernels
>> describe such information).

>Um. No.  Systems may have multiple levels of caches of different sizes and
>different numbers of "ways" per cache.  But the actual cache line size is
>almost locked in, and is the same for all caches in a system.  Most systems
>with DDR3 and DDR4 use 64 byte cache lines because it matches the
>memory burst length.  But other values are possible.  Right now HBM2
>is pushing GPUs (not CPUs) to 256 byte cache lines.  Will we eventually
>have Ada compilers generating code for heterogeneous systems?  Possible.
>What I am working on is building the blocks that can be used with
>DirectCompute, OpenCL 2.0, and perhaps other GPU software interfaces.

But you didn't answer the actual question. How in the world would an Ada 
compiler figure out the cache line size? I have no clue as to what it is on 
the computer that I'm writing them on, and it's not something that is 
provided by Windows or Linux. So how could an Ada runtime figure out it out 
and report it?? Janus/Ada programs run on any Win32 system from Windows 95 
on, it's wildly impractical to have some sort of hardware table.

As far as hetrogeneous systems go, you have to assume that (especially in a 
case like this). It would be awful to prevent that just for a little-used 
function. So there can't be an unconditional "cache-line" setting, it has to 
be based on a particular piece of memory. (It's similar in that way to file 
systems; you can have both case-sensitive and case-preserving file systems 
on the same computer and even in the same program.) That's one complication 
of several with discussing "cache-lines", not to mention that the entire 
concept will most likely be gone in a decade.

                            Randy.



^ permalink raw reply	[relevance 0%]

* Re: Real tasking problems with Ada.
  2017-08-01  4:41  0% ` Randy Brukardt
@ 2017-08-02  3:44  4%   ` Robert Eachus
  2017-08-03  4:16  0%     ` Randy Brukardt
  2017-08-03  8:03  0%     ` Simon Wright
  0 siblings, 2 replies; 138+ results
From: Robert Eachus @ 2017-08-02  3:44 UTC (permalink / raw)


On Tuesday, August 1, 2017 at 12:42:01 AM UTC-4, Randy Brukardt wrote:
 
> Use a discriminant of type CPU and (in Ada 2020) an 
> iterated_component_association. (This was suggested way back in Ada 9x, left 
> out in the infamous "scope reduction", and then forgotten about until 2013. 
> See AI12-0061-1 or the draft RM 
> http://www.ada-auth.org/standards/2xaarm/html/AA-4-3-3.html).

It is nice that this is in there, just in-time to be outmoded.  See my previous post, on most desktop and server processors assigning to alternate processor IDs is necessary.

> Why do you say this? Ada doesn't require the task that calls a protected 
> object to execute it (the execution can be handdled by the task that 
> services the barriers - I don't know if any implementation actually does 
> this, but the language rules are written to allow it).

Um, I say it because any other result is useless?  The use case is for the called task or protected object to be able to get the CPU number and do something with it.  The simple case right now would be a protected object whose only purpose is to make sure task assignments are compatible with the architecture.  Again with Zen, Epyx has multiprocessors with 64 cores, 128 threads that will show as CPUs.  There are favored pairings of threads so that they share caches, or have shorter paths to parts of L3.  Intel says they will support up to eight sockets, with 28 CPU cores and 56 threads per socket.  I don't believe a system with 448 CPU threads will be realistic, even 224 will probably stress scheduling.  (Note that many of these "big" systems use VMware to create lots of virtual machines with four or eight threads.)

> Say what? You're using Get_Id, so clearly you're using something there. 
> Get_Id (like the rest of dispatching domains is likely to be expensive, so 
> you don't want it dragged into all programs. (And CPU is effectively part of 
> all programs.)

Sigh! Get_Id as defined is heavy only because of the default initial value:

   function Get_CPU
      (T   : Ada.Task_Identification.Task_Id :=
                 Ada.Task_Identification.Current_Task)
           return CPU_Range;

but a parameterless Get_CPU could compile to a single load instruction.  I'm not asking for the current function to be eliminated, there are situations where it is needed.  But it doesn't need all that baggage for the normal use.

> 
> > 2) Allow a task to  its CPU assignment after it has started execution.  It
> > is no big deal if a task starts on a different CPU than the one it will 
> > spend
> > the rest of its life on.  At a minimum Set_CPU(Current_CPU) or just
> > Set_CPU should cause the task to be anchored to its current CPU core.
> >  Note that again you can do this with Dispatching_Domains.

Left out two words above.  Should read "Allow a task to statically set its CPU assignment...
> 
> So the capability already exists, but you don't like having to with an extra 
> package to use it? Have you lost your freaking mind? You want us to add 
> operations that ALREADY EXIST to another package, with all of the 
> compatibility problems that doing so would cause (especially for people that 
> had withed and used Dispatching_Domains)? When there are lots of problems 
> that can't be solved portably at all?

No, I don't want compilers putting in extra code when it is not necessary.  If a task has a (static) CPU assignment then again, Get_CPU is essentially free.  Is it cheaper than fishing some index out of main memory because it got flushed there? Probably.  Yes, I can make a function My_CPU which does this.  I'm just making too many of those workarounds right now. 
> 
> No, you're missing the point. Ada is about writing portable code. Nothing at 
> the level of "cache lines" is EVER going to be portable in any way. Either 
> one writes "safe" code and hopefully the compiler and runtime can take into 
> account the characteristics of the target. (Perhaps parallel loop constructs 
> will help with that.)
> 

> Or otherwise, one writes bleeding edge code that is not portable and not 
> safe. And you're on your own in such a case; no programming language could 
> possibly help you.

I am trying to write portable code.  Portable enough to run on all modern AMD64 and EM64T (Intel) CPUs.  A table of processor IDs with the associated values for the numbers I need in the program is not going to happen.  Most of the parameters I need can be found in Ada now.  Cache line size is one that is not there.
> 
> >A function Cache_Line_Size in System or System.Multiprocessors seems right.
> 
> No,  it doesn't. It assumes a particular memory organization, and one thing 
> that's pretty clear is that whatever memory organization is common now will 
> not be common in a bunch of years. Besides, so many systems have multiple 
> layers of caches, that a single result won't be enough. And there is no way 
> for a general implementation to find this out (neither CPUs nor kernels 
> describe such information).

Um. No.  Systems may have multiple levels of caches of different sizes and different numbers of "ways" per cache.  But the actual cache line size is almost locked in, and is the same for all caches in a system.  Most systems with DDR3 and DDR4 use 64 byte cache lines because it matches the memory burst length.  But other values are possible.  Right now HBM2 is pushing GPUs (not CPUs) to 256 byte cache lines.  Will we eventually have Ada compilers generating code for heterogeneous systems?  Possible.  What I am working on is building the blocks that can be used with DirectCompute, OpenCL 2.0, and perhaps other GPU software interfaces. 
> 
> >Is adding these features to Ada worth the effort?
> 
> No way. They're much too low level, and they actually aren't enough to allow 
> parallelization. You want a language which allows fine-grained parallelism 
> from the start (like Parasail); trying to retrofit that on Ada (which is 
> mainly sequential, only having coarse parallelism) just will make a mess. 
> You might get a few problems solved (those using actual arrays, as opposed 
> to containers or user-defined types -- which one hopes are far more common 
> in today's programs), but there is nothing general, nor anything that fits 
> into Ada's building block approach, at the level that you're discussing.
> 
For now we can agree to disagree.  The difference is the size of the arrays we have to deal with.  When arrays get to tens of millions of entries, and operations on them can take tens of billions operations, I don't think I am talking about fine grained parallelism.  The main characteristics of the operations I want to get working: matrix multiplication and inversion, linear programming, FFT, FLIR and FLRadar, Navier-Stokes, all have the form of a set of huge data arrays constant once loaded, and can be parallelized across large numbers of CPU cores, or GPUs.                           


^ permalink raw reply	[relevance 4%]

* Re: Real tasking problems with Ada.
  2017-07-25 23:19  2% Real tasking problems with Ada Robert Eachus
  @ 2017-08-01  4:41  0% ` Randy Brukardt
  2017-08-02  3:44  4%   ` Robert Eachus
  1 sibling, 1 reply; 138+ results
From: Randy Brukardt @ 2017-08-01  4:41 UTC (permalink / raw)


"Robert Eachus" <rieachus@comcast.net> wrote in message 
news:9e51f87c-3b54-4d09-b9ca-e3c6a6e8940a@googlegroups.com...
> First, it should be possible to assign tasks in arrays to CPUs.

Use a discriminant of type CPU and (in Ada 2020) an 
iterated_component_association. (This was suggested way back in Ada 9x, left 
out in the infamous "scope reduction", and then forgotten about until 2013. 
See AI12-0061-1 or the draft RM 
http://www.ada-auth.org/standards/2xaarm/html/AA-4-3-3.html).

...
>1) Add a function Current_CPU or whatever (to System.Multiprocessors) that
> returns the identity of the CPU this task is running on.  Obviously in a 
> rendezvous
> with a protected object, the function would return the ID of the caller.

Why do you say this? Ada doesn't require the task that calls a protected 
object to execute it (the execution can be handdled by the task that 
services the barriers - I don't know if any implementation actually does 
this, but the language rules are written to allow it).

>  Probably do the same thing in a rendezvous between two tasks for 
> consistency.
>  Note that Get_ID function in System.Multiprocessors.Dispatching_Domains
> does that but it requires adding three (unnecessary) packages (DD,
> Ada.Real_Time, and Ada.Task_Identification) to your context without really
> using anything there.

Say what? You're using Get_Id, so clearly you're using something there. 
Get_Id (like the rest of dispatching domains is likely to be expensive, so 
you don't want it dragged into all programs. (And CPU is effectively part of 
all programs.)

> 2) Allow a task to  its CPU assignment after it has started execution.  It
> is no big deal if a task starts on a different CPU than the one it will 
> spend
> the rest of its life on.  At a minimum Set_CPU(Current_CPU) or just
> Set_CPU should cause the task to be anchored to its current CPU core.
>  Note that again you can do this with Dispatching_Domains.

So the capability already exists, but you don't like having to with an extra 
package to use it? Have you lost your freaking mind? You want us to add 
operations that ALREADY EXIST to another package, with all of the 
compatibility problems that doing so would cause (especially for people that 
had withed and used Dispatching_Domains)? When there are lots of problems 
that can't be solved portably at all?

>Next, a huge problem.  I just had some code churn out garbage while I was 
>finding the
> "right" settings to get each chunk of work to have its own portion of an 
> array.  Don't tell
> me how to do this safely, if you do you are missing the point.

No, you're missing the point. Ada is about writing portable code. Nothing at 
the level of "cache lines" is EVER going to be portable in any way. Either 
one writes "safe" code and hopefully the compiler and runtime can take into 
account the characteristics of the target. (Perhaps parallel loop constructs 
will help with that.)

Or otherwise, one writes bleeding edge code that is not portable and not 
safe. And you're on your own in such a case; no programming language could 
possibly help you.

>A function Cache_Line_Size in System or System.Multiprocessors seems right.

No,  it doesn't. It assumes a particular memory organization, and one thing 
that's pretty clear is that whatever memory organization is common now will 
not be common in a bunch of years. Besides, so many systems have multiple 
layers of caches, that a single result won't be enough. And there is no way 
for a general implementation to find this out (neither CPUs nor kernels 
describe such information).

>Is adding these features to Ada worth the effort?

No way. They're much too low level, and they actually aren't enough to allow 
parallelization. You want a language which allows fine-grained parallelism 
from the start (like Parasail); trying to retrofit that on Ada (which is 
mainly sequential, only having coarse parallelism) just will make a mess. 
You might get a few problems solved (those using actual arrays, as opposed 
to containers or user-defined types -- which one hopes are far more common 
in today's programs), but there is nothing general, nor anything that fits 
into Ada's building block approach, at the level that you're discussing.

                             Randy.



^ permalink raw reply	[relevance 0%]

* Re: Real tasking problems with Ada.
  @ 2017-07-27  2:00  5%   ` Robert Eachus
  0 siblings, 0 replies; 138+ results
From: Robert Eachus @ 2017-07-27  2:00 UTC (permalink / raw)


On Wednesday, July 26, 2017 at 3:42:57 PM UTC-4, sbelm...@gmail.com wrote:
> On Tuesday, July 25, 2017 at 7:19:59 PM UTC-4, Robert Eachus wrote:
> >    1) Add a function Current_CPU or whatever (to System.Multiprocessors) that returns the identity of the CPU this task is running on.  
> > 
> >    2) Allow a task to  its CPU assignment after it has started execution. 
> > 
> 
> Are these not exactly what System.Multiprocessors.Dispatching_Domains.Get_CPU and Set_CPU do?

Short answer, not exactly.  Yes, if I had posted the code I'm working on--probably sometime next week--you would have seen me using just that.  But the operations from Dispatching_Domains are pretty heavyweight--even if you ignore bringing in the extra packages.  What I would like are very lightweight operations.  Bringing in Ada.Real_Time and Ada.Task_Identification for default parameters which are never used would be bad enough, the problem is the program ends up checking the values passed.  So a call to Set_CPU(ID); is really a call to: Set_CPU(ID, Ada.Task_Identification.Current_Task), which can't be done before a task has an ID assigned.

If on a particular implementation, they are exactly the same, then all I am asking for is some declarative sugar which requires four lines of source added to Ada.Multitasking.  But what I really want is the ability to start a task on the processor core it will stay on.  Ah, you say, I can set the aspect CPU.  Well, not really.

I can't determine how many CPU cores are available until run-time.  That means if I want to generate tasks on a per CPU core basis, I can/must create them at run-time.  But there is no way for me to set the CPU aspect when I have an array of (identical) tasks.  I can set the aspect for tasks named Tom, Dick, and Harry like in the examples, but if I declare: Worker_Tasks: array(1..Number_of_CPUs), I can't set the CPU other than by an entry, which serializes the tasks when there are lots of them.  Remember, some of those tasks, on some hardware, will need to run on a chip in a socket over there somewhere.

It's just making things harder for non-real-time programmers for no reason.  And when you see the results from the work I am doing, you will be either astonished or appalled.


^ permalink raw reply	[relevance 5%]

* Real tasking problems with Ada.
@ 2017-07-25 23:19  2% Robert Eachus
    2017-08-01  4:41  0% ` Randy Brukardt
  0 siblings, 2 replies; 138+ results
From: Robert Eachus @ 2017-07-25 23:19 UTC (permalink / raw)


This may come across as a rant.  I've tried to keep it down, but a little bit of ranting is probably appropriate.  Some of these problems could have been fixed earlier, but there are some which are only coming of age with new CPU and GPU designs, notably the Zen family of CPUs from AMD.

Let me first explain where I am coming from (at least in this thread).  I want to write code that takes full advantage of the features available to run code as fast as possible.  In particular I'd like to get the time to run some embarrassingly parallel routines in less than twice the total CPU time of a single CPU.  (In other words, a problem that takes T seconds (wall clock) on a single CPU should run in less than 2T/N wall clock time on N processors. Oh, and it shouldn't generate garbage.  I'm working on a test program and it did generate garbage once when I didn't guess some of the system parameters right. 

So what needs to be fixed.  First, it should be possible to assign tasks in arrays to CPUs.  With a half dozen CPU cores the current facilities are irksome.  Oh, and when doing the assignment it would be nice to ask for the facilities you need, rather than have per manufacturer's family code.  Just to start with, AMD has some processors which share floating-point units, so you want to run code on alternate CPU cores on those machines--if the tasks make heavy use of floating point.

Intel makes some processors with Hyperthreading, and some without, even within the same processor family.  Hyperthreading does let you get some extra performance out if you know what you are doing, but much of the time you will want the Hyperthreading alternate to do background and OS processing while allocating your heavy hitting work threads to the main threads.

Now look at AMD's Zen family.  Almost all available today have two threads per core like Intel's Hyperthreading, but these are much more like twins.  With random loads, each thread will do about the same amount of work.  However, if you know what you are doing, you can write code which usefully hogs all of the core's resources if it can.  Back to running on alternate cores...

I know that task array types were considered in Ada 9X.  I don't know what happened to them.  But even without them, two huge improvements would be:

   1) Add a function Current_CPU or whatever (to System.Multiprocessors) that returns the identity of the CPU this task is running on.  Obviously in a rendezvous with a protected object, the function would return the ID of the caller.  Probably do the same thing in a rendezvous between two tasks for consistency.  Note that Get_ID function in System.Multiprocessors.Dispatching_Domains does that but it requires adding three (unnecessary) packages (DD, Ada.Real_Time, and Ada.Task_Identification) to your context without really using anything there. 

   2) Allow a task to  its CPU assignment after it has started execution.  It is no big deal if a task starts on a different CPU than the one it will spend the rest of its life on.  At a minimum Set_CPU(Current_CPU) or just Set_CPU should cause the task to be anchored to its current CPU core.  Note that again you can do this with Dispatching_Domains.

   Stretch goal:  Make it possible to assign tasks to a specific pair of threads. In theory Dispatching_Domains does this, but the environment task messes things up a bit.  You need to leave the partner of the environment task's CPU core in the default dispatching domain.  The problem is that there is no guarantee that the environment task is running on CPU 1 (or CPU 0, the way the hardware numbers them).

Next, a huge problem.  I just had some code churn out garbage while I was finding the "right" settings to get each chunk of work to have its own portion of an array.  Don't tell me how to do this safely, if you do you are missing the point.  If each cache line is only written to by one task, that should be safe.  But to do that I need to determine the size of the cache lines, and how to force the compiler to allocate the data in the array beginning on a cache line boundary.  The second part is not hard, except that the compiler may not support alignment clauses that large.  The first?  A function Cache_Line_Size in System or System.Multiprocessors seems right.  Whether it is in bits or storage_units is no big deal.  Why a function not a constant?  The future looks like a mix of CPUs and GPUs all running parts of the same program.

Finally, caches and NUMA galore.  I mentioned AMD's Zen above.  Right now there are three Zen families with very different system architectures.  In fact, the difference between single and dual socket Epyc makes it four, and the Ryzen 3 and Ryzen APUs when released?  At least one more.  What's the big deal?  Take Threadripper to begin with.  Your choice of 12 or 16 cores each supporting two threads.  But the cache hierarchy is complex.  Each CPU core has two threads and its own L1 and L2 caches.  Then 3 or 4 cores, depending on the model share the same 8 Meg L3 cache. The four blocks of CPU cores and caches are actually split between two different chips.  Doesn't affect the cache timings much, but half the memory is attached to one chip, half to the other.  The memory loads and stores, if to the other chip, compete with L3 and cache probe traffic.  Let's condense that to this: 2 (threads)/(3 or 4) cores/2 (NUMA pairs)/2(chips)/1 (socket).  A Ryzen 7 chip is 2/4/2/1/1, Ryzen 5 is 2/(3 or 2)/2/1/1, Ryzen 3 1/2/2/1/1.  Epyc comes in at 2/(3 or 4)/2/4/2 among other flavors.

Writing a package to recognize these models and sort out for executable programs is going to be a non-trivial exercise--at least if I try to keep it current.  But how to convey the information to the software which is going to try to saturate the system?  No point in creating tasks which won't have a CPU core of their own (or half a core, or what you count Hyperthreading as).  Given the size of some of these systems, even without the HPC environment, it may be better for a program to split the work between chips or boxes.

Is adding these features to Ada worth the effort?  Sure.  Let me give you a very realistic example.  Running on processor cores which share L3 cache may be worthwhile.  Actually with Zen, the difference is that a program that stays on one L3 cache will actually save a lot of time on L2 probes.  (The line you need is in L2 on another CPU core.  Moving it to your core will take less time, and more importantly less latency than moving it from another CPU cluster.)  So we go to write our code.  On Ryzen 7 we want to run on cores 1, 3, 5, and 7 or 9, 11, 13 and 15, or 2, 4, 6, 8 or...  Actually I could choose 1,4,6, and 7, any set of one core from each pair staying within the module (of eight threads).  Move to a low-end Ryzen 3, and I get almost the same performance by choosing all the available cores: 1, 2, 3, and 4.  What about Ryzen 5 1600 and 1600X?  Is it going to be better to run on 3 cores and one L3 cache or 4 cores spread across two caches?    Or maybe choose all six cores on one L3 cache?  Argh!

Is this problem real?  Just took a program from  7.028 seconds on six cores, to 2.229 seconds on (the correct) three cores.  I'll post the program, or put it on-line somewhere once I've confined the memory corruption to very small examples--so you can see which machines do it--and do a bit more cleanup and optimization.

^ permalink raw reply	[relevance 2%]

* ANN: Cortex GNAT RTS 20160522
@ 2016-05-22 14:20  4% Simon Wright
  0 siblings, 0 replies; 138+ results
From: Simon Wright @ 2016-05-22 14:20 UTC (permalink / raw)


Available at
https://sourceforge.net/projects/cortex-gnat-rts/files/20160522/

This release includes GNAT Ada Run Time Systems (RTSs) based
on FreeRTOS (http://www.freertos.org) and targeted at boards with
Cortex-M3, -M4, -M4F MCUs (Arduino Due from http://www.arduino.org,
the STM32F4-series evaluation boards from STMicroelectronics at
http://www.st.com).

In each case, the board support for the RTS (configuration for size
and location of Flash, RAM; clock initialization; interrupt naming) is
in $RTS/adainclude. Support for the on-chip peripherals is also
included, in Ada spec files generated by SVD2Ada
(https://github.com/AdaCore/svd2ada).

The Ada source is either original or based on FSF GCC (mainly 4.9.1,
some later releases too).

(1) arduino-due is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the Arduino Due.

    See arduino-due/COPYING* for licensing terms.

    On-chip peripheral support in atsam3x8e/.

    Tests in test-arduino-due/.

(2) stm32f4 is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F4-DISC* board.

    See stm32f4/COPYING* for licensing terms.

    On-chip peripheral support in stm32f40x/.

    Tests in test-stm32f4/.

(3) stm32f429i is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F429I-DISC* board.

    See stm32f429i/COPYING* for licensing terms.

    On-chip peripheral support in stm32f429x/.

    Tests in test-stm32f429i/.

In this release,

* There is no longer any dependence on the STMicroelectronics'
  STM32Cube package.

* The support for on-chip peripherals is limited to the
  SVD2Ada-generated spec files. The AdaCore 'bareboard' software
  (currently https://github.com/AdaCore/bareboard, but a name change
  is under consideration) supports the STM32 line.

* Tasking no longer requires an explicit start
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/5/).

* Locking in interrupt-handling protected objects no longer inhibits
  all interrupts, only those of equal or lower priority
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/18/).

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 4%]

* timer_server triggers Task_Termination handler
@ 2016-04-21 10:23  6% Per Dalgas Jakobsen
  0 siblings, 0 replies; 138+ results
From: Per Dalgas Jakobsen @ 2016-04-21 10:23 UTC (permalink / raw)


Is it correct behaviour when tasks internal to the GNAT run-time causes 
users task_termination handlers to be called?

This behaviour is seen on:
   1) Debian Linux: gnat-5 (Ada 2005, Ada 2012).
   2) AIX: GNAT Pro 6.1.0w (Ada 2005).

A simple demonstration of the issue:

--------------------------------------------------------------------------------
with Ada.Text_IO;
with Log_Unhandled_Exceptions;

procedure Timer_Server_Noise is

begin
    Ada.Text_IO.Put_Line ("Start of main");

    select
       delay 0.5;
    then abort
       loop
          delay 0.1;
       end loop;
    end select;

    Ada.Text_IO.Put_Line ("End of main");
end  Timer_Server_Noise;
--------------------------------------------------------------------------------
with Ada.Exceptions;
with Ada.Task_Identification;
with Ada.Task_Termination;

package Log_Unhandled_Exceptions is

    pragma Elaborate_Body;

    use Ada.Task_Identification;
    use Ada.Task_Termination;
    use Ada.Exceptions;

    --
    protected Last_Wishes is
       procedure Log_Any_Exit (Cause : in Cause_Of_Termination;
                               T     : in Task_Id;
                               E     : in Exception_Occurrence);
    end;

end Log_Unhandled_Exceptions;
--------------------------------------------------------------------------------
with Ada.Text_IO;


package body Log_Unhandled_Exceptions is

    -- Encapsulates the actual log call
    procedure Log (Text : in String) is
    begin
       Ada.Text_IO.Put_Line ("Log_Unhandled_Exceptions >> " &
                               Text);
    end Log;

    --
    protected body Last_Wishes is

       procedure Log_Any_Exit (Cause : in Cause_Of_Termination;
                               T     : in Task_Id;
                               E     : in Exception_Occurrence) is
       begin
          case Cause is
             when Normal =>
                Log ("Normal exit of task: " & Image (T));
             when Abnormal =>
                Log ("Abnormal exit of task: " & Image (T));
             when Unhandled_Exception =>
                Log ("Unhandled exception in task: " & Image (T));
          end case;
       end Log_Any_Exit;

    end Last_Wishes;


begin
    if Current_Task_Fallback_Handler = null then
       Set_Dependents_Fallback_Handler (Last_Wishes.Log_Any_Exit'Access);
    else
       Log ("Fallback handler already set, will not set own handler.");
    end if;

    if Specific_Handler (Current_Task) = null then
       Set_Specific_Handler (Current_Task, Last_Wishes.Log_Any_Exit'Access);

    else
       Log ("Specific handler already set, will not set own handler.");
    end if;
end Log_Unhandled_Exceptions;
--------------------------------------------------------------------------------

~Per

^ permalink raw reply	[relevance 6%]

* ANN: Cortex GNAT RTS 20160314
@ 2016-03-14 17:42  5% Simon Wright
  0 siblings, 0 replies; 138+ results
From: Simon Wright @ 2016-03-14 17:42 UTC (permalink / raw)


At https://sourceforge.net/projects/cortex-gnat-rts/files/20160314/.

This release includes

* an RTS for the Arduino Due, arduino-due, and a minimal BSP,
  arduino-due-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i-disco-rtos, based on
  STMicroelectronics' STM32Cube package and FreeRTOS, and a
  corresponding partial BSP, stm32f429i-disco-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i, based on FreeRTOS, with
  a set of peripheral definition packages created by SVD2Ada.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 5%]

* ANN: Cortex GNAT RTS 20160207
@ 2016-02-07 22:45  5% Simon Wright
  0 siblings, 0 replies; 138+ results
From: Simon Wright @ 2016-02-07 22:45 UTC (permalink / raw)


This release is at Sourceforge[1].

This release includes an RTS for the Arduino Due, arduino-due, and a
minimal BSP, arduino-due-bsp.

For the STM32F429I-DISCO, there is one RTS, stm32f429i-disco-rtos, and
one BSP, stm32f429i-disco-bsp.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

* FreeRTOS is configured to detect stack overflow (if it is detected,
  the RTS loops inside vApplicationStackOverflowHook()).

The standard packages included (there are more,
implementation-specific, ones) are:

   Ada
   Ada.Containers
   Ada.Containers.Bounded_Hashed_Maps
   Ada.Containers.Bounded_Vectors
   Ada.Exceptions
   Ada.IO_Exceptions
   Ada.Interrupts
   Ada.Interrupts.Names
   Ada.Iterator_Interfaces
   Ada.Real_Time
   Ada.Streams
   Ada.Synchronous_Task_Control
   Ada.Tags
   Ada.Task_Identification
   Interfaces
   Interfaces.C
   Interfaces.C.Strings
   System
   System.Assertions
   System.Address_To_Access_Conversions
   System.Storage_Elements
   GNAT
   GNAT.Source_Info

The software is supplied built with for debugging (-g) and with suitable
optimisation (-Og), using GNAT GPL 2015 on Mac OS X (it should work
out of the box with a Linux-hosted GNAT GPL 2015 cross-compiler, but
will need recompiling for another compiler version).

[1] https://sourceforge.net/projects/cortex-gnat-rts/files/20160207/


^ permalink raw reply	[relevance 5%]

* ANN: STM32F4 GNAT Run Time Systems 20150406
@ 2015-04-06 17:27  5% Simon Wright
  0 siblings, 0 replies; 138+ results
From: Simon Wright @ 2015-04-06 17:27 UTC (permalink / raw)


This is the fourth release of a GNAT RTS with the GCC Runtime Library
exception for STM32F4 boards.

(a) Tasking is implemented using FreeRTOS[3], which STMicroelectronics
    provide a copy of with their BSP.

(b) I've included a BSP with minimal higher-level Ada interfaces to the
    board hardware: clock, buttons, LEDs, LCD. In addition, there's a
    machine-generated translation of STMicroelectronics' type-specific
    header in stm32f429xx_h.ads, for low-level interfacing.

The release is at
https://sourceforge.net/projects/stm32f4-gnat-rts/files/20150406/.

From its README,

20150406
========

This release has been reorganised from previous releases.

There is one RTS, stm32f4-disco-rtos, and one BSP, stm32f4-disco-bsp.

Changes to the RTS from the previous release:
---------------------------------------------

These units (and supporting units) are now included:

  Ada.Containers.Bounded_Vectors (*)
  Ada.Containers.Bounded_Hashed_Maps (*)
  Ada.Containers.Generic_Array_Sort
  Ada.Containers.Generic_Constrained_Array_Sort
  Ada.IO_Exceptions
  Ada.Streams
  Ada.Task_Identification
  Interfaces.C
  Interfaces.C.Strings
  System.Assertions

  (*) The new iterators (for some F in Foo loop ...) are NOT supported
      (they require finalization).

The STM32F429I_Discovery tree has been moved to the BSP.

The following tickets have been fixed:

  2  Protected spec hides package Interfaces
  14 Last_Chance_Handler doesn’t stop tasking

Tasking is started by calling Start_FreeRTOS_Scheduler.

^ permalink raw reply	[relevance 5%]

* Re: Access parameters and accessibility
  2014-12-18  0:56  0%         ` Robert A Duff
@ 2014-12-18  1:17  0%           ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2014-12-18  1:17 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccwq5prd0n.fsf@shell01.TheWorld.com...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
...
>> In the case of Timer, (a) no one ever uses this feature, and (b) I have 
>> no
>> idea why this just isn't
>>
>> type Timer (T : Ada.Task_Identification.Task_Id) is tagged limited 
>> private;
>
> Because Task_Id is a private type, and unfortunately you can't have
> discriminants of private type in Ada.

Ah yes, another language bug that we had to work around. I'm sure that by 
Ada 2045 discriminants will be allowed to be any type. ;-)

> But it if is actually used as an access type (with the access value being
>> copied somewhere), then you have trouble (with random Program_Errors and 
>> a
>> need to avoid passing local objects). It's possible in Ada 2012 to write 
>> a
>> precondition for this case, but of course that's not required (and surely 
>> is
>> not found in existing libraries), so the possibility doesn't help much.
>
> Not sure what you mean.  Could you show an example of such a
> precondition?

We extended membership checks to do accessibility checking in Ada 2005. (One 
of the things near the top of my ACATS priority list is to create a couple 
of tests for that feature.)

So if you have something like (stolen from Claw):

     type Any_Window_Type is access all Root_Window_Type'Class;

then you could write:

     procedure Show (Win : access Root_Window_Type; How : in 
Show_Window_Kind)
         with Pre => Win in Any_Window_Type;

and that will fail if Win is not convertable to Any_Window_Type, including 
accessibility. (See 4.5.2(30.3/4)). [I think we put this feature in in 
response to a comment/e-mail made by one Bob Duff. But it was a long time 
ago, so I might be wrong about that.]

The presence of such a precondition clearly shows that we're going to make 
an accessibility check in the body of the routine, and thus one had better 
not pass a local object. Of course if you just have:

     procedure Show (Win : access Root_Window_Type; How : in 
Show_Window_Kind);

you don't know that there isn't any conversion. Indeed, I don't know of any 
way to declare that no conversion happens (you can't really write that there 
are no restrictions). I suppose Pre => True sort of has that effect, if it's 
really meant and not just a short-hand for I-dunno!

Of course, the actual Claw specification is:
     procedure Show (Win : in Root_Window_Type; How : in Show_Window_Kind);
and we use 'Unchecked_Access and finalization to ensure that there's no 
dangling pointer problems for the conversion. Which is better still, IMHO 
(as no restrictions are needed).

                                            Randy.




^ permalink raw reply	[relevance 0%]

* Re: Access parameters and accessibility
  2014-12-17 23:18  4%       ` Randy Brukardt
@ 2014-12-18  0:56  0%         ` Robert A Duff
  2014-12-18  1:17  0%           ` Randy Brukardt
  0 siblings, 1 reply; 138+ results
From: Robert A Duff @ 2014-12-18  0:56 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> Yup. With the exception of timers, all of the others stem directly from the 
> mistake of using an anonymous access for streams. And *that* stems from the 
> mistake of not allowing "in out" parameters for functions (as Input is a 
> function).

Yes, and *that* stems from the unfortunate fact that 'out' parameters
don't work like function results (for composites).

> Ergo, in Ada 2012 you would write those as "in out Root_Stream_Type'Class". 
> And one should think of them as exactly that. (It's too late to fix this 
> mistake, sadly.)

Yes.

> In the case of Timer, (a) no one ever uses this feature, and (b) I have no 
> idea why this just isn't
>
> type Timer (T : Ada.Task_Identification.Task_Id) is tagged limited private;

Because Task_Id is a private type, and unfortunately you can't have
discriminants of private type in Ada.

> But it if is actually used as an access type (with the access value being 
> copied somewhere), then you have trouble (with random Program_Errors and a 
> need to avoid passing local objects). It's possible in Ada 2012 to write a 
> precondition for this case, but of course that's not required (and surely is 
> not found in existing libraries), so the possibility doesn't help much.

Not sure what you mean.  Could you show an example of such a
precondition?

- Bob


^ permalink raw reply	[relevance 0%]

* Re: Access parameters and accessibility
  @ 2014-12-17 23:18  4%       ` Randy Brukardt
  2014-12-18  0:56  0%         ` Robert A Duff
  0 siblings, 1 reply; 138+ results
From: Randy Brukardt @ 2014-12-17 23:18 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:eea29e4c-921a-467c-8007-80e80eda3507@googlegroups.com...
On Tuesday, December 16, 2014 11:46:59 AM UTC-8, Michael B. wrote:
...
>I'm sure Randy was being tongue-in-cheek when he said "get better 
>libraries".

Ahh, no.

...
>For one thing, you'd have to get better libraries than the libraries Ada 
>provides,
>because Ada defines some subprograms with anonymous access 
>parameters--namely
>Ada.Tags.Generic_Dispatching_Constructor, Ada.Execution_Time.Timers.Timer, 
>and >Read|Write_Exception_Occurrence in Ada.Exceptions. Also, the stream 
>attribute
>subprograms ('Read, 'Write, etc.) all have anonymous access parameters, and 
>you
>have to *write* a subprogram that has an anonymous access parameter in 
>order to
>use it as the stream subprogram for a type.  Quelle horreur!

Yup. With the exception of timers, all of the others stem directly from the 
mistake of using an anonymous access for streams. And *that* stems from the 
mistake of not allowing "in out" parameters for functions (as Input is a 
function).

Ergo, in Ada 2012 you would write those as "in out Root_Stream_Type'Class". 
And one should think of them as exactly that. (It's too late to fix this 
mistake, sadly.)

In the case of Timer, (a) no one ever uses this feature, and (b) I have no 
idea why this just isn't

type Timer (T : Ada.Task_Identification.Task_Id) is tagged limited private;

I have no idea who has an aliased Task_Id laying around anyway. That seems 
amazingly hard to use for no value whatsoever. I suspect it was something 
else originally and it never got changed sensibly.

>Anyway, I think you can avoid defining new subprograms that take anonymous 
>access
>parameters (except where needed for streams, or for 
>Generic_Dispatching_Constructor)
>and not add to the problem, but I don't see any value in avoiding existing 
>libraries.

Well, if you could tell a-priori if "access" was used as a stand-in for "in 
out", then it would be OK. In that case, the only use of the "access" is to 
dereference it.

But it if is actually used as an access type (with the access value being 
copied somewhere), then you have trouble (with random Program_Errors and a 
need to avoid passing local objects). It's possible in Ada 2012 to write a 
precondition for this case, but of course that's not required (and surely is 
not found in existing libraries), so the possibility doesn't help much.

Since you can't tell these cases apart (and the first is never necessary in 
Ada 2012 anyway, with the possible exception of foreign conventions), it's 
best to just avoid the feature. Especially as "access" is more expensive 
than "in out" because of the dynamic accessibility checking overhead (which 
exists regardless of whether it is ever used). Libraries should reflect this 
(moreso as Ada 2012 gets adopted more).

                                Randy.


^ permalink raw reply	[relevance 4%]

* Re: passing messages between the tasks
  @ 2014-10-14 22:22  4%         ` Shark8
  0 siblings, 0 replies; 138+ results
From: Shark8 @ 2014-10-14 22:22 UTC (permalink / raw)


On 10/14/2014 3:08 PM, compguy45@gmail.com wrote:
> What i am trying to do is something like this....code from above...
>
> 3
>    4 procedure SomeProcedure is
>    5
>    6 task type lamp is
>    7    entry reset(id : Integer);
>    8 end lamp;
>    9
>   10 lamps : array (1..6) of lamp;
>   11
>   12    task body lamp is
>   13    begin
>   14       Put_Line("Body of task lamp");
>   15       accept reset(id : Integer) do
>   16         put("inside reset");
>   17         put(id);
>   18         New_Line;
>   19       end reset;
>   20       delay 4.0;
>   21    put("after accept");
>   22    end lamp;
>   23
>   24 begin
>   25    lamps(1).reset(id => 1);
>   26    lamps(2).reset(id => 2);
>   27 end SomeProcedure;
>
> I am trying to figure out how to do following....
> have say main tasks call reset on say lamps(3).reset....
> Then lamp(3) would call reset on lamps(2) and lamps(1) and wait
> then someone lamps(2) and lamps(1) when they done with reset
> would somehow let lamp(3) know about it....
>
>Is this possible to do...?

Hm, I think it is -- but it's a bit on the convoluted side; when I saw 
your first post asking the same question I wrote up some code as a bit 
of a proof of concept. It kind-of works, I could probably get it a lot 
better if (A) I had more time, and/or (B) I had more experience w/ 
tasks. {Tasks are a great feature; I just haven't had occasion to use 
them all that often.}

Anyway; here's what I got for making a network of tasks -- which is, 
essentially, what you're asking about:

-----------------
--  NODES.ADS  --
-----------------

Package Nodes is
    type Node_Interface is task interface;


    type Node_Access is access all Node_Interface'Class;
    type Node_List is array(Positive range <>) of Node_Access;

    Function "XOR" (Left : Node_List; Right : Positive) return Node_List is
      ( Left(Left'First..Natural'Pred(Right)) & 
Left(Natural'Succ(Right)..Left'Last) );
    Function "XOR" (Left : Node_List; Right : Positive) return not null 
access Node_List is
      ( New Node_List'(Left XOR Right) );


    Function Null_List return not null access Node_List is
       ( New Node_List'(2..1 => <>) );

    Function Make_Network(Size : Natural) return not null access Node_List;

    task type Node( Neighbors : not null access Node_List ) is
         new Node_Interface with
    end Node;

End Nodes;


-----------------
--  NODES.ADB  --
-----------------
with
Ada.Task_Identification,
Unchecked_Conversion,
      System.Address_To_Access_Conversions,
      System.Address_Image,
Ada.Text_IO;

Package body Nodes is
    Package Node_Pointers is new
      System.Address_To_Access_Conversions(Object => Node);

    Function Convert is new Unchecked_Conversion
      (Source => Node_Pointers.Object_Pointer,  Target => Node_Access);

    Function Convert( A : System.Address ) return Node_Access is
      ( Convert(Node_Pointers.To_Pointer( A )) );

    task body Node is
       use Ada.Task_Identification, System;

       New_Line : Constant String:= ASCII.CR & ASCII.LF;


       Function Line_1 return String is
         ("Task " & Image(Current_Task) & ": " & Neighbors'Length'Img
              & ASCII.HT & Address_Image(Node'Access.All'Address)
          & New_Line
         );

       Function Line_2( Input : Node_List ) return String is
         (if Input'Length = 0 then ""
          else
              ASCII.HT & Address_Image(Input(Input'First).All'Address) & 
New_Line
            & Line_2( Input(Input'First+1..Input'Last) )
         );

       Function Line_2 return String is
          ( Line_2(Node.Neighbors.All) );
       Function Line_3 return String is
         ("Done.");
    begin
       Ada.Text_IO.Put_Line( Line_1 & Line_2 & Line_3 );
       null;
    end Node;


    Function Make_Network(Size : Natural) return Node_List;
    Function Make_Network(Size : Natural) return not null access 
Node_List is
       ( New Node_List'(Make_Network(size)) );


    Function Make_Network(Size : Natural) return Node_List is
       subtype Full_Range       is Positive Range 1..Size;
       subtype Full_Node_List   is Node_List(Full_Range);

       subtype Constrained_List is Node_List(1..Size-1);
       subtype Constrained_Node is Node( Neighbors => new 
Constrained_List );
       Type Task_Array is array (Full_Range) of aliased Constrained_Node;

       Package TAP is new System.Address_To_Access_Conversions(Task_Array);

       Generic
       Package Incrementation is
          Procedure Increment;
          Function  Increment return Full_Range;
       End Incrementation;

       Package body Incrementation is
          Index : Full_Range:= Full_Range'First;
          Function  Increment return Full_Range is
          begin
             Return  Result : constant Full_Range:= Index do
                Increment;
             end return;
          end Increment;

          Procedure Increment is
          begin
             Index:= (if Index = Full_Range'Last then Full_Range'First
                      else Full_Range'Succ( Index ));
          end Increment;
       end Incrementation;


       Function Make_Nodes(Task_List : out Task_Array) return Node_List is

          Package Inc is new Incrementation;
          Use Inc;

          List : constant Full_Node_List:=
            ( others => Convert(Task_List(Increment)'Address) );

             Function Get_List return Constrained_List is
             begin
                Return Result : Constrained_List:= List xor Increment;
             end;

             List_List : constant Array(Full_Range) of Constrained_List:=
                            (others => Get_List);

          Function Make_Tasks( List : Full_Node_List ) return Task_Array is
             Subtype Actual_Node is
               Node(Neighbors => New Node_List'(List_List(Increment)));
             Type Task_Cluster is Array(Full_Range) of Actual_Node;

             Function Tasks return Task_Cluster is
             begin
                Return result: Task_Cluster;
             end;

             Function Convert is new Unchecked_Conversion
               (Source => Task_Cluster, Target => Task_Array);
          begin
             Return Convert( Tasks );
          end Make_Tasks;



       Begin
          return Result : Full_Node_List := List do

             declare
                pragma Warnings( Off );
                K : Task_Array:= Make_Tasks(result)
                  with Address => Task_List'Address;
                pragma Warnings( On );
             begin
                null;
             end;
--              for Index in Full_Range loop
--                 declare
--                    N : Node renames Task_List(Index);
--                    A : constant System.Address := N'Address;
--                    pragma Warnings( Off );
--                    T : Node(Neighbors => New 
Node_List'(List_List(Index)))
--                      with Address => A;
--                    pragma Warnings( On );
--                 begin
--                    null;
--                 end;
--              end loop;

          end return;
       End Make_Nodes;



       Tasks : aliased Task_Array with Import;

    begin
       Return Make_Nodes(Tasks);
    end Make_Network;

End Nodes;


----------------
--  TEST.ADB  --
----------------
With
Nodes;

procedure Test is
    use all type Nodes.Node_List;

    Children_1 : not null access Nodes.Node_List:= Nodes.Make_Network(3);
    Master   : Nodes.Node( Neighbors =>
                           Children_1
                           --Nodes.Null_List
                          );

begin
    null;
end Test;



^ permalink raw reply	[relevance 4%]

* Re: Termination of periodic tasks
  2014-06-17 20:00  4%                       ` Randy Brukardt
@ 2014-06-17 20:16  0%                         ` Jeffrey Carter
  0 siblings, 0 replies; 138+ results
From: Jeffrey Carter @ 2014-06-17 20:16 UTC (permalink / raw)


On 06/17/2014 01:00 PM, Randy Brukardt wrote:
>
> Actually, there is a way, at least if you want to ensure that the program
> cleans itself up properly. We invented it for Claw, and I put it into the
> ACATS so it's pretty certain that all compilers support it.
>
> The trick is to use Ada.Task_Identification to find out whether the
> environment task is trying to exit.
>
>      if not Is_Callable(Environment_Task) then
>          return; -- Exit this task.
>     end if;

That's good to know. I'll try to add it to my bag of tricks (though of course 
not needing any tricks is better).

-- 
Jeff Carter
"Whatever it is, I'm against it."
Horse Feathers
46


^ permalink raw reply	[relevance 0%]

* Re: Termination of periodic tasks
  @ 2014-06-17 20:00  4%                       ` Randy Brukardt
  2014-06-17 20:16  0%                         ` Jeffrey Carter
  0 siblings, 1 reply; 138+ results
From: Randy Brukardt @ 2014-06-17 20:00 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:k4bw956nq1hk.1fbqgpp5xu777$.dlg@40tude.net...
...
> Thus per design there is no way to make a non-trivial library-level task 
> to
> complete without means outside the library level. Either some OS-specific
> stuff or an explicit action/declaration in a nested scope is required.

Actually, there is a way, at least if you want to ensure that the program 
cleans itself up properly. We invented it for Claw, and I put it into the 
ACATS so it's pretty certain that all compilers support it.

The trick is to use Ada.Task_Identification to find out whether the 
environment task is trying to exit.

    if not Is_Callable(Environment_Task) then
        return; -- Exit this task.
   end if;

Is_Callable will only be False for the environment task if the main 
subprogram has exited and we're waiting for library-level tasks to complete. 
In that case, we want to kill off this task. (Note: Not all Ada 95 compilers 
did this at the time, some always returned true from it no matter what. But 
that would fail ACATS test CXC7004 in modern compilers, so it's unlikely 
that many get this wrong. One might want to look at that ACATS test for a 
complete example of the method.)

It can be clunky to get this into the task somewhere; it works best if the 
task is actively polling (as the message loop task in Claw is always doing).

Note: function Environment_Task was added to the package in Ada 2012. For 
earlier Ada, one needs to have the elaboration of the package containing the 
task squirrel away the task id:

   Environment_Task_Id : constant Task_Id := Current_Task;

                                               Randy.




^ permalink raw reply	[relevance 4%]

* Re: 4 beginner's questions on the PL Ada
  2013-08-12 19:57  0%                 ` Simon Wright
@ 2013-08-12 20:13  0%                   ` Anh Vo
  0 siblings, 0 replies; 138+ results
From: Anh Vo @ 2013-08-12 20:13 UTC (permalink / raw)


On Monday, August 12, 2013 12:57:49 PM UTC-7, Simon Wright wrote:
> Anh Vo <anhvofrcaus@gmail.com> writes:
>  
> > Here is how a task name is consistently implemented across different 
> > compilers.
>  
> ? I think not, because ...
>  
> > with Ada.Exceptions; 
> > with Ada.Text_Io;  
> > with Ada.Task_Attributes; 
> > with Ada.Task_Identification; 
> > with GNAT.Traceback.Symbolic;
> 
>        ^^^^                       <<<<< this! 

It is true that GNAT and its children packages are not portable. GNAT.Traceback.Symbolic package is actually not needed for task name testing purposes.

^ permalink raw reply	[relevance 0%]

* Re: 4 beginner's questions on the PL Ada
  2013-08-12 17:39  6%               ` Anh Vo
@ 2013-08-12 19:57  0%                 ` Simon Wright
  2013-08-12 20:13  0%                   ` Anh Vo
  0 siblings, 1 reply; 138+ results
From: Simon Wright @ 2013-08-12 19:57 UTC (permalink / raw)


Anh Vo <anhvofrcaus@gmail.com> writes:

> Here is how a task name is consistently implemented across different
> compilers.

? I think not, because ...

> with Ada.Exceptions;
> with Ada.Text_Io; 
> with Ada.Task_Attributes;
> with Ada.Task_Identification;
> with GNAT.Traceback.Symbolic;
       ^^^^                       <<<<< this!
> use Ada;
>
> procedure Task_Name_Test is

^ permalink raw reply	[relevance 0%]

* Re: 4 beginner's questions on the PL Ada
  2013-08-09 22:00  0%       ` Jeffrey Carter
  @ 2013-08-12 19:47  5%         ` Randy Brukardt
  1 sibling, 0 replies; 138+ results
From: Randy Brukardt @ 2013-08-12 19:47 UTC (permalink / raw)


"Jeffrey Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:ku3opa$svn$3@dont-email.me...
> On 08/09/2013 02:38 PM, Emanuel Berg wrote:
>>
>> Yes! This works great:
>>
>> with Ada.Task_Identification;
>> use  Ada.Task_Identification;
>>
>> Task_Name : constant String := Image(Current_Task);
>>
>> It produces output like
>>
>> add_one_081838Dt
>>
>> if the task is referred to as Add_One in the code.
>
> Not necessarily. First, this is only available in compilers that choose to 
> implement the optional Annex C, Systems Programming, so this is 
> non-portable.

That's formally true, but practically, I don't know of any Ada compilers 
that don't implement Ada.Task_Identification. An Ada compiler vendor needs 
something like it for debugging tasking programs, and it would be silly to 
create something different for that job.

> Second, the contents of the string returned by Image are implementation 
> defined. One particular compiler uses the task name as part of the 
> returned value, but others might not, so adding another layer of 
> non-portability.

Right. Janus/Ada uses "@nnnn", where "nnnn" is a task number (they're all 
assigned integers by our task supervisor). The task supervisor doesn't know 
anything about the names used in the program (its much lower level than 
that).

But the *real* problem is having a unique identification for each task 
without having to worry about the task type. There might an additional level 
of work to figure out which task object is associated with which identifier 
string, but that's easily handled by printing out the id for each task when 
it starts.

                                Randy.


^ permalink raw reply	[relevance 5%]

* Re: 4 beginner's questions on the PL Ada
    2013-08-10  6:16  5%               ` Simon Wright
@ 2013-08-12 17:39  6%               ` Anh Vo
  2013-08-12 19:57  0%                 ` Simon Wright
  1 sibling, 1 reply; 138+ results
From: Anh Vo @ 2013-08-12 17:39 UTC (permalink / raw)


On Friday, August 9, 2013 6:24:13 PM UTC-7, Emanuel Berg wrote:
> Anh Vo <anhvofrcaus@gmail.com> writes:
>  
> You guys should do a field trip to gnu.emacs.help - there, we just 
> post code all days! It is much better. Code speaks louder than 
> words. It is very difficult to follow all this discussion on 
> memory allocation etc., but the few times you posted code there 
> wasn't a letter I didn't understand immediately.
>  
> And isn't that the same way with you? If you were to explain the C 
> for loop to another programmer, would you not just write
>  
> for (i = 0; i < STOP; i++) { printf("Pretty clear, huh?\n"); }
>  
> But I don't doubt your Ada knowledge, or you helpful attitude.

Hmmmm... These have nothing to do with how a task name implemented with respect to portability.
 
>> You can give/assign a name to a task the way you like by using
>> predefined package Ada.Task_Attributes. In this case you most
>> likely instantiate it with String subtype. Therefore, it is will
>> be completely portable.
>  
> And (drumroll...) how would that look?
 
Here is how a task name is consistently implemented across different compilers. By the way, this is a complete running program.

with Ada.Exceptions;
with Ada.Text_Io; 
with Ada.Task_Attributes;
with Ada.Task_Identification;
with GNAT.Traceback.Symbolic;
use Ada;

procedure Task_Name_Test is
   use Text_Io;
   
   type Name is access String;
   Default_Name : constant Name := new String'("Generic task name");
   
   Package Task_Manager is new Task_Attributes (Name, Default_Name);
   
   task Gentleman is
      entry Hello;
      entry Goodbye;
   end Gentleman;
   
   task body Gentleman is
   begin
      accept Hello;
      Put_Line ("My name is " & 
                   Task_Manager.Value (Task_Identification.Current_Task).all &
                  ". It's my pleasure to meeting you");
      accept Goodbye;
      Put_Line ("Hopefully, we will meet again in the future.");
   end Gentleman;

   Gentleman_Name : Name := new String'("Gentleman");
      
begin
   Put_Line ("Task_Name_Test starts");

   Task_Manager.Set_Value (Val => Gentleman_Name, T => Gentleman'Identity);
   
   Gentleman.Hello;
   Gentleman.Goodbye;

   Put_Line ("Task_Name_Test starts");
   
exception
   when Err : others =>
      Put_Line (Exceptions.Exception_Name(Err) & " was raised");
      Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback(Err));
end Task_Name_Test;


Once again, it is about task name. If it is not, it should not belong here.

Anh Vo.

^ permalink raw reply	[relevance 6%]

* Re: 4 beginner's questions on the PL Ada
  @ 2013-08-10  6:16  5%               ` Simon Wright
  2013-08-12 17:39  6%               ` Anh Vo
  1 sibling, 0 replies; 138+ results
From: Simon Wright @ 2013-08-10  6:16 UTC (permalink / raw)


Emanuel Berg <embe8573@student.uu.se> writes:

> Anh Vo <anhvofrcaus@gmail.com> writes:
>
>> You can give/assign a name to a task the way you like by using
>> predefined package Ada.Task_Attributes. In this case you most
>> likely instantiate it with String subtype. Therefore, it is will
>> be completely portable.
>
> And (drumroll...) how would that look?

Well, it turns out to be more complicated than Ahn Vo said, because
Ada.Task_Attributes[1] has to be instantiated with a definite type (it
begins "type Attribute is private;") and String is indefinite.

So it might look like

with Ada.Strings.Bounded;
with Ada.Task_Attributes;
with Ada.Task_Identification;
with Ada.Text_IO; use Ada.Text_IO;
procedure Task_Naming is
   package Task_Name_Strings
   is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => 64);
   package Task_Names
   is new Ada.Task_Attributes
     (Attribute => Task_Name_Strings.Bounded_String,
      Initial_Value => Task_Name_Strings.Null_Bounded_String);
   task Tsk is end Tsk;
   task body Tsk is
   begin
      delay 5.0;
   end Tsk;
begin
   Task_Names.Set_Value (T => Tsk'Identity,
                         Val => Task_Name_Strings.To_Bounded_String ("foo"));
   --  later ...
   Put_Line
     ("id is "
        & Task_Name_Strings.To_String (Task_Names.Value (Tsk'Identity)));
end Task_Naming;

Alternatively, you could say

   subtype Task_Name_String is String (1 .. 16);
   package Task_Names
   is new Ada.Task_Attributes
     (Attribute => Task_Name_String,
      Initial_Value => (others => ' '));

but then you'd have to say

   Task_Names.Set_Value (T => Tsk'Identity,
                         Val => ('f', 'o', 'o', others => ' '));

> You guys should do a field trip to gnu.emacs.help - there, we just
> post code all days! It is much better. Code speaks louder than
> words. It is very difficult to follow all this discussion on
> memory allocation etc., but the few times you posted code there
> wasn't a letter I didn't understand immediately.

We don't like to post code that doesn't work, and producing a working
example takes time. Also, we have an excellent on-line reference manual,
though it takes a special kind of person to want to read it at bed-time!

[1] http://www.adaic.org/resources/add_content/standards/12rm/html/RM-C-7-2.html


^ permalink raw reply	[relevance 5%]

* Re: 4 beginner's questions on the PL Ada
  2013-08-09 21:38  7%     ` Emanuel Berg
@ 2013-08-09 22:00  0%       ` Jeffrey Carter
    2013-08-12 19:47  5%         ` Randy Brukardt
  0 siblings, 2 replies; 138+ results
From: Jeffrey Carter @ 2013-08-09 22:00 UTC (permalink / raw)


On 08/09/2013 02:38 PM, Emanuel Berg wrote:
>
> Yes! This works great:
>
> with Ada.Task_Identification;
> use  Ada.Task_Identification;
>
> Task_Name : constant String := Image(Current_Task);
>
> It produces output like
>
> add_one_081838Dt
>
> if the task is referred to as Add_One in the code.

Not necessarily. First, this is only available in compilers that choose to 
implement the optional Annex C, Systems Programming, so this is non-portable. 
Second, the contents of the string returned by Image are implementation defined. 
One particular compiler uses the task name as part of the returned value, but 
others might not, so adding another layer of non-portability.

This may not be a concern for your present needs, though unnecessary 
non-portability usually bites you sooner or later in real projects. An advantage 
of the technique used in PragmARC.Reflection is that it is part of the core 
language, and so implemented by all compilers, and the resulting string is 
defined by the language, and so is the same for all compilers.

-- 
Jeff Carter
"Well, a gala day is enough for me. I don't think
I can handle any more."
Duck Soup
93

^ permalink raw reply	[relevance 0%]

* Re: 4 beginner's questions on the PL Ada
  @ 2013-08-09 21:38  7%     ` Emanuel Berg
  2013-08-09 22:00  0%       ` Jeffrey Carter
  0 siblings, 1 reply; 138+ results
From: Emanuel Berg @ 2013-08-09 21:38 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> This is true, but Ada has a better solution for the original
> problem -- use the task identifier (which can be displayed, it
> has an Image function).  Every task has a task id. See
> http://www.ada-auth.org/standards/12rm/html/RM-C-7-1.html.

Yes! This works great:

with Ada.Task_Identification;
use  Ada.Task_Identification;

Task_Name : constant String := Image(Current_Task);

It produces output like

add_one_081838Dt

if the task is referred to as Add_One in the code.

The 8-char code that follows doesn't look like anything I
recognize. Is it a random string ID, or is is generated out of
anything sensible? If it always is 8 chars (and an underscore), I
guess I could simply trim the strings.

-- 
Emanuel Berg - programmer (hire me! CV below)
computer projects: http://user.it.uu.se/~embe8573
internet activity: http://home.student.uu.se/embe8573


^ permalink raw reply	[relevance 7%]

* Re: Task with access to itself?
  2012-12-06  9:38  6% ` Egil Høvik
@ 2012-12-06 19:53  0%   ` Adam Beneschan
  0 siblings, 0 replies; 138+ results
From: Adam Beneschan @ 2012-12-06 19:53 UTC (permalink / raw)


On Thursday, December 6, 2012 1:38:41 AM UTC-8, Egil Høvik wrote:
> On Wednesday, December 5, 2012 2:53:53 PM UTC+1, Jacob Sparre Andersen wrote:

> Having the tasks grabbing jobs from a protected objects is probably a better idea, but this seems to work on GNAT Pro 7.0.2:
> 
> package foo is
> 
>    task type Handler is
>       entry Do_Stuff;
>    end Handler;
> 
>    type Reference is access all Handler;  
> 
>    procedure Register_As_Available(P : access Handler);
>    function Get_Next return Reference;
> 
> end foo;
> 
> 
> with Ada.Task_Identification;
> with Ada.Text_IO;
> 
> package body foo is
> 
>    task body Handler is
>    begin
>       Register_As_Available(Handler'Access); -- Handler here refers to the current instance of the type
>       loop
>          select 
>             accept Do_Stuff do
>                Ada.Text_IO.Put_Line("foo" & Ada.Task_Identification.Image(Handler'Identity));
>             end Do_Stuff;
>          or 
>             terminate;
>          end select;
>       end loop;
>    end Handler;
> 
>    List : array(1..2) of Reference;
>    Last : Natural := 0;
>    
>    procedure Register_As_Available(P : access Handler)
>    is
>    begin
>       Last := Last + 1;
>       List(Last) := Reference(P);
>    end Register_As_Available;
> 
>    Next : Natural := 0;
>    function Get_Next return Reference is
>    begin
>       Next := Next + 1;
>       if Next > List'Last then
>          Next := 1;
>       end if;
>       return List(Next);
>    end Get_Next;
> end foo;
> 
> 
> with foo;
> 
> procedure bar is
> 
>    t1 : foo.handler;
>    t2 : foo.handler;
> 
>    Ref : foo.Reference;
> begin
> 
>    for i in 1..10 loop
>       Ref := foo.Get_Next;
>       Ref.Do_Stuff;
>    end loop;
> 
> end bar;
> 
> 
> (If you're not careful, you may end up with a bunch of accessibility issues, though)

This program *does* have accessibility issues.  It works only because GNAT is known to have problems catching accessibility-level violations.  The accessibility of Handler is deeper than that of the Reference type; therefore, when this is executed:

  Register_As_Available(Handler'Access)

a Constraint_Error should be raised when Register_As_Available converts its parameter to Reference.  To see this, suppose you have a nested procedure that declares its own Nested_Task : foo.Handler.  Nested_Task would put an access to itself in the List array.  Then the nested procedure exits and Nested_Task is no more, but an access to it still lives in the List.  In Ada, if you don't use 'Unchecked_Access or other constructs that let you get around the rules, you can't have an access object that outlives the thing it's pointing to (except when there's a hole in the language; but there isn't, at least in this case).  So that should be enough to convince anyone that this program shouldn't work.

Changing the above to

  Register_As_Available(Handler'Unchecked_Access)

should make things work, although then the programmer has to be careful to write things in a way so that dangling references aren't used.  Also, the above program has some other problems: (1) both tasks could execute Register_As_Available at the same time, which could really screw things up if the both increment Last before either of them stores into the array; and (2) the main subprogram's code could execute before either task has a chance to call Register_As_Available, meaning that Ref could be null and the program could bomb that way.  If your program "seems" to work, it's because you got lucky (in addition to the compiler problem that is causing an accessibility check to be missed).

                         -- Adam




^ permalink raw reply	[relevance 0%]

* Re: Task with access to itself?
  @ 2012-12-06  9:38  6% ` Egil Høvik
  2012-12-06 19:53  0%   ` Adam Beneschan
  0 siblings, 1 reply; 138+ results
From: Egil Høvik @ 2012-12-06  9:38 UTC (permalink / raw)


On Wednesday, December 5, 2012 2:53:53 PM UTC+1, Jacob Sparre Andersen wrote:
> I would like to maintain a collection of tasks, where the tasks
> 
> themselves can register their availability.
> 
> 
> 
> My immediate thought was to let the tasks know their own address
> 
> ('Access), such that they can simply pass that to the collection of
> 
> available tasks, when they are ready.  But I haven't found a nice way to
> 
> implement that pattern, so may be I should do it a different way.
> 

Having the tasks grabbing jobs from a protected objects is probably a better idea, but this seems to work on GNAT Pro 7.0.2:

package foo is

   task type Handler is
      entry Do_Stuff;
   end Handler;
   
   type Reference is access all Handler;
   
   procedure Register_As_Available(P : access Handler);
   function Get_Next return Reference;

end foo;


with Ada.Task_Identification;
with Ada.Text_IO;

package body foo is

   task body Handler is
   begin
      Register_As_Available(Handler'Access); -- Handler here refers to the current instance of the type

      loop
         select 
            accept Do_Stuff do
               Ada.Text_IO.Put_Line("foo" & Ada.Task_Identification.Image(Handler'Identity));
            end Do_Stuff;
         or 
            terminate;
         end select;
      end loop;
   end Handler;


   List : array(1..2) of Reference;
   Last : Natural := 0;
   
   procedure Register_As_Available(P : access Handler)
   is
   begin
      Last := Last + 1;
      List(Last) := Reference(P);
   end Register_As_Available;


   Next : Natural := 0;
   function Get_Next return Reference is
   begin
      Next := Next + 1;
      if Next > List'Last then
         Next := 1;
      end if;
      return List(Next);
   end Get_Next;
end foo;


with foo;

procedure bar is

   t1 : foo.handler;
   t2 : foo.handler;

   Ref : foo.Reference;
begin

   for i in 1..10 loop
      Ref := foo.Get_Next;
      Ref.Do_Stuff;
   end loop;

end bar;


(If you're not careful, you may end up with a bunch of accessibility issues, though)

-- 
~egilhh



^ permalink raw reply	[relevance 6%]

* Re: Tasking troubles, unexpected termination.
  @ 2012-10-31  2:17  6%     ` Shark8
  0 siblings, 0 replies; 138+ results
From: Shark8 @ 2012-10-31  2:17 UTC (permalink / raw)


Here's the updated code:

---- Scheduling.adb ------------------------------------------
with
Ada.Text_IO,
Ada.Calendar,
Ada.Containers.Indefinite_Vectors,
Ada.Task_Termination,
Ada.Task_Identification,
Task_Debugging;

Procedure Scheduling is

    -- Introduce shorthand so convert Strings to access strings.
    Function "+" (Item : String) Return Not Null Access String is
      ( New String'(Item) );
    
    -- Forward declare the Notification type; indicate it has discriminants.
    Type Notification(<>);
    
    -- Declare Handle for Notifications.
    Type Notification_Handle is Not Null Access Notification;
    
    Type Notification(	Message	: Not Null Access String;
			Expiry	: Not Null Access Ada.Calendar.Time
		     ) is null record;
    
    -- Declare the Timing-task.
    Task Type Timing ( Resolution : Not Null Access Duration ) is
	Entry Add( Event : Notification_Handle );
    end Timing;

    
    -- Implementation for the timing-task.
    Task body Timing is

	-- Package for showing Duration.
	Package Decimal_Display is new Ada.Text_IO.Fixed_IO( Duration );
	
	-- Internal package, defining Vectors holding notification handles.
	Package Notification_Vector is New Ada.Containers.Indefinite_Vectors
	  ( Index_Type => Positive, Element_Type => Notification_Handle );
	Use Notification_Vector;
	
	-- Handle expired messages.
	Procedure Handle_Expiration( List : in out Vector ) is
	    Use Ada.Calendar, Ada.Text_IO;
	    Length : Positive:= Positive(List.Length);
	    Now    : Time:= Clock;

	    -- We flag everything to be deleted, as tampering with the cursor is
	    -- not good.
	    Type Deletion_Flags is Array(1..Length) of Boolean;
	    Deletion_Marks : Deletion_Flags:= (Others => False);
	    
	    
	    procedure Execute(Position : Cursor) is
		Item	: Constant Notification_Handle:= Element(position);
		Index	: Constant Positive:= Positive( To_Index(position) );
	    begin
		Deletion_Marks(Index):= Now >= Item.Expiry.All;
		--
		Ada.Text_IO.Put( ASCII.HT & "Exipration: " );
		Decimal_Display.Put( Item.Expiry.All - Now, Fore => 2, Aft => 3 );
		Ada.Text_IO.New_Line;
	    end Execute;

	begin
	    -- Iterate through the vector's elements; old-style iterator.
	    List.Reverse_Iterate( Process => Execute'Access );

	    -- Delete flagged elements; iteration bckwards to preserve indicies.
	    For Index in reverse Deletion_Marks'Range loop
		if Deletion_Marks(Index) then
		    
		    Put_Line( "Message: " & List(Index).Message.All);
		    List.Delete( Index );
		end if;
	    end loop;
	    
	    -- Render a report on the new length, if it was altered.
	    declare
		Post_op_length : Natural:= Natural(List.Length);
	    begin
		if Length /= post_op_length then
		    Put_Line( "Deleted items; New Length:" &  post_op_length'Img);
		end if;
	    end;
	end Handle_Expiration;

	-- Declare a Vector to hold all the nofifications.
	Notification_List : Vector:= Empty_Vector;
	
	Use Ada.Task_Termination, Task_Debugging, Ada.Containers, Ada.Calendar;
	
	-- Mark the start-time.
	Start : Time:= Clock;
	
--	Function Elapsed Return String is
--	  ( Duration'Image(Clock - Start)(1..7) );
	Function Elapsed Return Duration is
	  ( Clock - Start );

    begin
	-- Set our debugging-handler for this task.
	Ada.Task_Termination.Set_Specific_Handler(
		T       => Ada.Task_Identification.Current_Task,
		Handler => Debug.Termination'Access );

	-- When there are no items in our internal vector, then we need can only
	-- accept Add or terminate the task.
	-- When we add an item, then we can either add another item or when the
	-- time expires iterate the vector and handling Notifications as needed.
	loop
	    select 
		accept Add( Event : Notification_Handle ) do
		    Notification_List.Append( Event );
		end add;
		while not Notification_List.Is_Empty loop
		    Ada.Text_IO.Put( "Elapsed:" );
		    Decimal_Display.Put( Elapsed, Fore => 2, Aft => 3 );
		    Ada.Text_IO.New_Line;
		    Handle_Expiration( List => Notification_List );
		    select
			accept Add( Event : Notification_Handle ) do
			    Notification_List.Append( Event );
			    Ada.Text_IO.Put_Line( "New Length: " & Notification_List.Length'Img );
			    Ada.Text_IO.Put( ASCII.HT & "Exipration: " );
			    Decimal_Display.Put( Event.Expiry.All - Clock, Fore => 2, Aft => 3 );
			    Ada.Text_IO.New_Line;
			end add;
		    or
			delay Timing.Resolution.All;
		    end select;
		end loop;
		Ada.Text_IO.Put_Line( "EMPTY." );
	    or
		terminate;
	    end select;
	end loop;
    end Timing;
    
    
      
    K : Timing( Resolution => New Duration'(2.0) ); -- 2 second resolution.
    Now : Ada.Calendar.Time:= Ada.Calendar.Clock;
begin
    For Index in 1..10 loop
	declare
	    Use Ada.Calendar;
	    Item : Notification(
			 Message => + ("DD"&Positive'Image(Index)),
			 -- Expire at Now and 3*Index seconds.
			 Expiry  => New Time'( Now + Duration(Index) )
			);
	begin
	    K.Add( Event => New Notification'(Item) );
	end;
    end loop;
    
    -- Add an element in the past... it should immediately be operated on.
    K.Add( Event => New Notification'(
	Message => + ("Last."),
	Expiry  => New Ada.Calendar.Time'( Now )
	)
    );

end Scheduling;

---- Task_Debugging.ads ----------------------------------------------
-- The following are not strictly nessacary, but used in this example for 
-- debugging purposes.
With
System.Address_To_Access_Conversions,
Ada.Unchecked_Conversion,
Ada.Exceptions.Traceback,
Ada.Task_Identification,
Ada.Task_Termination;

Package Task_Debugging is
    Pragma Elaborate_Body;
    
    Protected Type Debugging is
	-- Termination debugging function.
	procedure Termination(
				 Cause : Ada.Task_Termination.Cause_Of_Termination;
				 T     : Ada.Task_Identification.Task_Id;
				 X     : Ada.Exceptions.Exception_Occurrence);

    End Debugging;
    
    -- Debug, an instance of our debugging object.
    Debug : Debugging;
    
End Task_Debugging;

---- Task_Debugging.adb ----------------------------------------------
With Ada.Text_IO;

Package Body Task_Debugging is

    Protected body Debugging is
	-- Termination debugging function.
	procedure Termination(
		       Cause : Ada.Task_Termination.Cause_Of_Termination;
		       T     : Ada.Task_Identification.Task_Id;
		       X     : Ada.Exceptions.Exception_Occurrence) is
	    Use Ada.Text_IO, Ada.Task_Termination, Ada.Exceptions;
	begin
	    Put_Line("Termination: "& Cause'Img);
	    case Cause is
	    When Normal | Abnormal => Null;
	    When Unhandled_Exception =>
		Put_Line( Exception_Name(X)&": "&Exception_Message(X) );
	    end case;
	end Termination;	
    end Debugging;

End Task_Debugging;
---------------------------------------------------------------------------

I've fixed the original problems (first the "tampering", and second a constraint_error) but there's still something strange going on. The discriminants for notifications seem to be being ignored (or rather the latest one being used).

Here's the output:
C:\Programming\Projects\Scheduler>scheduling.exe
Elapsed: 0.000
        Exipration:  0.984
New Length:  2
        Exipration:  1.983
Elapsed: 0.002
        Exipration:  1.982
        Exipration:  1.982
New Length:  3
        Exipration:  2.981
Elapsed: 0.004
        Exipration:  2.980
        Exipration:  2.980
        Exipration:  2.980
[...]
Message: Last.
Deleted items; New Length: 10
Elapsed: 2.047
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
Elapsed: 4.051
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
Elapsed: 6.061
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
Elapsed: 8.086
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
Elapsed:10.106
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
Message: DD 10
Message: DD 9
Message: DD 8
Message: DD 7
Message: DD 6
Message: DD 5
Message: DD 4
Message: DD 3
Message: DD 2
Message: DD 1
Deleted items; New Length: 0
EMPTY.
Termination: NORMAL

As you can see, instead of each element being different they're all tagged as having the same expiration.



^ permalink raw reply	[relevance 6%]

* Re: In case you need to remember...
  @ 2012-04-06 20:09  5% ` anon
  0 siblings, 0 replies; 138+ results
From: anon @ 2012-04-06 20:09 UTC (permalink / raw)


The truth is Ada is Concurrent which means Ada uses one and only one 
thread for all tasks. 


And on a multiple core system the thread may swap between processors 
during thread scheduling but the Ada code is only one thread under 
the OS.  The RM 2012 does have some multiple processors packages but 
they are not enough routines to build a fully functioning true multiple 
thread for each task.

Now, GNAT using OS_Lib packages does have some OS links that can request 
new thread but these routines are not listed in the RM. Also, GNAT can 
use the Spawn or folk call but it is not recommended due to fact of 
blocking and signal/locks which are unpredictable. (see Note in 
System.OS_Lib.ads) Now in GNAT 2012 release in a month or two this 
may be different.


And example to demonstrated Ada based thread:


with Ada.Text_IO ;
with Ada.Integer_Text_IO ;
with Ada.Task_Identification ;

--  If Ada was multiple tasking using threads then the main procedure 
--  would end and the Task would run in the background similar to 
--  starting a server on any OS. This is, the main procedure would 
--  be use to active the task and then exit. But due to the fact that 
--  Ada is still concurrent the main procedure will finish executing 
--  but will be blocked in "Finalization".  Some resources may be 
--  release but not all. In other words the main procedure will be 
--  blocked and some resources held until the "Task" ends it run or 
--  the operator kills the executing thread which kills both the 
--  main procedure and the task and release all resources.
--
--  Also if you use a thread monitor you will see only one thread
--  was created and is running. And if Ada used multiple threads then 
--  in this program there would be one thread for the main procedure
--  "Test" and a second thread for the task "Task_1". But there is 
--  only one thread indicating that Ada is still concurrent.
--

procedure Test is

  use Ada ;
  use Text_IO ;
  use Integer_Text_IO ;


  task type CPU_TASK is
    entry Run_cpu ;  
  end CPU_TASK ;

  PC : Integer := 55 ;
  Run_Flag : Boolean := False ;

  --  Task is activated once the program begins
  --  If Ada was multiple thread then this task would activated once 
  --  the OS created a new thread entry in the job thread scheduler
  Task_1 : CPU_TASK ;  


  task body CPU_TASK is

    begin -- CPU_TASK 

      Put_Line ( "Processor is Uninitialized" ) ;
      loop
        select
          accept Run_cpu ;      

              -- Run until process is either reset, halted.  

              Put_Line ( "Task is in RUN Mode" ) ;
              Run_Flag := True ;
              loop
                Put_Line ( "Executed Instruction" & PC'img ) ;
                PC := PC + 1 ;
                Delay  0.0 ; -- tells Ada RTL to swap task to main
              end loop ;
              exit ;
        or
         terminate ;
        end select ;
      end loop ;
    end CPU_TASK ;

begin

  Put_Line ( "Reset Processor status" ) ;
  PC := 0 ;
  Delay 0.1 ;
  Put_Line ( "Set processor status to RUN Task" ) ;
  Task_1.Run_cpu ;

  Delay  0.5 ;
  Put_Line ( "Trying to Single Step Task" ) ;


--  Delay  0.1 ;
--  Put_Line ( "Stopping the Task" ) ;
--  Ada.Task_Identification.Abort_Task ( Task_1 ' Identity ) ;

    Put_Line ( "Finished Excution of program" ) ;
end test ;

In <1984433.261.1333725652284.JavaMail.geo-discussion-forums@vbbfr18>, mockturtle <framefritti@gmail.com> writes:
>....how nice is having tasks built-in in your preferred language, I just lan=
>ded over this text (Threads =97 Threat or Menace?)
>
>   http://www.faqs.org/docs/artu/ch07s03.html#id2923889
>
>Just an excerpt:=20
>
>  "Threads are a fertile source of bugs because they can too easily know to=
>o much about each others' internal states. There is no automatic encapsulat=
>ion, as there would be between processes with separate address spaces that =
>must do explicit IPC to communicate. Thus, threaded programs suffer from no=
>t just ordinary contention problems, but from entire new categories of timi=
>ng-dependent bugs that are excruciatingly difficult to even reproduce, let =
>alone fix."
>
>Hmm... Why do I have this warm and cozy feeling? :-)=20
>
>BTW, a curiosity: does the Linux version of GNAT use threads to implement t=
>asks?=20
>
>Riccardo




^ permalink raw reply	[relevance 5%]

* Re: task abortion
  2012-01-26 16:47  0%     ` Anh Vo
@ 2012-01-31 13:25  0%       ` tonyg
  0 siblings, 0 replies; 138+ results
From: tonyg @ 2012-01-31 13:25 UTC (permalink / raw)


On Jan 26, 4:47 pm, Anh Vo <anhvofrc...@gmail.com> wrote:
> On Jan 26, 1:12 am, tonyg <tonytheg...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > On Jan 25, 10:43 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
>
> > > On Wed, 25 Jan 2012 02:11:55 -0800 (PST), tonyg wrote:
> > > > I want to be able to abort a task if it has not responded for a while,
> > > > and then start a new one in its stead.
>
> > > > I have a pointer going to the concerned task.
>
> > > > Each task has a 'stop accept' in its rendezvous which forces it out of
> > > > its loop so that it ends, but if the task has frozen for some reason
> > > > then I want to abort.
>
> > > What are you going to achieve by that?
>
> > > Consider the scenarios:
>
> > > 1. The task crashed, it is already terminated then.
>
> > > 2. The task is looping somewhere:
>
> > > 2.a. What about the resources it owns? Local resources are usually freed
> > > when the task is aborted. But if you have some globally allocated memory,
> > > semaphores etc, they all get lost unless freed by some local controlled
> > > objects, "holders" releasing the resources upon finalization, as they leave
> > > the scope upon task abort. Now:
>
> > > 2.b. What if the task is frozen in an abort-deferred thing? Finalization is
> > > such a thing. Abort-deferred stuff cannot be aborted. Note that system I/O
> > > is most likely non-abortable. I.e. you would not be able to abort
> > > Ada.Text_IO.Get_Line or recv on a socket etc anyway.
>
> > > All in one, aborting tasks doing complex stuff is not likely to work in a
> > > reasonable way. Aborting tasks doing simple stuff is not needed, such tasks
> > > impose no problems anyway. Ergo, it is not likely you would need to abort
> > > any task.
>
> > > If you decided for aborting, you would have to redesign almost everything
> > > and in an extremely careful way in order to make tasks logically abortable.
> > > That means to make continuation possible and meaningful after aborting some
> > > tasks. Now a guess: making the tasks right and thus preventing a need
> > > aborting them, would probably be far less efforts...
>
> > > --
> > > Regards,
> > > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de
>
> > Since I wrote my message I have discovered the package
> > Ada.Task_Identification. I totally agree with your argument on not
> > having them fail in the first place. My strategy should be then not to
> > abort :), I'm going to use that package just to monitor my tasks and
> > see if any freeze for some IO reason. Thanks for the advice.
>
> Just in case your task disappear which I do not expect it will, you
> can use package Ada.Task_Termination to query the reason (Normal,
> Abnormal, Unhandled_Exception) it dies.
>
> Anh Vo

Thabjs Anh for that



^ permalink raw reply	[relevance 0%]

* Re: task abortion
  2012-01-26  9:12  5%   ` tonyg
@ 2012-01-26 16:47  0%     ` Anh Vo
  2012-01-31 13:25  0%       ` tonyg
  0 siblings, 1 reply; 138+ results
From: Anh Vo @ 2012-01-26 16:47 UTC (permalink / raw)


On Jan 26, 1:12 am, tonyg <tonytheg...@gmail.com> wrote:
> On Jan 25, 10:43 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>
>
>
>
>
>
>
>
> > On Wed, 25 Jan 2012 02:11:55 -0800 (PST), tonyg wrote:
> > > I want to be able to abort a task if it has not responded for a while,
> > > and then start a new one in its stead.
>
> > > I have a pointer going to the concerned task.
>
> > > Each task has a 'stop accept' in its rendezvous which forces it out of
> > > its loop so that it ends, but if the task has frozen for some reason
> > > then I want to abort.
>
> > What are you going to achieve by that?
>
> > Consider the scenarios:
>
> > 1. The task crashed, it is already terminated then.
>
> > 2. The task is looping somewhere:
>
> > 2.a. What about the resources it owns? Local resources are usually freed
> > when the task is aborted. But if you have some globally allocated memory,
> > semaphores etc, they all get lost unless freed by some local controlled
> > objects, "holders" releasing the resources upon finalization, as they leave
> > the scope upon task abort. Now:
>
> > 2.b. What if the task is frozen in an abort-deferred thing? Finalization is
> > such a thing. Abort-deferred stuff cannot be aborted. Note that system I/O
> > is most likely non-abortable. I.e. you would not be able to abort
> > Ada.Text_IO.Get_Line or recv on a socket etc anyway.
>
> > All in one, aborting tasks doing complex stuff is not likely to work in a
> > reasonable way. Aborting tasks doing simple stuff is not needed, such tasks
> > impose no problems anyway. Ergo, it is not likely you would need to abort
> > any task.
>
> > If you decided for aborting, you would have to redesign almost everything
> > and in an extremely careful way in order to make tasks logically abortable.
> > That means to make continuation possible and meaningful after aborting some
> > tasks. Now a guess: making the tasks right and thus preventing a need
> > aborting them, would probably be far less efforts...
>
> > --
> > Regards,
> > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de
>
> Since I wrote my message I have discovered the package
> Ada.Task_Identification. I totally agree with your argument on not
> having them fail in the first place. My strategy should be then not to
> abort :), I'm going to use that package just to monitor my tasks and
> see if any freeze for some IO reason. Thanks for the advice.

Just in case your task disappear which I do not expect it will, you
can use package Ada.Task_Termination to query the reason (Normal,
Abnormal, Unhandled_Exception) it dies.

Anh Vo



^ permalink raw reply	[relevance 0%]

* Re: task abortion
  @ 2012-01-26  9:12  5%   ` tonyg
  2012-01-26 16:47  0%     ` Anh Vo
  0 siblings, 1 reply; 138+ results
From: tonyg @ 2012-01-26  9:12 UTC (permalink / raw)


On Jan 25, 10:43 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 25 Jan 2012 02:11:55 -0800 (PST), tonyg wrote:
> > I want to be able to abort a task if it has not responded for a while,
> > and then start a new one in its stead.
>
> > I have a pointer going to the concerned task.
>
> > Each task has a 'stop accept' in its rendezvous which forces it out of
> > its loop so that it ends, but if the task has frozen for some reason
> > then I want to abort.
>
> What are you going to achieve by that?
>
> Consider the scenarios:
>
> 1. The task crashed, it is already terminated then.
>
> 2. The task is looping somewhere:
>
> 2.a. What about the resources it owns? Local resources are usually freed
> when the task is aborted. But if you have some globally allocated memory,
> semaphores etc, they all get lost unless freed by some local controlled
> objects, "holders" releasing the resources upon finalization, as they leave
> the scope upon task abort. Now:
>
> 2.b. What if the task is frozen in an abort-deferred thing? Finalization is
> such a thing. Abort-deferred stuff cannot be aborted. Note that system I/O
> is most likely non-abortable. I.e. you would not be able to abort
> Ada.Text_IO.Get_Line or recv on a socket etc anyway.
>
> All in one, aborting tasks doing complex stuff is not likely to work in a
> reasonable way. Aborting tasks doing simple stuff is not needed, such tasks
> impose no problems anyway. Ergo, it is not likely you would need to abort
> any task.
>
> If you decided for aborting, you would have to redesign almost everything
> and in an extremely careful way in order to make tasks logically abortable.
> That means to make continuation possible and meaningful after aborting some
> tasks. Now a guess: making the tasks right and thus preventing a need
> aborting them, would probably be far less efforts...
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Since I wrote my message I have discovered the package
Ada.Task_Identification. I totally agree with your argument on not
having them fail in the first place. My strategy should be then not to
abort :), I'm going to use that package just to monitor my tasks and
see if any freeze for some IO reason. Thanks for the advice.




^ permalink raw reply	[relevance 5%]

* Re: "C - like: THIS" pointer to a task type inside a task function
  @ 2012-01-23 22:17  7% ` tmoran
  0 siblings, 0 replies; 138+ results
From: tmoran @ 2012-01-23 22:17 UTC (permalink / raw)


> An entry can have in, out, in-out parameters like a subprogram call. You
> can pass parameters in and get the results out, just in one call.

  If the client task, after giving work to the server, needs to do things
other than wait for a result, then adding an "out" parameter won't work.

> It is considered bad design when two components know each other. Usually
> the software is designed in a way that component relationships are
> asymmetric, e.g. the callee knows nothing about the caller. Component knows
> nothing about the container, etc. The advantage of this approach is its
> robustness. You can have as many callers you need without changing the
> callee.

  True, but if the server really does need to call the client, it will
need to know the "name" of the client.  You can do this with
Ada.Task_Identification:

with Ada.Task_Identification;
procedure Testti is

  task type Clients is
    entry Get_Result(Result  : in     Character);
  end Clients;

  task Server is
    entry Get_Work(Work    : in     Character);
  end Server;

  task body Clients is
    Generated_Result: Character;
  begin
    for Jobs in 1 .. 5 loop -- we do want eventual termination of this demo!
      -- generate some work todo, then
      Server.Get_Work(Work => 'w');
      -- do other stuff, then ask for the results
      select
        accept Get_Result(Result  : in     Character) do
          Generated_Result := Result;
        end Get_Result;
        -- use Generated_Result
      or
        terminate; -- Server is dead!  Don't just hang around.  Die.
      end select;
    end loop;
  end Clients;

  Client_List: array (1 .. 10) of Clients;

  task body Server is
    use type Ada.Task_Identification.Task_Id;
    Todo    : Character;
    Result  : Character;
    Source  : Ada.Task_Identification.Task_Id;
  begin
    loop
      select
        accept Get_Work(Work    : in     Character) do
          Todo := Work;
          Source := Get_Work'Caller;
        end Get_Work;
      or
        terminate;
      end select;
      -- handle Todo, generating Result, then pass it back to Source client.
      for I in Client_List'range loop
        if Client_List(I)'Identity = Source then
          Client_List(I).Get_Result(Result);
          exit;
        end if;
        -- if a task other than one in Client_List gave us work, toss it.
      end loop;
    end loop;
  end Server;

begin
  null;  -- Client_List and Server tasks are working away...
end Testti;



^ permalink raw reply	[relevance 7%]

* Re: Class with task destructor
  @ 2011-12-01  0:35  4%           ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2011-12-01  0:35 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:ey516bovprzb$.1tjszfc528chj$.dlg@40tude.net...
> On Tue, 29 Nov 2011 18:21:51 -0800 (PST), Adam Beneschan wrote:
...
>> I don't know of a good way
>> around this (besides Ada.Task_Termination).
>
> I am using polling for T'Terminated after the rendezvous.

That's the Ada 83 solution, and there really isn't anything better in the 
language. Not sure if there even could be (I'm not a top-level expert on 
real-time issues, beyond what the Janus/Ada runtime does).

...
> Not a feature, rather a plain language design bug. Unchecked_Deallocation
> shall wait for the object's finalization. Finalization of a task evidently
> includes its termination. So Unchecked_Deallocation must block until
> termination before it frees anything.

The problem here is that finalization and task termination are different 
operations according to the language, and task termination generally has to 
be done first. This was done, I believe, so that any running task does not 
have to worry about having the objects it accesses finalized.

I usually agree that this is wrong, but actually it doesn't matter what 
choice is made -- any choice will be wrong a large part of the time. The 
current choice, for instance, makes it possible for finalize routines to 
access objects that have already been finalized (and allocate objects of 
access types that already have been finalized) - a finalize routine often 
needs to protect against this if it needs to access anything outside of the 
object being finalized.

We had a lot of trouble with this in Claw, particularly because we wanted to 
use a global finalizable object to tell the library tasks when to terminate. 
But that doesn't work in Ada, because tasks are awaited before any 
library-level finalization is done -- and thus the tasks never get their 
shutdown entries called. We eventually found a tricky way to use 
Ada.Task_Identification to determine when the main subprogram has exited, 
and used that to terminate the tasks. (And then we had to get all of the Ada 
95 compilers to implement it properly -- that took a couple of years and an 
ACATS test.)

Switching the order of task waiting and finalization would have worked in 
this case, but it wouldn't work in general as the library tasks would then 
be accessing global objects that have been finalized. Which seems worse than 
the original problem.

Point is that all of these things are interelated, and it isn't always 
possible to make all of them perfect. (Tucker Taft calls this "moving the 
bump under the carpet"; you can move it around to different locations, but 
you can't get rid of it without tearing out the carpet. That happens a lot 
more often in language design than most people think.)

                                           Randy.





^ permalink raw reply	[relevance 4%]

* Re: Class with task destructor
  @ 2011-11-23  2:44  4% ` Adam Beneschan
    1 sibling, 0 replies; 138+ results
From: Adam Beneschan @ 2011-11-23  2:44 UTC (permalink / raw)


Although I haven't looked into this too rigorously, I think the
problem (with the first implementation) is that neither "terminate"
alternative in the task is given a chance to work.  First of all, you
have "select accept Start; ... or terminate;" (the second "or
terminate, toward the end of Primary_Task).  Start is called right
away, so we go into that branch.  Then we go into Main_Loop, and you
have a select with three alternatives: accept Pause; accept Finish; or
an "else" that will get executed right away if nobody is calling Pause
and Finish.  Pause isn't called anywhere, and in your first
implementation Finish isn't called everywhere.  Thus, the select goes
right to the "else" branch, which does a Put and a delay, then you
loop back to do it again, and since Pause and Finish aren't still
being called, it goes to the Put and delay again, and it keeps going
round and round and round.  The inner "select" that has the terminate
alternative never gets executed since you have to accept Pause first,
and the outer "select" with the terminate alternative never gets
executed since you never get out of Main_Loop.  So the "terminate"
alternatives in your task never have any effect.

The language rules say that Unchecked_Deallocation doesn't force tasks
to terminate.  I believe he only way to terminate a task that doesn't
terminate on its own (either by leaving the task body, or by a
terminate alternative) is to use ABORT (or
Ada.Task_Identification.Abort_Task).  And I wouldn't do that if there
are other ways to get a task to terminate.

                        -- Adam




On Nov 22, 5:50 pm, "Rego, P." <pvr...@gmail.com> wrote:
> So now I have a class with a task inside and a Constructor, and I want to implement a destructor.
>
> --test_pkg.ads
> with Unchecked_Deallocation;
> package Test_Pkg is
>
>    type Test_Class is tagged;
>    type Test_Class_Ptr is access all Test_Class;
>
>    function Construct return Test_Class_Ptr;
>    procedure Destruct (T : access Test_Class);
>
>    task type Primary_Task (This : not null access Test_Class) is
>       entry Start;
>       entry Pause;
>       entry Release;
>       entry Finish;
>    end Primary_Task;
>
>    type Test_Class is tagged limited
>       record
>          Some_Info : Integer;
>          Primary   : Primary_Task (Test_Class'Access);
>       end record;
>
>    procedure Free is new Unchecked_Deallocation (Object => Test_Class,
>                                                  Name   => Test_Class_Ptr);
> end Test_Pkg;
>
> --test_pkg_main.adb
> with Test_Pkg; use Test_Pkg;
>
> procedure Test_Pkg_Main is
>    Obj_Ptr : Test_Class_Ptr;
> begin
>    Obj_Ptr := Construct;
>    delay 5.0;
>    Obj_Ptr.Destruct;
>
> end Test_Pkg_Main;
>
> --test_pkg.adb
> with Text_IO; use Text_IO;
> package body Test_Pkg_Rev661 is
>    task body Primary_Task is
>    begin
>       Outer_Loop : loop
>          select
>             accept Start;
>             Main_Loop : loop
>                select
>                   accept Pause;
>                   select
>                      accept Release;
>                   or
>                      accept Finish;
>                      exit Outer_Loop;
>                   or
>                      terminate;
>                   end select;
>                or
>                   accept Finish;
>                   exit Outer_Loop;
>                else
>                   Put ("^"&Integer'Image (This.Some_Info));
>                   delay 0.5;
>                end select;
>             end loop Main_Loop;
>          or
>             terminate;
>          end select;
>       end loop Outer_Loop;
>    end Primary_Task;
>
>    function Construct return Test_Class_Ptr is
>       T_Ptr : constant Test_Class_Ptr := new Test_Class;
>    begin
>       T_Ptr.Some_Info := 1;
>       T_Ptr.Primary.Start;
>       return T_Ptr;
>    end Construct;
>
>    procedure Destruct (T : access Test_Class) is
>    ...
>    end Destruct;
> end Test_Pkg_Rev661;
>
> --
> (1) So, the first implementation I tried was
>    procedure Destruct (T : access Test_Class) is
>       T_Ptr : Test_Class_Ptr := Test_Class_Ptr (T);
>    begin
>       Free (T_Ptr);
>    end Destruct;
>
> So I thought that if I unallocate the object, the task inside would be dead too, because the object would be its master. It looks that I'm wrong, because the execution led me to
>
> ^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 6295912^ 6295912^ (...)
> then the task is not dead after the object dies.
> So why is this implementation wrong?
>
> (2) The second one implementation I tried, which looks me that led me to a (happy) program termination was
>    procedure Destruct (T : access Test_Class) is
>       T_Ptr : Test_Class_Ptr := Test_Class_Ptr (T);
>    begin
>       T.Primary.Finish;
>       Free (T_Ptr);
>    end Destruct;
>
> and the execution leds me to
> ^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1^ 1 (and no more)
>
> I agree that in this case the task is dead, because of the forced termination. And so on the object itself. But is this implementation preferable over the first one?
>
> Thank you again.




^ permalink raw reply	[relevance 4%]

* An Example for Ada.Execution_Time
@ 2010-12-27 18:26  5% anon
  0 siblings, 0 replies; 138+ results
From: anon @ 2010-12-27 18:26 UTC (permalink / raw)


You ask for an example.

Here is an example for packages (Tested using MaRTE):
  Ada.Execution_Time         -- Defines Time type and main operations as
                             -- well as the primary Clock for this type

  Ada.Execution_Time.Timers  -- Links to Timers 


Altering this example one could use a number of timers to be set 
using different times. Or testing a number of algorithms using 
the timer.

Also, I do have a Real_Time non-Task version that this example was 
based on.


-------------------------------
-- Work.adb -- Main program

with Ada.Integer_Text_IO ;
with Ada.Text_IO ;
with Work_Algorithm ;         -- Contains worker algorithm
with Work_Execution_Time ;    -- Contains execution Timing routines

procedure Work is

  use Ada.Integer_Text_IO ;
  use Ada.Text_IO ;
  use Work_Execution_Time ; 

  Task_0 : Work_Task ;

begin -- Work
  Initialize ( Work_Algorithm'Access ) ;
  Task_0.Start ( False ) ;

  -- Prints results of Test

  New_Line ;
  Put ( "Event occured " ) ;
  Put ( Item => Counter, Width => 3 ) ;
  Put_Line ( " Times." ) ;
  New_Line ;

end Work ;

-------------------------------
-- Work_Algorithm.ads

procedure Work_Algorithm ;

-------------------------------
-- Work_Algorithm.adb

with Ada.Integer_Text_IO ;
with Ada.Text_IO ;

procedure Work_Algorithm is
    use Ada.Integer_Text_IO ;
    use Ada.Text_IO ;
  begin
    for Index in 0 .. 15 loop
      Put ( "Paused =>" ) ;
      Put ( Index ) ;
      New_Line ;
      delay 1.0 ;
    end loop ;
  end Work_Algorithm ;


-------------------------------
-- Work.Execution_Time.ads

with Ada.Execution_Time ;
with Ada.Real_Time ;

package Work_Execution_Time is

  type Algorithm_Type is access procedure ;

  task type Work_Task is
    entry Start ( Active : in Boolean ) ;
  end Work_Task ;


  Counter    : Natural ;

  procedure Initialize ( A : in Algorithm_Type ) ;

private 

  Algorithm  : Algorithm_Type ;

  Start_Time : Ada.Execution_Time.CPU_Time ;
  At_Time    : Ada.Execution_Time.CPU_Time ;
  In_Time    : Ada.Real_Time.Time_Span ;

end Work_Execution_Time ;

-------------------------------
-- Work_Execution_Time ;
with Ada.Integer_Text_IO ;
with Ada.Text_IO ;
with Ada.Execution_Time ;
with Ada.Execution_Time.Timers ;
with Ada.Real_Time ;
with Ada.Task_Identification ;

package body Work_Execution_Time is


    use Ada.Execution_Time ;
    use Ada.Real_Time ;
    use Timers ;

    package D_IO is new Ada.Text_IO.Fixed_IO ( Duration ) ;
    package S_IO is new Ada.Text_IO.Integer_IO
                                      ( Ada.Real_Time.Seconds_Count ) ;

  protected Handlers is
    -- Handler: Single Event
      procedure Handler_1 ( TM : in out Timer ) ;

    -- Handler: Multple Event
      procedure Handler_2 ( TM : in out Timer ) ;
  end Handlers ;



  task body Work_Task is

      use Ada.Task_Identification ;

    ID         : aliased Task_Id := Current_Task ;
    TM         : Timers.Timer ( ID'Access ) ;

    Cancelled  : Boolean := False ;

  begin
    Counter := 0 ;
    loop
      select
        Accept Start ( Active : in Boolean ) do
          if Active then
            Start_Time := Ada.Execution_Time.Clock ;
            At_Time := Start_Time + Milliseconds ( 5 ) ;
            Set_Handler ( TM, AT_Time, Handlers.Handler_2'Access ) ;
          else
            Start_Time := Ada.Execution_Time.Clock ;
            In_Time := Milliseconds ( 10 ) ;
            Set_Handler ( TM, In_Time, Handlers.Handler_2'Access ) ;
          end if ;

          Algorithm.all ;  -- Execute Test algorithm

          Timers.Cancel_Handler ( TM, Cancelled ) ;
        end Start ;
      or
        terminate ;
      end select ;
    end loop ;
  end Work_Task ;


  --
  -- Timer Event Routines
  --
  protected body Handlers is 

    -- Handler: Single Event

    procedure Handler_1 ( TM : in out Timer ) is

        Value     : Time_Span ;
        Cancelled : Boolean ;

      begin
        Value := Time_Remaining ( TM ) ;
        Ada.Text_IO.Put ( "Timing Event Occured at " ) ;
        D_IO.Put ( To_Duration ( Value ) ) ;
        Ada.Text_IO.New_Line ;
        Counter := Counter + 1 ;
        Cancel_Handler ( TM, Cancelled ) ;
      end Handler_1 ;

    -- Handler: Multple Event

    procedure Handler_2 ( TM : in out Timer ) is

        Value   : Time_Span ;

      begin
        Value := Time_Remaining ( TM ) ;
        Ada.Text_IO.Put ( "Timing Event Occured at " ) ;
        D_IO.Put ( To_Duration ( Value ) ) ;
        Ada.Text_IO.New_Line ;
        Counter := Counter + 1 ;

        Start_Time := Ada.Execution_Time.Clock ;
        In_Time := Ada.Real_Time.Milliseconds ( 10 ) ;
        Set_Handler ( TM, In_Time, Handlers.Handler_2'Access ) ;
      end Handler_2 ;

  end Handlers ;


  -- Initialize: Set Algorithm and Counter

  procedure Initialize ( A : in Algorithm_Type ) is
    begin
      Algorithm := A ;
      Counter := 0 ;
    end Initialize ;

end Work_Execution_Time ;




^ permalink raw reply	[relevance 5%]

* Re: gnat: Execution_Time is not supported in this configuration
  2009-12-04 12:10  5% ` Georg Bauhaus
@ 2009-12-07  8:08  0%   ` singo
  0 siblings, 0 replies; 138+ results
From: singo @ 2009-12-07  8:08 UTC (permalink / raw)


On Dec 4, 1:10 pm, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:

> The reason are explained in the GNAT source files.  The ones I have show
> a note, after the © box:
> ------------------------------------------------------------------------------
> --                                                                          --
> --                         GNAT RUN-TIME COMPONENTS                         --
> --                                                                          --
> --                   A D A . E X E C U T I O N _ T I M E                    --
> --                                                                          --
> --                                 S p e c                                  --
> --                                                                          --
> -- This specification is derived from the Ada Reference Manual for use with --
> -- GNAT.  In accordance with the copyright of that document, you can freely --
> -- copy and modify this specification,  provided that if you redistribute a --
> -- modified version,  any changes that you have made are clearly indicated. --
> --                                                                          --
> ------------------------------------------------------------------------------
>
> --  This unit is not implemented in typical GNAT implementations that lie on
> --  top of operating systems, because it is infeasible to implement in such
> --  environments.
>
> --  If a target environment provides appropriate support for this package
> --  then the Unimplemented_Unit pragma should be removed from this spec and
> --  an appropriate body provided.
>
> with Ada.Task_Identification;
> with Ada.Real_Time;
>
> package Ada.Execution_Time is
>    pragma Preelaborate;
>
>    pragma Unimplemented_Unit;

Thanks to all of you for your help!

Still I wonder why it is written in the GNAT reference specification
that the real time annex is fully implemented [1].

"Real-Time Systems (Annex D) The Real-Time Systems Annex is fully
implemented."

According to the ARM 'Execution Time' is part of the real-time annex
[2], so it should be implemented.

So, does "fully implemented" mean that it only in principle is fully
implemented, but that the underlying OS/hardware (in my case 64-bit
Ubuntu-Linux (9.10) on an Intel QuadCore) has to support this features
as well?

Or how do I have to read "fully implemented"?

Best regards

Ingo

[1] http://gcc.gnu.org/onlinedocs/gnat_rm/Specialized-Needs-Annexes.html#Specialized-Needs-Annexes
[2] http://www.adaic.org/standards/05rm/html/RM-D-14.html




^ permalink raw reply	[relevance 0%]

* Re: gnat: Execution_Time is not supported in this configuration
  @ 2009-12-04 12:10  5% ` Georg Bauhaus
  2009-12-07  8:08  0%   ` singo
  0 siblings, 1 reply; 138+ results
From: Georg Bauhaus @ 2009-12-04 12:10 UTC (permalink / raw)


singo schrieb:

> I cannot get the package Ada.Execution_Time to work with gnat,
> although the gnat documentation says that the real-time annex is fully
> supported... I use the gnat version 4.4 on a Ubuntu 9.10 distribution.

The reason are explained in the GNAT source files.  The ones I have show
a note, after the � box:
------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                   A D A . E X E C U T I O N _ T I M E                    --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT.  In accordance with the copyright of that document, you can freely --
-- copy and modify this specification,  provided that if you redistribute a --
-- modified version,  any changes that you have made are clearly indicated. --
--                                                                          --
------------------------------------------------------------------------------

--  This unit is not implemented in typical GNAT implementations that lie on
--  top of operating systems, because it is infeasible to implement in such
--  environments.

--  If a target environment provides appropriate support for this package
--  then the Unimplemented_Unit pragma should be removed from this spec and
--  an appropriate body provided.

with Ada.Task_Identification;
with Ada.Real_Time;

package Ada.Execution_Time is
   pragma Preelaborate;

   pragma Unimplemented_Unit;





^ permalink raw reply	[relevance 5%]

* Re: exit a program
  @ 2009-08-02 14:38  6% ` Robert A Duff
  0 siblings, 0 replies; 138+ results
From: Robert A Duff @ 2009-08-02 14:38 UTC (permalink / raw)


asd@fdsfs.com (Autoscontro difettoso) writes:

> is there an instruction that stops a program?

In GNAT, look at GNAT.OS_Lib.  You can call OS_Exit or OS_Abort.

In other compilers, you can call "exit" or "abort" via pramga Import.

Alternatively, you can abort the environment task.  Look at
Ada.Task_Identification.  If you call Current_Task during library-level
elaboration, you can save the identity of the env task.

- Bob



^ permalink raw reply	[relevance 6%]

* Re: [Ravenscar] run tasks on events
  @ 2008-05-30 11:59  6%       ` stefan-lucks
  0 siblings, 0 replies; 138+ results
From: stefan-lucks @ 2008-05-30 11:59 UTC (permalink / raw)


On Fri, 30 May 2008, Niklas Holsti wrote:

> In unrestricted Ada, if an exception occurs in a task, and the task does not
> handle the exception, the task by default terminates silently when the
> exception propagates out of the task. If you want to know about exceptions in
> a task, you should put a last-chance, catch-all exception handler in the task
> body ("exception when others => ...").

You don't need this in Ada 05 any more. You can define some callback 
procedures, to do something in the case of unhandled exceptions (and 
normal and abnormal termination as well, if you want to). 


The following is similar to an example in Barnes' book, except that the 
usage avoids race conditions:

--------------------------------------------------------------------------

Package defined in 
<http://www.adaic.org/standards/05rm/html/RM-C-7-3.html>:

with Ada.Task_Identification; with Ada.Exceptions;

package Ada.Task_Termination is
  ...
  type Cause_Of_Termination is (Normal, Abnormal, Unhandled_Exception);
  type Termination_Handler is access protected procedure
    (Cause : in Cause_Of_Termination;
     T     : in Ada.Task_Identification.Task_Id;
     X     : in Ada.Exceptions.Exception_Occurrence);

  procedure Set_Dependents_Fallback_Handler(Handler: in Termination_Handler);
  ...
end Ada.Task_Termination;

--------------------------------------------------------------------------

Specification of Callback:

protected End_Of is
  
  procedure World(C: Cause_Of_Termination;
                  T: Task_ID;
                  X: Exception_Occurrence);

end End_Of;

--------------------------------------------------------------------------

Implementation of Callback:

  procedure World(C: Cause_Of_Termination;
                  T: Task_ID;
                  X: Exception_Occurrence);

  begin
    case C is
      when Normal => 
        null;
      when Abnormal => 
        Put_Log("abnormal termination of Task" & Image(T));
      when Unhandled_Exception =>
        Put_Log("unhandled exception in Task" & Image(T));
        Put_Log(Exception_Information(X));
    end case;
  end World;

--------------------------------------------------------------------------

Usage of callback (typically in main program / environment task):

begin 
  Set_Dependents_Fallback_Handler(End_Of.World);
  declare -- any task you want
    A_Bunch_Of_Tasks: array (0 .. 1023) of Some_Task_Type;
    Alice, Bob: Some_Other_Task_Type;
  begin
    ...
    -- Whenever any of our tasks terminates normally or abnormally or 
    -- propagates an exception, End_Of.World is called. 
  end;
end;




So long

Stefan

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[relevance 6%]

* Re: Finalization of static package variables
  2007-05-16 19:10  7%           ` Randy Brukardt
@ 2007-05-22  4:41  0%             ` christoph.grein
  0 siblings, 0 replies; 138+ results
From: christoph.grein @ 2007-05-22  4:41 UTC (permalink / raw)


On 16 Mai, 21:10, "Randy Brukardt" <r...@rrsoftware.com> wrote:
> No, because your proposed "fix" is more complex than the trick, which is
> simply to use Ada.Task_Identification:
>
> -- In a librarypackage:
> with Ada.Task_Identification; use Ada.Task_Identification;
>
> Env_Task_Id : constant Task_Id := Current_Task;
>
> Now, in any task that you want to take special action if the main subprogram
> has exited:
>
>      if Is_Completed (Env_Task_Id) then

There is no such function as is_Completed. Which do you mean:
   is_Terminated
or
   not is_Callable?




^ permalink raw reply	[relevance 0%]

* Re: Finalization of static package variables
  @ 2007-05-16 19:10  7%           ` Randy Brukardt
  2007-05-22  4:41  0%             ` christoph.grein
  0 siblings, 1 reply; 138+ results
From: Randy Brukardt @ 2007-05-16 19:10 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message
news:1179324410.556097.234870@u30g2000hsc.googlegroups.com...
...
> So, to go back to a point I briefly mentioned in my previous post:
> does Ada need a feature that would allow you to call your own
> finalization procedure or something when the environment task is
> completing, so that you don't have to do this using trickery?

No, because your proposed "fix" is more complex than the trick, which is
simply to use Ada.Task_Identification:

-- In a library package:
with Ada.Task_Identification; use Ada.Task_Identification;

Env_Task_Id : constant Task_Id := Current_Task;

Now, in any task that you want to take special action if the main subprogram
has exited:

     if Is_Completed (Env_Task_Id) then

Originally, when I dreamt this up for Claw, no compilers actually
implemented it. Indeed, I asked the question to the ARG, which became
AI-206. When that was resolved, ACATS test CXC7004 was added to test it, so
it is likely that all current compilers support doing this. (Surely all of
the Windows ones do, we sent bug reports to all of them...)

So there is no need for something fancier, the capability already exists.

                            Randy.











^ permalink raw reply	[relevance 7%]

* Re: task time-out&abort
  2005-06-22 18:08  5% task time-out&abort e.coli
  2005-06-22 18:40  0% ` Dmitry A. Kazakov
@ 2005-06-22 19:44  0% ` Mark Lorenzen
  1 sibling, 0 replies; 138+ results
From: Mark Lorenzen @ 2005-06-22 19:44 UTC (permalink / raw)


"e.coli" <maurizio.ferracini@gmail.com> writes:

> here the code...
> ------------------------------------
> with Ada.Text_Io;
> with Ada.Task_Identification;
> 
> procedure Semplice2 is --processo genitore
> 
>    task Un_Task is--specifica
>       entry Uno;
>       entry Due;
>    end Un_Task;
> 
>    task body Un_Task is
>    begin
>       loop
>          select
>             accept Uno do
>                Ada.Text_Io.Put_Line("foo");
>             end Uno;
>          or
>             accept Due do
>                Ada.Text_Io.Put_Line("buffering");
>                loop           -- ;)
>                   delay(0.0);
>                end loop;
>                Ada.Text_Io.Put_Line("bar");
>             end Due;
>          end select;
>       end loop;
>    end Un_Task;
> 
> begin --corpo genitore
>    Un_Task.Uno;
>    Ada.Text_Io.Put_Line ("wait Horribly long calculation");
>    select
>       delay 5.0;
>       Ada.Text_Io.Put_Line ("Horribly long calculation abandoned");
>    then abort
>       un_task.due;
>    end select;
> end Semplice2;
> -----------------------------------------
> 
> but don't work...
> how i can do the five second time out?
> thanks

As I see it, you have a calculation that may take a long time and you
want to abandon that calculation, if some time constraint is
reached. To do it the proper "Ada-way" you will need to use an other
technique, see:

http://www.adaic.com/standards/95aarm/html/AA-9-7-4.html

- Mark Lorenzen



^ permalink raw reply	[relevance 0%]

* Re: task time-out&abort
  2005-06-22 18:08  5% task time-out&abort e.coli
@ 2005-06-22 18:40  0% ` Dmitry A. Kazakov
  2005-06-22 19:44  0% ` Mark Lorenzen
  1 sibling, 0 replies; 138+ results
From: Dmitry A. Kazakov @ 2005-06-22 18:40 UTC (permalink / raw)


On 22 Jun 2005 11:08:23 -0700, e.coli wrote:

> here the code...
> ------------------------------------
> with Ada.Text_Io;
> with Ada.Task_Identification;
> 
> procedure Semplice2 is --processo genitore
> 
>    task Un_Task is--specifica
>       entry Uno;
>       entry Due;
>    end Un_Task;
> 
>    task body Un_Task is
>    begin
>       loop
>          select
>             accept Uno do
>                Ada.Text_Io.Put_Line("foo");
>             end Uno;
>          or
>             accept Due do
>                Ada.Text_Io.Put_Line("buffering");
>                loop           -- ;)
>                   delay(0.0);
>                end loop;
>                Ada.Text_Io.Put_Line("bar");
>             end Due;
>          end select;
>       end loop;
>    end Un_Task;
> 
> begin --corpo genitore
>    Un_Task.Uno;
>    Ada.Text_Io.Put_Line ("wait Horribly long calculation");
>    select
>       delay 5.0;
>       Ada.Text_Io.Put_Line ("Horribly long calculation abandoned");
>    then abort
>       un_task.due;
>    end select;
> end Semplice2;
> -----------------------------------------
> 
> but don't work...
> how i can do the five second time out?
> thanks

It is not clear what you are trying to achieve. The entry point Due engages
the rendezvous and then loops there. Because looping happens during a
rendezvous both participants (Un_Task and the main task) will stay there
forever. Note that a timed entry call puts on a limit for *waiting* for a
rendezvous, it does not limit the rendezvous itself.

---
The rule of thumb: rendezvous (and protected operations) should be as short
as possible.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* task time-out&abort
@ 2005-06-22 18:08  5% e.coli
  2005-06-22 18:40  0% ` Dmitry A. Kazakov
  2005-06-22 19:44  0% ` Mark Lorenzen
  0 siblings, 2 replies; 138+ results
From: e.coli @ 2005-06-22 18:08 UTC (permalink / raw)


here the code...
------------------------------------
with Ada.Text_Io;
with Ada.Task_Identification;

procedure Semplice2 is --processo genitore

   task Un_Task is--specifica
      entry Uno;
      entry Due;
   end Un_Task;

   task body Un_Task is
   begin
      loop
         select
            accept Uno do
               Ada.Text_Io.Put_Line("foo");
            end Uno;
         or
            accept Due do
               Ada.Text_Io.Put_Line("buffering");
               loop           -- ;)
                  delay(0.0);
               end loop;
               Ada.Text_Io.Put_Line("bar");
            end Due;
         end select;
      end loop;
   end Un_Task;

begin --corpo genitore
   Un_Task.Uno;
   Ada.Text_Io.Put_Line ("wait Horribly long calculation");
   select
      delay 5.0;
      Ada.Text_Io.Put_Line ("Horribly long calculation abandoned");
   then abort
      un_task.due;
   end select;
end Semplice2;
-----------------------------------------

but don't work...
how i can do the five second time out?
thanks




^ permalink raw reply	[relevance 5%]

* Re: Finalization of a record containing a task
  @ 2005-02-18  2:34  7%         ` Randy Brukardt
  0 siblings, 0 replies; 138+ results
From: Randy Brukardt @ 2005-02-18  2:34 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wccll9mu3m7.fsf@shell01.TheWorld.com...
...
> >... So in most cases one
> > is forced to use access-to-task components rather than plain task ones.
>
> Yes, but if you declare the object in a library package, you'll
> still have the same problem with finalization happening too late.

Claw uses Ada.Task_Identification.Is_Callable to handle this problem.
(Unfortunately, some compilers get this wrong.) That only works if you
trying to handle this at the library level (having some other solution for
nested objects). In our case, the task is a library-level one that all of
the objects share; the problem is that the task can only close when all of
the objects are gone (as they potentially could use it for executing
commands), but of course the task has to go away before any library-level
objects are finalized.

The solution was to use Ada.Task_Identification.Is_Callable to see if the
main subprogram has completed. If it has, the task exits, allowing
finalization to continue. (Otherwise, a Claw program would hang if objects
are not destroyed by the program, which was common when exceptions were
raised.) This isn't quite a bullet-proof solution; if the main program does
nothing and exits quickly, with all of the real work done by library tasks,
this will cause premature shutdown of the application. (Claw has a way to
turn off this termination for this reason, but the default behavior is less
surprising in the *vast* majority of programs.) This eliminated the
confusing hangs, and made Claw a lot more usable. (We've also got a bunch of
code to detect whether the implementation actually provides a meaningful
result from this function, but hopefully this now works on implementations.)

The trick is to get a task id for the environment task. That can be done by
asking for current task during library-level elaboration by declaring a
constant directly in a library package spec or body:
       Env_Task_Id : constant Ada.Task_Identification.Task_ID :=
             Ada.Task_Identification.Current_Task;
and then using it as needed.

                     Randy.







^ permalink raw reply	[relevance 7%]

* Re: generic and visibility
  2004-11-04 15:23  5% generic and visibility mferracini
@ 2004-11-05  3:39  0% ` John Woodruff
  0 siblings, 0 replies; 138+ results
From: John Woodruff @ 2004-11-05  3:39 UTC (permalink / raw)


"mferracini" <maurizio.ferracini@gmail.com> wrote in message news:<1099581795.057353.199160@c13g2000cwb.googlegroups.com>...
> i'm new on ADA, and i hav some problem
> with generic.
> 
> this is an exemple
> 
> 
> 
> ------------------------------------
> package Manage is
> generic
> Id : integer;
> with procedure Init;
> with procedure Job;
> package Det is
> 
> procedure Start(
> Status :    out Integer );
> end Det;
> end Manage;
> 
> ----------------------------------------
> 
> with Ada.Text_Io;
> with Ada.Task_Identification;
> 
> package body Applicazione is
> I : Integer := 0;
> 
> procedure Init is
> begin
> I:=1;
> end Init;
> 
> procedure Job is
> begin
> Ada.Text_Io.Put(Item => "> mi sbatto!  ");
> I:=I+1;
> Ada.Text_Io.Put(Item => Integer'Image (I));
> Ada.Text_Io.New_Line;
> end Job;
> 
> end Applicazione;
> -----------------------------------------
> 
> with Manage;
> with Applicazione;
> 
> 
> package Fake_App is new Manage_Task.Det_Task_M_Pack
> (
> Id_task => 1,
> Init_Job => Applicazione.Init,
> Job => Applicazione.Job);
> 
> ---------------
> 
> 
> with Fake_App;
> 
> procedure Test is
> begin
> Fake_app.job;
> end Test;
> 
> ---------------------------------------------------------------------------------
> job in not a visible entry of fake_app
> 
> how i can do?
> thanks

I'm guessing "homework" here, so I'll give (I hope) constructive
hints, but not solve the problem completely ----

You have omitted a couple items that are needed before I can answer
your direct question.

You need to give a specification for the package Applicazione.  You
gave only a body, and every package needs a spec (most need a body as
well). 

It probably looks like this:

package Applicazione is
  procedure Init ;
  procedure Job ;
end Applicazione;
-----

Next, your package that you call "Fake_App" is not correct.  Manage
contains an internal package called Det.  So you need to "instantiate"
that internal package by naming it properly when you say something
like

  package Fake_App is new <<correct name here>> with its parameters.
-----

Then finally, why are you unable to find an entry "job" in the
instance called Fake_App?

When you make a new instance (the thing you're calling Fake_App),
it has the  subprograms that were visible in its spec.  Start is the
ONLY visible subprogram declared.  Consider the difference between the
generic formal procedure "Job" and the procedure Start.   

HTH
John



^ permalink raw reply	[relevance 0%]

* generic and visibility
@ 2004-11-04 15:23  5% mferracini
  2004-11-05  3:39  0% ` John Woodruff
  0 siblings, 1 reply; 138+ results
From: mferracini @ 2004-11-04 15:23 UTC (permalink / raw)


i'm new on ADA, and i hav some problem
with generic.

this is an exemple



------------------------------------
package Manage is
generic
Id : integer;
with procedure Init;
with procedure Job;
package Det is

procedure Start(
Status :    out Integer );
end Det;
end Manage;

----------------------------------------

with Ada.Text_Io;
with Ada.Task_Identification;

package body Applicazione is
I : Integer := 0;

procedure Init is
begin
I:=1;
end Init;

procedure Job is
begin
Ada.Text_Io.Put(Item => "> mi sbatto!  ");
I:=I+1;
Ada.Text_Io.Put(Item => Integer'Image (I));
Ada.Text_Io.New_Line;
end Job;

end Applicazione;
-----------------------------------------

with Manage;
with Applicazione;


package Fake_App is new Manage_Task.Det_Task_M_Pack
(
Id_task => 1,
Init_Job => Applicazione.Init,
Job => Applicazione.Job);

---------------


with Fake_App;

procedure Test is
begin
Fake_app.job;
end Test;

---------------------------------------------------------------------------------
job in not a visible entry of fake_app

how i can do?
thanks




^ permalink raw reply	[relevance 5%]

* Re: Task discriminants
  2004-05-21  7:57  5%   ` Dmitry A. Kazakov
@ 2004-06-04 12:59  0%     ` Andersen Jacob Sparre
  0 siblings, 0 replies; 138+ results
From: Andersen Jacob Sparre @ 2004-06-04 12:59 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> Though, why one should want an Id discriminant, if there is the
> package Ada.Task_Identification?

It could be that the tasks represented entities with externally
assigned identities.

Greetings,

Jacob
-- 
Scripts for automating parts of the daily
operations of your Linux system:
              http://jacob.sparre.dk/Jacob/edb/tcsh-samling/



^ permalink raw reply	[relevance 0%]

* Re: Task discriminants
  @ 2004-05-21  7:57  5%   ` Dmitry A. Kazakov
  2004-06-04 12:59  0%     ` Andersen Jacob Sparre
  0 siblings, 1 reply; 138+ results
From: Dmitry A. Kazakov @ 2004-05-21  7:57 UTC (permalink / raw)


On Thu, 20 May 2004 19:30:57 +0200, Martin Krischik
<krischik@users.sourceforge.net> wrote:

>Dave Levy wrote:
>
>> Suppose one has a task type with a discriminant:
>> 
>>     task type A_Task( Id : integer);
>> 
>> and one wishes to declare a set of tasks with initialised discriminants:
>>     t1 : A_Task(1);
>>     t2 : A_Task(2);
>>     t3 : A_Task(3);
>> 
>> How could one declare them as an array of tasks with each one getting an
>> initialised discriminant? Perhaps something like:
>> 
>>     The_Tasks: array (1..3) of A_Task( Id => 1,2,3 );

Ada does not have constructors with parameters, alas.

>> Except I tried this with Gnat and it won't compile.
>
>Of corse not! Tasks are indefinite type and can't be stored in arrays. You
>can store an access to a task in an array.
>
>With Regards
>
>Martin
>
>PS: I could not find anything in the RM: Does anybody know if task are also
>limited.

Task types are indeed limited. This does not prevent us from having
arrays of tasks. A task type as above with an integer discriminant
will be unconstrained not because it is a task, but because Id has no
default value. The solution Martin Dowie proposed shows it.

Though, why one should want an Id discriminant, if there is the
package Ada.Task_Identification?

--
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[relevance 5%]

* Re: To raise an exception in task and handle/catch it in outer-block.
  @ 2004-01-10 21:05  3%       ` Frank
  0 siblings, 0 replies; 138+ results
From: Frank @ 2004-01-10 21:05 UTC (permalink / raw)


Hi!

Im dont understand your answer completely. What I get from it is that the
effect
of this kind of construction ..may be... platform-dependent, due to a
GNAT-bug (which is an OK answer).

I have tried (dont read it as "tested") the original example in Windows,
where it appeared to work
the 5-7 times I ran it :-)

It was my feeling that my construction was "agressive" this is why I check
it here.

1) I agree that there is a great chance of  locking tasks doing it in this
way.
2) The Text_IO is there for the moment for debugging purposes.
3) And by "outer-block" I mean the calling main program in my example.
4) Im currently using GNAT 3-15p on Windows XP.

This leaves me with the original "problem", how to I simplify the life of
the outer-block. In this posting a have noted two alternative.....

A)
--------------------------------
Norman H. Cohen's "Ada a Second language"(2nd ed) discusses this issue in
chapter
"18.9.1 Exceptions in Task Bodies", he proposes a solution where the
exception becomes
noticeable (but not "handled" when considering my example):

<Quote Norman H. Cohen>

task body My_Task
...
  use Ada.Text_IO; Ada.Task_Identification; Ada.Exception;
begin
..
exception
  when E: others => Put_Line(Current_Error, "Task " & Image(Current_Task) &
"terminated becuase of exception " &
       Exception_Name(E));
end My_Task;

</Quote Norman H. Cohen>

I have used it, and it works, but I was not quite satisifed because it still
leaves my outer-block in trouble....

B)
--------------------------------
A new theory I have now after reading this feedback, is to do the follwoing
(this is a rework of the example in the original posting):

What I do here is that I remove the "accept"'s in the exception-block of the
task and leaves an exceptions handling like
alternative (A) plus catching then "test_exception" in particular.
The accept is now moved to the if-statement where the
problem is found. Now the outer-block will
call these "alternative" accept-statements if the if-statement found a
problem. I leave the "raise test_exception" in the
"accept Final" as before, which should propagate to the outer-block.
(PS: Example has not been compiled by me)


Now I should be back on safe grounds again - or what?


with Ada.Text_IO;

package body Test_Task_Exception is

   test_exception : exception;

   task body A_Task is
     Run : Boolean := False;
     Counter : Integer := 0;
     Fail : Boolean;

   begin
      accept Init ( P_Fail : in Boolean) do
         Ada.Text_IO.Put_Line ("Test_Task_Exception.A_Task.Init - Body");
         Fail := P_Fail;
      end Init;

      accept Start do
         Ada.Text_IO.Put_Line ("Test_Task_Exception.A_Task.Start - Body");
         Run := True;
      end Start;

      while Run loop
         Counter := Counter + 1;

         Ada.Text_IO.Put_Line("Test_Task_Exception.A_Task.Task Working " &
Counter'Img);

         if Counter > 8 and not Fail then
            select
               accept Stop do
                  Ada.Text_IO.Put_Line ("Test_Task_Exception.A_Task.Stop -
Body");
                  Run := False;
               end Stop;

            else
                  null;
            end select;
         end if;

         if Counter > 8 and Fail then
            -- I wish to raise a exception and propagate it to the
outer-block.
            -- I add an accept here also that the outer-block will visit
now...
            accept Stop do
                Ada.Text_IO.Put_Line
("Test_Task_Exception.A_Task.Stop -Alternative handling");
                Run := False;
            end Stop;

            accept Final do
                Ada.Text_IO.Put_Line ("Test_Task_Exception.A_Task.Final - To
Raise exception");
                raise test_exception;
            end Final;
         end if;
      end loop;

      accept Final do
        Ada.Text_IO.Put_Line ("Test_Task_Exception.A_Task.Final - Body");
      end Final;

    exception
        when test_exception => null; -- short cut this one since it is
handled elsewhere.....

        when others =>
       -- "Norman H. Cohen's tick"

   end A_Task;

end Test_Task_Exception;







^ permalink raw reply	[relevance 3%]

* No_Abort_Statements
@ 2003-07-31 19:40  8% Stephan Heinemann
  0 siblings, 0 replies; 138+ results
From: Stephan Heinemann @ 2003-07-31 19:40 UTC (permalink / raw)


D.7.5 says

No_Abort_Statements
There are no abort_statements, and there are no calls on
Task_Identification.Abort_Task.

My compiler (gnat) detects only the violation caused by "abort T;". But I 
get
away with "Abort_Task(T'Identity);" or using ATC via select (see below).
Now, I am not quite sure what this restriction really covers... Abort_Task
should obviously be detected but what about ATC?

Thanks in advance,
Stephan

pragma Restrictions(No_Abort_Statements);

with Ada.Task_Identification; use Ada.Task_Identification;
with Ada.Text_IO; use Ada.Text_IO;

procedure No_Abort_Statements is

    task type A;
    task body A is
    begin
        loop
            Put_Line(Image(Current_Task));
            delay 0.5;
        end loop;
    end A;

    T : A;

begin
    abort T;
    
    --Abort_Task(T'Identity);
    
    --select
    --    delay 1.0;
    --    Put_Line("aborted");
    --then abort
    --    declare
    --        T : A;
    --    begin
    --        delay 2.0;
    --    end;
    --end select;
    
end No_Abort_Statements;




^ permalink raw reply	[relevance 8%]

* Re: terminate applications
  @ 2003-07-24 16:06  6%                                 ` Robert I. Eachus
  0 siblings, 0 replies; 138+ results
From: Robert I. Eachus @ 2003-07-24 16:06 UTC (permalink / raw)


Marin David Condic wrote:
> I think the answer is to have a standard library of stuff that provides 
> connections to common OS operations. Most OS's support some kind of 
> process kill capability - we just need a standard interface to it. In 
> "normal" conditions, you use the Ada task abortion. When you need some 
> specialized OS capability (such as killing without concern for cleanup, 
> etc.) you connect to the OS in a standard way and let it do the wet-work 
> for you.

First you ignored this code snippet for putting in any loops in an abort 
deferred region.  You should probably wrap OS calls in an abort deferred 
region with a tendancy to hang in an ATC with similar effects. Of 
course, better is not to put OS calls in protected objects, but 
sometimes, as in device drivers or interrupt handlers, it is necessary.

with Ada.Task_Identification; use Ada.Task_Identification;
procedure Exit_Abort_Deferred_Region is
begin
   if Is_Terminated(Current_Task) then raise Program_Error; end if;
end Exit_Abort_Deferred_Region;

Having said that, in one sense this argument is specious.  In Ada 83, 
abort meant "terminate with extreme predjudice."  Ada 83 code compiled 
with an Ada 95 compiler will have the same semantics--Ada 95 abort can 
only hang in the presense of Ada 95 extensions to Ada 83.

The argument that you couldn't abort the environment task in Ada 83 is 
also specious.  Ada 83 did not forbid it, but also did not provide a 
non-implementation specific name for the environment task.  However, the 
main program, or anything running in the main task could execute an 
abort with no argument, which aborted the environment task and all 
dependent tasks.

So the question should not be, "Is this feature in good taste?" but "Is 
this feature needed in the presence of the new Ada 95 extensions.  There 
are good arguments on both sides, but I tend to feel that such a 
super-abort or �berkill is necessary and should be provided in Annex D. 
  And as I also said, the procedure should do as much cleanup as 
possible, subject to a time limit, something like:

procedure Abort_All(Timeout: Duration);

So that Abort_All(3.0) allows for reasonable last wishes, and 
Abort_All(0.0) says kill everything now.  The reference manual can say 
that the Timeout value should be chosen to allow all non-abort deferred 
tasks to complete their cleanup.

-- 

                                                        Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are 
insignificant beside two prime questions, which are: 1. Can he shoot? 2. 
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and 
Steve Miller.




^ permalink raw reply	[relevance 6%]

* Priority Ceiling
@ 2003-07-23 21:24  6% Stephan Heinemann
  0 siblings, 0 replies; 138+ results
From: Stephan Heinemann @ 2003-07-23 21:24 UTC (permalink / raw)


Please have a look at the following piece of code:

pragma Queuing_Policy(Priority_Queuing);
pragma Locking_Policy(Ceiling_Locking);
pragma Task_Dispatching_Policy(FIFO_Within_Priorities);

with System; use System;
with Ada.Dynamic_Priorities; use Ada.Dynamic_Priorities;
with Ada.Task_Identification; use Ada.Task_Identification;
with Ada.Exceptions; use Ada.Exceptions;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Priorities is
    pragma Priority(0);
    -- if not specified default priority is inherited by tasks?
    P1: constant Priority := Priority'First;
    P2: constant Priority := Priority'Last;

    protected Ceiling_Object is
        --pragma Priority(System.Priority'Last);
        pragma Priority(2);
        -- less than 15 raises Program_Error?
        -- default priority
        procedure E;
    end Ceiling_Object;

    protected body Ceiling_Object is    
        procedure E is
        begin
            Put_Line("E entered");
            -- delay 5.0; -- should actually not be done
            -- display the active priority
            Put(Image(Current_Task));
            Put(Get_Priority(Current_Task)); New_Line;
            -- dynamic priority not raised?
            Put_Line("E finished");
        end E;
    end Ceiling_Object;
    
    task A is
        pragma Priority(0);
    end A;
    
    task body A is
    begin
        Put_Line("T running");
        Ceiling_Object.E;
        -- should raise Program_Error only if task priority
        --- higher than ceiling priority
        Put_Line("T done");
    exception
        when Ex: others =>
            Put(Image(Current_Task) & " ");
            Put(Exception_Name(Ex)); New_Line;
    end A;
    
    task B is
        pragma Priority(1);
    end B;
    
    task body B is
    begin
        Put_Line("B running");
        Ceiling_Object.E;
        Put_Line("B done");
    exception
        when Ex: others =>
            Put(Image(Current_Task) & " ");
            Put(Exception_Name(Ex)); New_Line;
    end B;

begin
    Put("P1: "); Put(P1); New_Line;
    Put("P2: "); Put(P2); New_Line;
end Priorities;

Now the questions:
(1)
If I understood correctly then the task priority should be raised to the
ceiling priority of the protected object (immediate ceiling priority
protocol). However, I cannot obtain this new active priority using
"Get_Priority(Current_Task)"; the base priority is returned instead. Why?
(2)
The procedure "Priorities" would run with default priority (15) if
pragma Priority(0) was not given. But this change seems to affect the
defined tasks as well, eventhough they have their own base priorities
assigned to them. Do they inherit their priorities from the
"Priorities"-executing task, if they are assigned lower base priorities
than the latter?

Thanks in advance,
Stephan



^ permalink raw reply	[relevance 6%]

* Re: terminate applications
  @ 2003-07-23  4:02  6%                             ` Robert I. Eachus
    0 siblings, 1 reply; 138+ results
From: Robert I. Eachus @ 2003-07-23  4:02 UTC (permalink / raw)


Marin David Condic wrote:

> If Ada wants to be competitive against C, C++, Java or whatever else is 
> out there, it has to be focused on customer needs. It can't be dependent 
> on sending the customer to the competitor for features it can't or won't 
> support, or the customer just starts to wonder why he is bothering with 
> Ada when he has to have the other product anyway in order to get the job 
> done. Ada needs to provide "One-Stop Shopping" so a developer doesn't 
> need to look elsewhere for an answer.

As I have said, I think that you may have a need that should be 
addressed.  But remember what you are asking for here.  To get to the 
point where you need this feature in Ada, you have to use not normal 
(Ada 83) tasking but protected objects or asynchronous transfer of 
control.  Furthermore you have to place a blocking action--or more 
normally an endless loop--inside an abort deferred region.

As I said, I certainly agree that, especially for debugging situations, 
such a feature would be nice to have.  But the more I think about it, 
the more I think that the right solution may be to add a special 
procedure that breaks the abort deferral.  Let's see,

with Ada.Task_Identification; use Ada.Task_Identification;
procedure Exit_Abort_Deferred_Region is
begin
   if Is_Terminated(Current_Task) then raise Program_Error; end if;
end Exit_Abort_Deferred_Region;

Not very special after all, but you do need Ada.Task_Identification from 
Annex C.  And if you do insist on putting loops inside protected object, 
probably a useful tool to have around.  (For example, if you do a search 
through a linked list. Or use an AVL or other type of tree and do 
lookups.)  Putting that in busy waits inside protected objects and in 
other loops where you might have a problem solves part of the problem.

The other problem, of aborting a task that is waiting IN the OS has to 
be an implementation defined thing.  But it shouldn't be too hard to 
talk your vendor in to checking whether a task that is being aborted is 
waiting in an OS call and doing whatever OS specific thing is required 
to get out there.  Especially where Ada tasks correspond to OS threads, 
that shouldn't be too hard.  You don't care why that (abort protected) 
thread is not in a ready state in the OS, you want to kill any such 
threads.  (Since making a blocking call from an abort protected region 
is a bounded error, I don't think any langauge changes are required for 
this.)

-- 

                                                Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are 
insignificant beside two prime questions, which are: 1. Can he shoot? 2. 
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and 
Steve Miller.




^ permalink raw reply	[relevance 6%]

* Re: terminate applications
  2003-07-18 10:54  8% ` Jeffrey Creem
@ 2003-07-18 11:51  0%   ` Marin David Condic
    0 siblings, 1 reply; 138+ results
From: Marin David Condic @ 2003-07-18 11:51 UTC (permalink / raw)


Terminating the environment task is supposed to be a legitimate method 
of killing everything, but I've had problems getting it to work with 
GNAT on a PC platform. What compiler do you use on which this works 
reliably?

MDC

Jeffrey Creem wrote:

> 
> package body Arnold is
> 
> Environment_Task_Id : Ada.Task_Identification.Task_Id :=
> Ada.Task_Identification.Current_Task;
> 
> procedure Terminator is
> 
> begin
> 
> Ada.Task_Identification.Abort_Task(Environment_Task_Id);
> 
> end Terminator;
> 
> end Arnold;
> 
> 
> 
> 


-- 
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jast.mil/

Send Replies To: m c o n d i c @ a c m . o r g

     "In general the art of government consists in taking as
     much money as possible from one class of citizens to give
     to the other."

         --  Voltaire
======================================================================




^ permalink raw reply	[relevance 0%]

* Re: terminate applications
  @ 2003-07-18 10:54  8% ` Jeffrey Creem
  2003-07-18 11:51  0%   ` Marin David Condic
  0 siblings, 1 reply; 138+ results
From: Jeffrey Creem @ 2003-07-18 10:54 UTC (permalink / raw)



This is not something I usually have to worry about because almost
everything I do is embedded stuff
but when I am doing little non embedded programs and I want to kill the
program (especially when
making  use of embedded packages that have no real facilities for shutting
down their tasks) I usuallly
just terminate the environment task. The package below provides a procedure
that when called from
anywhere (either main task or any other task) will terminate the environment
task and shut down the
program.

The real answer is that when writing well behaved multi-tasking programs,
one needs to provide nice shutdown
facilities for all the tasks....but this terminator approach works for the
quick and dirty case.


package Arnold is

procedure Terminator;

end Arnold;



with Ada.Task_Identification;

pragma Elaborate_All(Ada.Task_Identification);





package body Arnold is

Environment_Task_Id : Ada.Task_Identification.Task_Id :=
Ada.Task_Identification.Current_Task;

procedure Terminator is

begin

Ada.Task_Identification.Abort_Task(Environment_Task_Id);

end Terminator;

end Arnold;







^ permalink raw reply	[relevance 8%]

* Re: Suspicious reentrant semaphore
  @ 2003-05-01 12:33  6%   ` Jano
  0 siblings, 0 replies; 138+ results
From: Jano @ 2003-05-01 12:33 UTC (permalink / raw)


Dmitry A. Kazakov dice...
> The requeue statement does the trick in case you want to use a parameter 
> value in a barrier. You could add one more private entry and requeue to it 
> if the task is not the owner:

Dmitry: I love this suggestion specially because is the first time I'm 
going to employ requeue (never before I faced the necessity).

Here is the new version of my package. I've also slightly changed the 
release logic to obtain exceptions instead of deadlocks in case of wrong 
use:

---------------- SPEC ---------------------

with Ada.Finalization;        use Ada;
with Ada.Task_identification;

package Adagio.Monitor is

   use Ada.Task_identification;

   Use_error : Exception;
   
   protected type Semaphore is

      entry     P (Owner : Task_id);
      procedure V (Owner : Task_id);

   private

      entry Safe_P (Owner : Task_id);

      Caller : Task_id := Null_task_id;           -- Requester
      In_use : Natural := 0;                      -- Times requested

   end Semaphore;

   type Semaphore_access is access all Semaphore;

   -- Use: 
   -- S : aliased Semaphore;
   -- declare
   --   M : Object(S'access);
   -- begin
   --   Exclusive_work;
   -- end;
   type Object (S : access Semaphore) is new 
      Finalization.Limited_Controlled with null record;

   procedure Initialize (this : in out Object);
   procedure Finalize   (this : in out Object);

end Adagio.Monitor;

------------------ BODY -----------------------

package body Adagio.Monitor is

   protected body Semaphore is

      entry P (Owner : Task_id) when true is
      begin
         if Owner = Caller then
            In_use := In_use + 1;
         else
            requeue Safe_P with abort;
         end if;
      end P;

      entry Safe_P (Owner : Task_id) when In_use = 0 is
      begin
         Caller := Owner;
         In_use := 1;
      end Safe_P;

      procedure V (Owner : Task_id) is
      begin
         if Owner /= Caller then
            raise Use_error;
         else
            In_use:= In_use - 1;
            if In_use = 0 then
               Caller := Null_task_id;
            end if;
         end if;
      end V;

   end Semaphore;

   -- Get
   procedure Initialize(this: in out Object) is
   begin
      this.S.P (Current_task);
   end Initialize;

   -- Release
   procedure Finalize(this: in out Object) is
   begin
      this.S.V (Current_task);
   end Finalize;

end Adagio.Monitor;

-- 
-------------------------
Jano
402450.at.cepsz.unizar.es
-------------------------



^ permalink raw reply	[relevance 6%]

* Re: Suspicious reentrant semaphore
  2003-04-29 22:04  4% Suspicious reentrant semaphore Jano
  @ 2003-04-30 17:39  5% ` Randy Brukardt
  1 sibling, 0 replies; 138+ results
From: Randy Brukardt @ 2003-04-30 17:39 UTC (permalink / raw)


Jano wrote in message ...
>Hello everybody,
>Leaving aside why I have done that (yes, poor design, I'm removing it
>anyway ;-), I would like to know if my package is right or really is
>there some race condition. Please comment on it. I know that
>Current_Task shouldn't be called inside entries (in fact Gnat doesn't
>allow it, I tried :-P) but doesn't complain about it being used in
>barriers. Anyways, I have a (maybe wrong) feel about that being related
>to the deadlock.


Why don't you use the attribute defined for this purpose? E'Caller
returns the task-id of the caller.

Claw uses a lock much like this one, and it uses E'Caller, not
Current_Task (which may not be the caller).

Here's the body of the "Get" entry from Claw:

        entry Get when True is
            use type Ada.Task_Identification.Task_Id;
        begin
            if Use_Count = 0 then
                Owner_Task_Id := Get'Caller;
                Use_Count := 1;
            elsif Owner_Task_Id = Get'Caller then
                Use_Count := Use_Count + 1;
            else
                requeue Wait_for_Free with abort; -- Let any timeouts
expire.
            end if;
        end Get;

And Wait_for_Free looks like:

        entry Wait_for_Free when Use_Count = 0 is
        begin
            Owner_Task_Id := Wait_for_Free'Caller;
            Use_Count := 1;
        end Wait_for_Free;

           Randy Brukardt.





^ permalink raw reply	[relevance 5%]

* Suspicious reentrant semaphore
@ 2003-04-29 22:04  4% Jano
    2003-04-30 17:39  5% ` Randy Brukardt
  0 siblings, 2 replies; 138+ results
From: Jano @ 2003-04-29 22:04 UTC (permalink / raw)


Hello everybody,

I'm developing a multitasking program that runs OK for several hours. At 
some indeterminate moment, a bunch of its tasks cease to respond, and I 
have a strong suspicion that the culprit is a semaphore package I've 
done.

The purpose is to have a semaphore which can be called more than a time 
_by the same task_, and that must be released the same amount of times. 
Nested calls, simply.

Leaving aside why I have done that (yes, poor design, I'm removing it 
anyway ;-), I would like to know if my package is right or really is 
there some race condition. Please comment on it. I know that 
Current_Task shouldn't be called inside entries (in fact Gnat doesn't 
allow it, I tried :-P) but doesn't complain about it being used in 
barriers. Anyways, I have a (maybe wrong) feel about that being related 
to the deadlock.

Here are the spec and body:

P.s: I can guarantee that never use it without the controlled object, so 
no calls to V should occur without a previous P.

P.s: If it turns out that this isn't the culprit, I will amuse you ;-) 
with more samples of my code ^_^

Thanks!

------------SPEC---------------------------------------------------

package Adagio.Monitor is

   use Ada.Task_identification;
   
   protected type Semaphore is
      entry P (Owner : Task_id);
      entry V;
   private
      Caller : Task_id := Null_task_id;           -- Requester
      In_use : Natural := 0;                      -- Times requested
   end Semaphore;

   type Semaphore_access is access all Semaphore;

   -- Use: 
   -- S : aliased Semaphore;
   -- M : Object (S'access);
   type Object (S : access Semaphore) is new 
      Finalization.Limited_Controlled with null record;

   procedure Initialize (this : in out Object);
   procedure Finalize   (this : in out Object);

end Adagio.Monitor;

---------------------BODY----------------------------------

package body Adagio.Monitor is

   protected body Semaphore is

      entry P (Owner: Task_id) 
         when In_use = 0 or else Current_task = Caller is
      begin
         Caller := Owner;
         In_use := In_use + 1;
      end P;

      entry V when In_use > 0 and Current_task = Caller is
      begin
         In_use := In_use - 1;
      end V;

   end Semaphore;

   -- Get
   procedure Initialize (this : in out Object) is
   begin
      this.S.P (Current_task);
   end Initialize;

   -- Release
   procedure Finalize (this : in out Object) is
   begin
      this.S.V;
   end Finalize;

end Adagio.Monitor;

-- 
-------------------------
Jano
402450.at.cepsz.unizar.es
-------------------------



^ permalink raw reply	[relevance 4%]

* gnat Dynamic Priority Dispatching Anomalies
@ 2003-02-04 12:04  7% Ian Broster
  0 siblings, 0 replies; 138+ results
From: Ian Broster @ 2003-02-04 12:04 UTC (permalink / raw)


Hello

I've noticed some anomalies with dynamic priorites and task dispatching
with gnat 3.15p, using both FSU threads and the native (linux) threads. It
seems that the highest priority runnable task does not always execute.

I have produced a test program which demonstrates the problem.
Can someone explain whether it is my misunderstanding or
whether it is a compiler/runtime problem.

The test programs are below, but I've also bundled them together at 
http://www-users.cs.york.ac.uk/~ianb/pub/gnatdispatching.tgz

The program output (with FSU threads) is below.
The first number in each line is the (dynamic) base priority, 
the second field is the task ID.

So the question is: at lines 4 and 6, why is a low priority (1)
task running when there is a high priority task (15) still
ready to execute?

 15  main_task_080921A8  Main started
 15  t1_08092888  Before set_priority
 15  main_task_080921A8  t1 made
 1  t1_08092888  After set_priority
 15  t2_0809AE60  Before set_priority
 1  t1_08092888  After delay
 15  main_task_080921A8  t2 made
 1  t2_0809AE60  After set_priority
 1  t2_0809AE60  After delay

Thanks for any help

Ian Broster



Program and version information follows.

Compiler version: (binary distribution)
GNAT 3.15p  (20020523) Copyright 1996-2002 Free Software Foundation, Inc.

uname:
Linux x 2.4.18 #14 SMP Fri Aug 30 14:37:42 BST 2002 i686 unknown


with text_io; use text_io;
with tasks; use tasks;

procedure main is
	t1 : athread_p;
	t2 : athread_p;
begin
	info("Main started");
	t1 := new athread;
	info("t1 made");
	t2 := new athread;
	info("t2 made");
end main;

package tasks  is
	procedure info(s: string);

	task type athread;
	type athread_p is access athread;
end tasks;


with Ada.Dynamic_Priorities; 
with system; use system;
with text_io; use text_io;
with Ada.Task_Identification; 

package body tasks  is
	procedure info(s: string) is
	begin
		put(Integer'image(Ada.Dynamic_Priorities.Get_Priority));
		put("  " );
		put(
			Ada.Task_Identification.Image(
				Ada.Task_Identification.Current_Task)
		);
		put("  ");
		put_line(s);
	end info;
	
	task body athread is
	begin
		info("Before set_priority");
		Ada.Dynamic_Priorities.Set_Priority(priority'first+1);
		info("After set_priority");
		delay 0.0;
		info("After delay");
		loop
			delay 0.0;
		end loop;
	end athread;

end tasks;



^ permalink raw reply	[relevance 7%]

* Re: String library with garbage collection?
  @ 2003-01-10 11:35  5%         ` Craig Carey
  0 siblings, 0 replies; 138+ results
From: Craig Carey @ 2003-01-10 11:35 UTC (permalink / raw)


On Fri, 10 Jan 2003 03:52:13 GMT, "James S. Rogers"
<jimmaureenrogers@worldnet.att.net> wrote:
>"Craig Carey" <research@ijs.co.nz> wrote:
>> On Thu, 09 Jan 2003 20:46:45 GMT, "James S. Rogers" wrote:
...

>It is true that global constants are safe to access.
>

E.g. constant pointers in linked list of nodes where each node is
 labelled with a Task_Id. Task can simultaneously traverse it safely.

To add a new node, some safer scheme is used.

If tasks correctly identify their own node and only write to that, then
parallel update also does not need to be protected.

Checks to see which nodes are no longer used, also do not need to be
protected.

An idea is that the function to find the Task_Id,
 "Ada.Task_Identification.Current_Task ()", is faster than protected
objects (and that is true of the GNAT 3.15_ implementation):

   RM C.7.1 The Package Task_Identification
     http://www.adaic.org/standards/95aarm/html/AA-C-7-1.html


>Furthermore, pragma Atomic() is really only useful on a uniprocessor system.

I notice the correction.

>There is no way to check Task_Id's and update or read a linked list
>element atomically. This entails at least two reads, or a read and a write.

Those words "is no way" seems to be inconsistent with these words:

 "global constants [that] are safe to access".

...
>> RM 9.10 defines "erroneous":
>>    http://www.adaic.org/standards/95aarm/html/AA-9-10.html
>
>Read that definition again. "Erroneous" execution is not a desired
>behavior.


That would be rejected using this argument.

RM 9.10, does not actually have extra words to differentiate between the
"updating" of, and the "reading" of, the "global constants" (may need to
add the constraint that the variables be genuinely 'volatile' (updates
are actually done before the next read).

RM9.10(11) uses the word "or" to have the same constraints on both the
idea of reading and writing ("updating"), be applied in an atomic action:

  "Given an action of assigning to an object, and an action of
   reading or updating a part of the same object ... is erroneous
   unless ...".

I thought Mr Rogers was trying to nail down this group as holding a
desire of preferring to avoid owning erroneous programs. To keep the
thread shorter, some corrective statement is appropriate.

[I didn't see text in the RM saying that Task_Id's should be uniquely
assigned over the life of the program.]


PS. Correction: 0x2000 bytes = 8192 bytes


Craig Carey

Some Ada 95 mailing lists: http://www.ijs.co.nz/ada_95.htm






^ permalink raw reply	[relevance 5%]

* Re: stupid question: how can I finish a program?
  2002-08-14  6:41  7% ` stupid question: how can I finish a program? Emil Moholth
@ 2002-08-14 14:00  0%   ` Marin D. Condic
  0 siblings, 0 replies; 138+ results
From: Marin D. Condic @ 2002-08-14 14:00 UTC (permalink / raw)


That would be a good answer except that it doesn't work in all cases. It is
possible for tasks to be in a state where they can't be aborted. There are
corner cases in the language rules that will prevent the statement you show
from terminating the program.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com

Enabling Digital.
Our Vision is to be the biggest supplier worldwide of digital gateway
technology.
www.pacemicro.com

"Emil Moholth" <emil.moholth@kongsberg.com> wrote in message
news:3d59fb69@193.71.169.73...
>
> This is supported as part of the Annex C - Systems programming.
>
> C.7.1 (9) The effect of Abort_Task is the same as the abort_statement for
> the task identified by T. In addition, if T identifies the environment
task,
> the entire partition is aborted, See E.1
>
> So this leaves us with this single line in the main procedure.
>
> Ada.Task_Identification.Abort_Task (
>       T => Ada.Task_Identification.Current_Task );
>
> If some library unit maintains some persistent state extra measures is
> needed to ensure a correct state before executing the above statement. I
> would feel a lot more safe if I could ensure termination of all tasks in
the
> partition as part of the partition termination. Then the partition would
> terminate normally without any such statement.
>
> emilm
>
>





^ permalink raw reply	[relevance 0%]

* Re: stupid question: how can I finish a program?
       [not found]     <c923f575.0208130627.479e0b3d@posting.google.com>
  2002-08-14  6:41  7% ` stupid question: how can I finish a program? Emil Moholth
@ 2002-08-14  7:37  7% ` Martin Dowie
  1 sibling, 0 replies; 138+ results
From: Martin Dowie @ 2002-08-14  7:37 UTC (permalink / raw)


"drmed" <jonas.gasser@dataflow.ch> wrote in message
news:c923f575.0208130627.479e0b3d@posting.google.com...
> hi,
> Is there a function which quit/exit/end a program? -> whitout using
> the signals (like SIGINT ... etc).
> Only a one-line function.

I think this may have been covered in cla a few times (Dec 2000?)
but you could do something like:

package Program is

   procedure Kill;

end Program;

with Ada.Task_Identification; use Ada.Task_Identification;
package body Program is
   Environment_Task : Task_ID := Current_Task;

   procedure Kill is
   begin
      Abort_Task (T => Environment_Task);
   end Kill;
end Program;

then call "Program.Kill" from pretty much anywhere else in
your program.







^ permalink raw reply	[relevance 7%]

* Re: stupid question: how can I finish a program?
       [not found]     <c923f575.0208130627.479e0b3d@posting.google.com>
@ 2002-08-14  6:41  7% ` Emil Moholth
  2002-08-14 14:00  0%   ` Marin D. Condic
  2002-08-14  7:37  7% ` Martin Dowie
  1 sibling, 1 reply; 138+ results
From: Emil Moholth @ 2002-08-14  6:41 UTC (permalink / raw)



"drmed" <jonas.gasser@dataflow.ch> wrote in message
news:c923f575.0208130627.479e0b3d@posting.google.com...
> hi,
> Is there a function which quit/exit/end a program? -> whitout using
> the signals (like SIGINT ... etc).
> Only a one-line function.
> thanks
>
> jonas

This is supported as part of the Annex C - Systems programming.

C.7.1 (9) The effect of Abort_Task is the same as the abort_statement for
the task identified by T. In addition, if T identifies the environment task,
the entire partition is aborted, See E.1

So this leaves us with this single line in the main procedure.

Ada.Task_Identification.Abort_Task (
      T => Ada.Task_Identification.Current_Task );

If some library unit maintains some persistent state extra measures is
needed to ensure a correct state before executing the above statement. I
would feel a lot more safe if I could ensure termination of all tasks in the
partition as part of the partition termination. Then the partition would
terminate normally without any such statement.

emilm





^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23 13:02  4%               ` Marin David Condic
                                   ` (3 preceding siblings ...)
  2002-07-25  0:43  6%                 ` Robert Dewar
@ 2002-07-25  1:04  7%                 ` tmoran
  4 siblings, 0 replies; 138+ results
From: tmoran @ 2002-07-25  1:04 UTC (permalink / raw)


> hanging on socket I/O,
As others have pointed out, it's highly likely your tasks are stuck in
the OS blocking I/O somewhere.  But if you really want to kill this
program, what about the other programs/devices it's in communication
with?  Should they also be stopped or told nicely, or should they
just discover their interlocutor has closed his socket?



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23 13:02  4%               ` Marin David Condic
                                   ` (2 preceding siblings ...)
  2002-07-24 23:20  7%                 ` Dmitry A.Kazakov
@ 2002-07-25  0:43  6%                 ` Robert Dewar
  2002-07-25  1:04  7%                 ` tmoran
  4 siblings, 0 replies; 138+ results
From: Robert Dewar @ 2002-07-25  0:43 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> wrote in message news:<ahjk4d$5t5$1@nh.pace.co.uk>...
> Why don't the
> "terminate" alternatives work? You tell me.

No, you tell us why you think that terminate would do
something useful in this situation. I have no idea why
you would think this. Use the definition of terminate
in the RM to answer, not some vague intuition of what
it might mean.

Or perhaps you should write the exact code you have in
mind that does not "work". You postulate a compiler bug,
but I would be willing to bet this is a programmer misunderstanding!



^ permalink raw reply	[relevance 6%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23 13:02  4%               ` Marin David Condic
  2002-07-24  8:34  7%                 ` Lutz Donnerhacke
  2002-07-24  8:35  7%                 ` Fabien Garcia
@ 2002-07-24 23:20  7%                 ` Dmitry A.Kazakov
  2002-07-25  0:43  6%                 ` Robert Dewar
  2002-07-25  1:04  7%                 ` tmoran
  4 siblings, 0 replies; 138+ results
From: Dmitry A.Kazakov @ 2002-07-24 23:20 UTC (permalink / raw)


Marin David Condic wrote:

> A: I can't periodically poll because the subsidiary tasks in question are
> hanging on socket I/O, so they're considered "busy".

[If I correctly understand the problem] I suppose that if you close the 
socket file/handle from another task, then socket I/O should immediately 
end with an error, so the task will be able to accept "die_at_once" entry 
call.

-- 
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-24  8:34  7%                 ` Lutz Donnerhacke
@ 2002-07-24 13:58  6%                   ` Marin David Condic
  0 siblings, 0 replies; 138+ results
From: Marin David Condic @ 2002-07-24 13:58 UTC (permalink / raw)


Without trying to explain the whole design, this wouldn't be a good idea.
Polling in general is not something I want these tasks to be doing and any
attempt to introduce non-blocking I/O and/or polling amounts to a redesign.
If I'm going to redesign, then I'm going to redesign something different
that doesn't amount to just beating the existing design with a club until it
surrenders. :-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com


"Lutz Donnerhacke" <lutz@iks-jena.de> wrote in message
news:slrnajspk6.ok.lutz@taranis.iks-jena.de...
> * Marin David Condic wrote:
> >A: I can't periodically poll because the subsidiary tasks in question are
> >hanging on socket I/O, so they're considered "busy".
>
> Use async (or if not avail) non-blocking IO.





^ permalink raw reply	[relevance 6%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23 13:02  4%               ` Marin David Condic
  2002-07-24  8:34  7%                 ` Lutz Donnerhacke
@ 2002-07-24  8:35  7%                 ` Fabien Garcia
  2002-07-24 23:20  7%                 ` Dmitry A.Kazakov
                                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 138+ results
From: Fabien Garcia @ 2002-07-24  8:35 UTC (permalink / raw)


Marin David Condic wrote:

> A: I can't periodically poll because the subsidiary tasks in question are
> hanging on socket I/O, so they're considered "busy". Why don't the
> "terminate" alternatives work? You tell me. Compiler bug? Some kind of
> corner case in the rules regarding tasks? 

Are task able to abort while waiting for data on sockets ?
I'm still a bit new to Ada and sockets but in C you have non blocking 
calls that check for data being present on the socket and then returns 
with or without data. It might do the trick in your case.
(sorry this is only a guess)

Fabien




^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23 13:02  4%               ` Marin David Condic
@ 2002-07-24  8:34  7%                 ` Lutz Donnerhacke
  2002-07-24 13:58  6%                   ` Marin David Condic
  2002-07-24  8:35  7%                 ` Fabien Garcia
                                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 138+ results
From: Lutz Donnerhacke @ 2002-07-24  8:34 UTC (permalink / raw)


* Marin David Condic wrote:
>A: I can't periodically poll because the subsidiary tasks in question are
>hanging on socket I/O, so they're considered "busy".

Use async (or if not avail) non-blocking IO.



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-23  6:08  7%             ` tmoran
@ 2002-07-23 13:02  4%               ` Marin David Condic
  2002-07-24  8:34  7%                 ` Lutz Donnerhacke
                                   ` (4 more replies)
  0 siblings, 5 replies; 138+ results
From: Marin David Condic @ 2002-07-23 13:02 UTC (permalink / raw)


Q: Why is the OS call unsatisfactory?

A: Its not portable. While it might fix my immediate problem, in general I'd
prefer to have an Ada-only way of doing it rather than build the code to be
bound to Windows or Linux or whatever.

Q: Why can't you do aborts on each subsidiary task?

A: I'm not 100% sure that I am not dealing with a compiler bug. In the
current subsystem, I've built code that *should* (if I understand it
correctly) abort the tasks, but apparently is not. (And its way too much
code to post here and by the time I trimmed it down to a simple enough test
case that still demonstrated it, I probably could restructure the whole
thing to work differently, so no, I'm not interested in trying to debug this
one, but rather find a workaround or do a redesign.) Also, at the point
where I know I want to terminate the program, I don't have direct visibility
to the tasks in question since they are safely stored in a subsystem to do
all those wonderful buzzwords like "Information Hiding" and "Encapsulation".
So my call into the subsystem to abort the tasks is failing to do so and the
practical answer is "Just Kill The Program..." I'll probably eventually
figure out a different structure for the subsystem since I'd like to reuse
it, but I'd like to have a good quick fix for the problem now that won't
require a redesign.

Q: Why don't "terminate" alternatives or periodic polling of a global
"please_die" variable do the job?

A: I can't periodically poll because the subsidiary tasks in question are
hanging on socket I/O, so they're considered "busy". Why don't the
"terminate" alternatives work? You tell me. Compiler bug? Some kind of
corner case in the rules regarding tasks? I *thought* they should be able to
shut down and I did build in aborts and no, they just refuse to die. So my
choices became these: 1) Study it to death to try to figure out exactly why
the current heierarchy of tasks won't die. 2) Do a redesign so that the
structure is fundamentally changed & may allow for a different method of
shutting everything down. 3) Find a way to just shoot the whole process in
the head and be done with the immediate problem. I was trying to work on
option 3. Probably, the next most efficient answer is to go to option 2
since doing option 1 is likely to lead to option 2 anyway. Being an engineer
rather than a scientist, I just want to get close enough to get the job
done. :-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com


<tmoran@acm.org> wrote in message
news:bp6%8.26322$eU7.31933571@newssvr14.news.prodigy.com...
> > if Ada provided a standard way of accomplishing this.
>   Could you give more detail about the situation?  Why is the OS
> call unsatisfactory for the no-finalization-needed case?  Why can't
> you do aborts on each subsidiary task?  Why don't "terminate"
> alternatives or periodic polling of a global "please_die" variable
> do the job?





^ permalink raw reply	[relevance 4%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-22 12:53  5%           ` Marin David Condic
@ 2002-07-23  6:08  7%             ` tmoran
  2002-07-23 13:02  4%               ` Marin David Condic
  0 siblings, 1 reply; 138+ results
From: tmoran @ 2002-07-23  6:08 UTC (permalink / raw)


> if Ada provided a standard way of accomplishing this.
  Could you give more detail about the situation?  Why is the OS
call unsatisfactory for the no-finalization-needed case?  Why can't
you do aborts on each subsidiary task?  Why don't "terminate"
alternatives or periodic polling of a global "please_die" variable
do the job?



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-20 17:18  6%         ` Robert A Duff
@ 2002-07-22 12:53  5%           ` Marin David Condic
  2002-07-23  6:08  7%             ` tmoran
  0 siblings, 1 reply; 138+ results
From: Marin David Condic @ 2002-07-22 12:53 UTC (permalink / raw)


Yeah, in this particular instance, it really is just a matter of killing the
whole process and not worrying about finalization or the state of anything.
The OS should be able to clean up anything that matters and I just want the
program to stop. Obviously, this sort of thing could be very dangerous in
the wrong setting because you do avoid finalization and there might be cases
where things would be left in an unknown state. (Files not being properly
updated, for example.) But its not an uncommon need even in embedded
computers. Sometimes you might find yourself in some sort of corrupt state
and the easiest answer is to double-stroke the watchdog timer and force the
computer into a reset that re-initializes the whole thing. It would be nice
if Ada provided a standard way of accomplishing this.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wcc8z46pbcl.fsf@shell01.TheWorld.com...
>
> But note that with such a feature, whatever finalization actions you
> wrote will be skipped.  (If they aren't skipped, then the feature
> doesn't do what you said above, because finalization might loop.)
> If you're running on a real operating system, it might be perfectly OK
> to skip finalization, since the OS has to clean up anyway.
>






^ permalink raw reply	[relevance 5%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-19 12:55  5%       ` Marin David Condic
@ 2002-07-20 17:18  6%         ` Robert A Duff
  2002-07-22 12:53  5%           ` Marin David Condic
  0 siblings, 1 reply; 138+ results
From: Robert A Duff @ 2002-07-20 17:18 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> writes:

> Fair enough. I'm going to have to review the code in question when I get a
> chance to revisit it (back to being busy with "real" work...:-) They may be
> hanging on some abort-defer region as you suggest, but it would be simpler
> to have some kind of "Kill this process and I really, really mean it!"
> command.

Well, you can call "exit" via pragma Import.  I agree that it would be
nice to have such a feature as a standard part of the language.

But note that with such a feature, whatever finalization actions you
wrote will be skipped.  (If they aren't skipped, then the feature
doesn't do what you said above, because finalization might loop.)
If you're running on a real operating system, it might be perfectly OK
to skip finalization, since the OS has to clean up anyway.

- Bob



^ permalink raw reply	[relevance 6%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-18 21:32  7%     ` Robert A Duff
@ 2002-07-19 12:55  5%       ` Marin David Condic
  2002-07-20 17:18  6%         ` Robert A Duff
  0 siblings, 1 reply; 138+ results
From: Marin David Condic @ 2002-07-19 12:55 UTC (permalink / raw)


Fair enough. I'm going to have to review the code in question when I get a
chance to revisit it (back to being busy with "real" work...:-) They may be
hanging on some abort-defer region as you suggest, but it would be simpler
to have some kind of "Kill this process and I really, really mean it!"
command. The situation is such that you've got tasks that are off doing
something - mostly standing around waiting for things to come across the
network - and the operator goes "Shut down the server...". In this instance,
you don't much care what the other threads are up to (no critical database
updates or something like that) and you just want the program to quit. I
should probably revisit the design and see if maybe there's a better way to
control the shutdown.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wccofd4lo1p.fsf@shell01.TheWorld.com...
>
> Aborts don't happen right away -- aborts can be deferred.  When you
> abort the env task, all the other tasks in the hierarchy get aborted
> too, and the env tasks waits for them to terminate.  Perhaps one of your
> tasks is in an abort-deferred region, and looping forever, or waiting
> forever for something.  That would cause the env task to wait forever.
>






^ permalink raw reply	[relevance 5%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-15 12:52  5%   ` Marin David Condic
  2002-07-15 23:31  7%     ` tmoran
@ 2002-07-18 21:32  7%     ` Robert A Duff
  2002-07-19 12:55  5%       ` Marin David Condic
  1 sibling, 1 reply; 138+ results
From: Robert A Duff @ 2002-07-18 21:32 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> writes:

> After some additional experimentation, it seems like maybe I've tripped
> across some kind of compiler bug or other unusual condition.

Aborts don't happen right away -- aborts can be deferred.  When you
abort the env task, all the other tasks in the hierarchy get aborted
too, and the env tasks waits for them to terminate.  Perhaps one of your
tasks is in an abort-deferred region, and looping forever, or waiting
forever for something.  That would cause the env task to wait forever.

- Bob



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-12 17:13 12% Ada.Task_Identification.Abort_Task (Environment_Task) ; Marin David Condic
  2002-07-13 13:45  6% ` Simon Wright
  2002-07-13 14:12  6% ` Robert A Duff
@ 2002-07-16 20:43 13% ` Simon Wright
  2 siblings, 0 replies; 138+ results
From: Simon Wright @ 2002-07-16 20:43 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> writes:

> I'm trying to make a call to Ada.Task_Identification.Abort_Task
> (Environment_Task) ; using the Gnat 3.14p compiler on WindowsNT.

I'm not sure what Environment_Task is, but here I've used
Ada.Task_Identification.Current_Task from the main program with no
problems.



^ permalink raw reply	[relevance 13%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-15 12:52  5%   ` Marin David Condic
@ 2002-07-15 23:31  7%     ` tmoran
  2002-07-18 21:32  7%     ` Robert A Duff
  1 sibling, 0 replies; 138+ results
From: tmoran @ 2002-07-15 23:31 UTC (permalink / raw)


>to a different point in the code where I don't have a specific set of
>tasks running and it aborts just fine. After I get these tasks started, the
>abort has no effect.
  Perhaps the environment task is just "waiting for the termination of
dependent tasks" 9.8(8)?



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-13 14:12  6% ` Robert A Duff
@ 2002-07-15 12:52  5%   ` Marin David Condic
  2002-07-15 23:31  7%     ` tmoran
  2002-07-18 21:32  7%     ` Robert A Duff
  0 siblings, 2 replies; 138+ results
From: Marin David Condic @ 2002-07-15 12:52 UTC (permalink / raw)


After some additional experimentation, it seems like maybe I've tripped
across some kind of compiler bug or other unusual condition. I can move the
abort to a different point in the code where I don't have a specific set of
tasks running and it aborts just fine. After I get these tasks started, the
abort has no effect. So whatever is going on, it probably isn't a case of my
not getting the right stuff together in the build process.

Is there any other way of shooting the whole process in the head? It might
be easier to find an alternative than it is to try to sort out a rather
complex set of tasks to create a sufficiently simple demonstration of the
bug. (And there's no telling if it would be readily fixable, so maybe a
workaround is good enough. The entire rest of the code works just fine and
I'm just trying to terminate the program where some tasks may be hung
waiting for data on sockets.)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wccznwvzpgl.fsf@shell01.TheWorld.com...
>
> I used the -gnatP switch to compile one program I wrote.  I don't think
> I had to do anything to get it to include the right parts of the
> run-time system (other than giving the switch on the command line).
>
> And I *think* I used an abort to kill the whole program,
> and it worked properly on Windows and Solaris and Linux.
> (Not sure about that -- I could be misremembering.)
>
> I presume Environment_Task is what its name implies?
>
> Another way is to pragma-import "exit", and call that.
> But be sure you understand whether that will do finalization,
> and whether you want it to.
>
> - Bob





^ permalink raw reply	[relevance 5%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-13 13:45  6% ` Simon Wright
@ 2002-07-13 22:12  7%   ` Robert Dewar
  0 siblings, 0 replies; 138+ results
From: Robert Dewar @ 2002-07-13 22:12 UTC (permalink / raw)


Simon Wright <simon@pushface.org> wrote in message news:<x7v8z4f4u7d.fsf@pushface.org>...
> The 4wexcpol.adb (and other files with numeric prefixes) 
> contain variants, using a naming scheme I've never tried 
> to understand

Nothing to understand there, just look at the lists of
files in the makefile, and it is quite clear what is going
on for each target.



^ permalink raw reply	[relevance 7%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-12 17:13 12% Ada.Task_Identification.Abort_Task (Environment_Task) ; Marin David Condic
  2002-07-13 13:45  6% ` Simon Wright
@ 2002-07-13 14:12  6% ` Robert A Duff
  2002-07-15 12:52  5%   ` Marin David Condic
  2002-07-16 20:43 13% ` Simon Wright
  2 siblings, 1 reply; 138+ results
From: Robert A Duff @ 2002-07-13 14:12 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> writes:

> I'm trying to make a call to Ada.Task_Identification.Abort_Task
> (Environment_Task) ; using the Gnat 3.14p compiler on WindowsNT. It is
> failing to terminate the program. From looking at the documentation for:
> pragma Polling and the -gnatP switch, its looking like I've got to do
> something special to get this to work. A package body: 4wexcpol.adb seems to
> be mentioned, but it is not clear how to get this included in the build. Can
> anyone offer some advice on how to get the Abort_Task to kill the whole
> program on demand? Thanks.

I used the -gnatP switch to compile one program I wrote.  I don't think
I had to do anything to get it to include the right parts of the
run-time system (other than giving the switch on the command line).

And I *think* I used an abort to kill the whole program,
and it worked properly on Windows and Solaris and Linux.
(Not sure about that -- I could be misremembering.)

I presume Environment_Task is what its name implies?

Another way is to pragma-import "exit", and call that.
But be sure you understand whether that will do finalization,
and whether you want it to.

- Bob



^ permalink raw reply	[relevance 6%]

* Re: Ada.Task_Identification.Abort_Task (Environment_Task) ;
  2002-07-12 17:13 12% Ada.Task_Identification.Abort_Task (Environment_Task) ; Marin David Condic
@ 2002-07-13 13:45  6% ` Simon Wright
  2002-07-13 22:12  7%   ` Robert Dewar
  2002-07-13 14:12  6% ` Robert A Duff
  2002-07-16 20:43 13% ` Simon Wright
  2 siblings, 1 reply; 138+ results
From: Simon Wright @ 2002-07-13 13:45 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> writes:

> I'm trying to make a call to Ada.Task_Identification.Abort_Task
> (Environment_Task) ; using the Gnat 3.14p compiler on WindowsNT. It
> is failing to terminate the program. From looking at the
> documentation for: pragma Polling and the -gnatP switch, its looking
> like I've got to do something special to get this to work. A package
> body: 4wexcpol.adb seems to be mentioned, but it is not clear how to
> get this included in the build. Can anyone offer some advice on how
> to get the Abort_Task to kill the whole program on demand? Thanks.

This technique worked for us out of the box with no special
switches. OK, it was 3.14a1 to start with and now 3.15a1 .. but as I
say, no trouble.

The 4wexcpol.adb (and other files with numeric prefixes) contain
variants, using a naming scheme I've never tried to understand, which
are selected and renamed by the GNAT build process. So I would expect
you to have the right one for your platform already.



^ permalink raw reply	[relevance 6%]

* Ada.Task_Identification.Abort_Task (Environment_Task) ;
@ 2002-07-12 17:13 12% Marin David Condic
  2002-07-13 13:45  6% ` Simon Wright
                   ` (2 more replies)
  0 siblings, 3 replies; 138+ results
From: Marin David Condic @ 2002-07-12 17:13 UTC (permalink / raw)


I'm trying to make a call to Ada.Task_Identification.Abort_Task
(Environment_Task) ; using the Gnat 3.14p compiler on WindowsNT. It is
failing to terminate the program. From looking at the documentation for:
pragma Polling and the -gnatP switch, its looking like I've got to do
something special to get this to work. A package body: 4wexcpol.adb seems to
be mentioned, but it is not clear how to get this included in the build. Can
anyone offer some advice on how to get the Abort_Task to kill the whole
program on demand? Thanks.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com






^ permalink raw reply	[relevance 12%]

* Re: How do I end the program?
  2002-02-06  7:46  0%   ` Dale Stanbrough
@ 2002-02-06  8:40  0%     ` Martin Dowie
  0 siblings, 0 replies; 138+ results
From: Martin Dowie @ 2002-02-06  8:40 UTC (permalink / raw)


> > In the main procedure of your program, before entering glutMainLoop save
off
> > the task ID of the environment task.
> >
> >   env_task_id := Ada.Task_Identification.Current_Task;
> >
> > When you want to kill the program call:
> >
> >   Ada.Task_Identification.Abort_Task( env_task_id );
> >
> > When you kill the environment task, all subordinate tasks are terminated
as
> > well.
> >
> > With GNAT 3.14p, I get the message:
> >   Execution terminated by abort of environment task
> >
> > On the console window of my test program.
>
> Well, i'm not sure that would work. What if one of the tasks is
> a library level task, i.e. declared and elaborated in a library
> level package? I'm not sure that there is a "parent" task in that
> case.

This was covered circa nov/dec 2000 and the above solution was
proposed with the slight twist of "env_task_id" being a package
level variable assigned during elaboration. The rationale then
was that all elaboration occurs within the scope of the environment
task.

Can't remember who put forward the example - I have a feeling they
had a french sounding name though! :-)





^ permalink raw reply	[relevance 0%]

* Re: How do I end the program?
  2002-02-06  3:16  8% ` Steve Doiel
@ 2002-02-06  7:46  0%   ` Dale Stanbrough
  2002-02-06  8:40  0%     ` Martin Dowie
  0 siblings, 1 reply; 138+ results
From: Dale Stanbrough @ 2002-02-06  7:46 UTC (permalink / raw)


Steve Doiel wrote:

> In the main procedure of your program, before entering glutMainLoop save off
> the task ID of the environment task.
> 
>   env_task_id := Ada.Task_Identification.Current_Task;
> 
> When you want to kill the program call:
> 
>   Ada.Task_Identification.Abort_Task( env_task_id );
> 
> When you kill the environment task, all subordinate tasks are terminated as
> well.
> 
> With GNAT 3.14p, I get the message:
>   Execution terminated by abort of environment task
> 
> On the console window of my test program.

Well, i'm not sure that would work. What if one of the tasks is 
a library level task, i.e. declared and elaborated in a library
level package? I'm not sure that there is a "parent" task in that
case.


Dale



^ permalink raw reply	[relevance 0%]

* Re: How do I end the program?
  @ 2002-02-06  3:16  8% ` Steve Doiel
  2002-02-06  7:46  0%   ` Dale Stanbrough
  0 siblings, 1 reply; 138+ results
From: Steve Doiel @ 2002-02-06  3:16 UTC (permalink / raw)


Yes, but it isn't pretty.

Take a look at the module: Ada.Task_Identification.

In the main procedure of your program, before entering glutMainLoop save off
the task ID of the environment task.

  env_task_id := Ada.Task_Identification.Current_Task;

When you want to kill the program call:

  Ada.Task_Identification.Abort_Task( env_task_id );

When you kill the environment task, all subordinate tasks are terminated as
well.

With GNAT 3.14p, I get the message:
  Execution terminated by abort of environment task

On the console window of my test program.

SteveD

"David Starner" <dvdeug@x8b4e53cd.dhcp.okstate.edu> wrote in message
news:a3n4mj$9qe1@news.cis.okstate.edu...
> How do I exit the program? It may seem like a silly question, but I'm
> trying to exit from a function called from a callback written in C, so I
> can't just return or raise an exception. glutMainLoop never returns, so
> I can't run off the end of the main function. I used
> GNAT.OS_Lib.OS_Exit. Is there a pure Ada alternative?
>
> --
> David Starner - starner@okstate.edu, dvdeug/jabber.com (Jabber)
> Pointless website: http://dvdeug.dhis.org
> What we've got is a blue-light special on truth. It's the hottest thing
> with the youth. -- Information Society, "Peace and Love, Inc."





^ permalink raw reply	[relevance 8%]

* ACT announces availability of GNAT 3.14p
@ 2002-01-31  2:49  1% Robert Dewar
  0 siblings, 0 replies; 138+ results
From: Robert Dewar @ 2002-01-31  2:49 UTC (permalink / raw)


Ada Core Technologies (ACT) has made available at the NYU
site (ftp://cs.nyu.edu/pub/gnat) GNAT 3.14p builds for the
following targets:

MS Windows (NT/2K)
Sparc Solaris (2.5.1 through 2.8)
GNU Linux (Redhat 6.2)

The above are the official platforms, but in practice the
NT version works reasonable well on Win 98 and Win ME and
other versions of GNU Linux including Debian GNU/Linux are
known to be compatible with this version of GNAT.

These are the only public versions that ACT plans to build.
As always, the releases contain the full sources, and we
invite volunteers to create builds for other platforms.  We
also draw attention to the availability of source snapshots
for the current development version of GNAT (similar to the
3.15 release, but on GCC 3, rather than GCC 2).  The above
public versions are still based on ACT's 2.8.1 GCC version.

These versions are provided without any warranty or
guarantee of any kind, and no support of any kind is
available for these public versions from ACT.  They are
provided as a service for use by students, hobbyists and
researchers who need access to a high quality Ada 95
system.

If you need a supported commercial Ada 95 compiler, we
recommend the use of our GNAT Pro product.  In particular,
we do not recommend the use of the public version for
formal evaluation purposes. Contact sales@gnat.com
or sales@act-europe.fr for further details on GNAT Pro, 
including the availability of evaluation versions.

Robert Dewar
Ada Core Technologies


The following is a list of new features available in 3.14
as compared with 3.13.

GNAT 3.14p NEW FEATURES LIST
============================

Copyright (c) 2001, Ada Core Technologies

This file contains a complete list of new features in
version 3.14p of GNAT.  A full description of all GNAT
features can be found in the GNAT User Guide and GNAT
Reference Manual.

NF-314-5827-001 New -u switch for gnatmake

The command gnatmake -u only recompiles the main file when
needed.  Gnatmake can now be used as the main and only
interface to the compiler since a single compilation can be
launched with "gnatmake -u -f".

NF-314-6806-001 Source reference pragmas read by gnatchop

The gnatchop utility now recognizes and respects existing
source reference pragmas that it finds in the input file,
so that the output files always properly reflect the
original source file.

NF-314-6813-011 Asis queries to evaluate static expressions

A new set of queries is added to package Asis.Extensions.
These queries allows an ASIS application to evaluate the
value of a discrete static expressions and to get the low
and high bound of a static 'Range attribute.  The results
are returned as string images of expression values, The
'Pos value is returned for enumeration expressions.  See
specification of Asis.Extensions for more details.

NF-314-7001-006 Better messages on non-visible entities

The warnings for non-visible entities have been improved to
exclude implicit entities, and entities declared in the
private part of GNAT internal units.  This results in more
helpful error messages for undefined variables.

NF-314-7008-003 New package GNAT.Sockets

This package provides a high level interface to the sockets
API.  Most of the features are implemented.  This high
level and portable interface is based on the
GNAT.Sockets.Thin API which is a thin binding to the OS
sockets API.

NF-314-7110-008 New package GNAT.Most_Recent_Exception

This package provides subprograms giving access to the
exception occurrence, or exception occurrence access for
the most recently raised exception.  Unlike the routines in
GNAT.Current_Exceptions, these routines do not have to be
called statically from within an exception handler.

NF-314-7207-004 Issue error for bad Source_Reference pragma

The Source_Reference pragma is (and always has been)
required to be the first line of the file.  This is now
clearly documented, and a diagnostic is issued if the first
Source_Reference pragma is not the first line in the file.

NF-314-7207-006 Warn when Duration unexpectedly used

A new warning has been added when a universal fixed
expression is interpreted as type Standard.Duration.
Although this is correct according to RM semantics, it is
almost always suspicious and represents an unintended
meaning.

NF-314-7215-008 Improve msg for missing WITH of predef unit

The error message handling for cases of forgotten WITH's of
predefined library routines has been improved.

NF-314-7314-004 Remove useless initialization checks

Initialization procedures for arrays were doing unnecessary
subscript range checks, that have now been suppressed,
since an out of range condition is impossible in this
context.

NF-314-7418-008 New switch for gnatchop to exit on errors

The new -x gnatchop switch causes gnatchop to exit on
detecting parse errors.  Now gnatchop also sets the exit
status to indicate errors.

NF-314-7506-010 Improve message for access param comparison

A comparison of an access parameter with null is illegal.
This was always caught by GNAT but with a confusing error
message that complained about the types of the operands.
Now a specific error mesage is given pointing out that it
is not allowed for an access parameter to be null in the
first place.

NF-314-7509-002 Improve warning for possibly null values

The warning for possibly null values has been improved to
be more precise and to catch some previously uncaught
cases.

NF-314-7515-007 Multiple Source_Reference pragmas allowed

It is now permitted for a single file to have more than one
Source_Reference pragma.  All pragmas must refer to the
same original file, but the sections referenced need not be
contiguous.  This permits correct processing of files with
configuration pragmas that are chopped using gnatchop with
the -c and -r switches.

NF-314-7516-012 Better warning messages for Storage_Error

In some cases, a warning about possible storage error was
posted on the offending statement in a generic template.
Now the message is always on the relevant instantiation
with a pointer to the generic template location.

NF-314-7524-009 GNAT version string is in executable

The executable now contains a string identifying the GNAT
version in the form "GNAT Version:  xxx(xxx)" where
xxx(xxx) is the version number.  The external name of this
constant is __gnat_version.

NF-314-7530-009 Consistency checking for -gnatE mode

Units compiled with -gnatE and without -gnatE can be mixed
under certain conditions, now properly documented in the
GNAT Users Guide.  The binder now checks that the rules for
safe mixing are properly followed.

NF-314-7606-012 Improve equality ambiguity error messages

In the case of ambiguous operands for equality, -gnatf now
gives details on the possible resolutions discovered by the
compiler, making it easy to diagnose the cause of this
error in non-obvious situations.

NF-314-7607-007 Improved control for NT temporary files

Under NT, it is now possible to control where temporary
files are created.  First, the TMP environment variable is
checked, and if this is set, it specifies the directory to
be used.  If TMP is not set, then c:\temp is used.  If both
of these checks fail, then, and only then, is the current
working directory used.

NF-314-7611-007 Warnings for WITH of internal GNAT unit

The only units that should be WITH'ed by application
programs are those that are documented in the RM or in the
GNAT documentation.  Any WITH of an internal GNAT
implementation unit not documented in one of these two
locations now generates a warning.  This warning can be
controlled individually by use of the -gnatwi/-gnatwI
switches.  It is on by default.

NF-314-7614-005 Avoid use of a-types.h in runtime

The use of a-types.h is now avoided in building the runtime
library.  This reduces unnecessary symbol table and debug
information

NF-314-7619-008 Access to source related information

A new package GNAT.Source_Info provides some useful utility
subprograms that provide access to source code informations
known at compile time, such as file name, line number and
enclosing entity.

NF-314-7620-002 More flexible source file naming

The Source_File_Name pragma has been enhanced so that it
can provide general pattern driven rules for constructing
file names.  The scheme is powerful enough to accomodate
all common schemes for deriving file names from unit name
that we are aware of, and in particular it supports
standard schemes used by other Ada 95 compilers.  This
means that for most purposes the large set of
Source_File_Name pragmas can be replaced by two pragmas,
giving pattern rules for bodies and specs.

NF-314-7622-004 New packages for CGI programming

A new package GNAT.CGI provides basic services for CGI
(Common Gateway Interface) programming.  A subsidiary
package GNAT.CGI.Cookies provides facilities for dealing
with "cookies" (data kept in Web client software).  A third
package GNAT.CGI.Debug provides debugging facilities.
Between them, these packages enable an easy interface for
Web programming from Ada.

NF-314-7626-013 Automatic backtraces during exception
handling

A new package GNAT.Exception_Traces is now available for
platforms on which the backtrace features is implemented.
This provides a feature for enabling automatic output of
backtraces upon exception occurrences.  Two options are
available, enabling traces either for every occurrence or
only for occurrences that are not caught by a user defined
handler.  The latter is typically useful to get traces when
a task dies because of an unhandled exception.
 
NF-314-7708-001 New Setenv procedure in GNAT.OS_Lib.

A procedure Setenv has been added in GNAT.OS_Lib.  This
procedure can be used to add or remove environment
variables for the current and child process.  This is not
yet supported under VMS, but is fully supported for all
other GNAT ports.

NF-314-7709-004 New unit GNAT.AWK (AWK style file parsing)

A new package GNAT.AWK (file g-awk.ads) provides AWK-like
file parsing with an easy interface for parsing one or more
files containing formatted data.  The file is viewed as a
database where each record is a line and a field is a data
element in this line.

NF-314-7711-001 New function Paren_Count in GNAT.Regpat

A new function Paren_Count is now provided in GNAT.Regpat
to return the maximum number of parentheses pairs in the
compiled regular-expression.

NF-314-7712-005 Support for honoring gcc -fno-common

The -fno-common gcc command line option is now recognized.
The use of this option causes the allocation of
uninitialized global variables to be moved to the bss
section of the object file, rather than generating them as
common blocks.  This solves problems caused by the presence
of a symbol both in a library and in an explicitly linked
object file.

NF-314-7713-002 Improved error message placement

The error message noting that only subtype marks can be
used in a generic array formal are now more accurately
placed and point specifically to the offending construct.

NF-314-7713-003 Front-end inlining

The -gnatN switch enables front-end inlining.  In this
compilation mode, the front-end replaces a call to a
subprogram that has an Inline pragma by the expanded body
of the subprogram, provided the body is short enough.  This
supplements the inlining performed by the GCC back-end.

NF-314-7717-001 Task_Name pragma provided to set task name

A new pragma Task_Name can be used in a task definition to
specify the name used for a task for debugging purposes and
by Ada.Task_Identification.Image.  The argument is the task
name, and can be an expression referencing the task
discriminants, allowing different names to be given to
different instances of the same task type.
 
NF-314-7718-001 Linker_Options extensions now documented

The documentation (GNAT Reference Manual) has been enhanced
to contain full documentation of the GNAT implementation of
the Linker_Options pragma.  GNAT allows multiple arguments,
and also allows the use of ASCII.NUL to separate arguments
in a single string.

NF-314-7718-003 New warning option to detect hiding

New flags -gnatwh/-gnatWH are provided to enable/disable
checking for the case where an inner entity hides an outer
one.  This is of course legal, but in some environments
such hiding is discouraged, and this warning option (which
is by default off) can be used to enforce this requirement.
Note that the common case of one character identifiers such
as I,J,K is excluded from consideration.

NF-314-7721-002 Improved range analysis for subtraction

The circuit for range analysis for subtraction has been
enhanced.  This eliminates some range checks, and some
additional warnings at compile time for cases where the
result is known to be out of range.

NF-314-7721-003 Implement range analysis 'Length

Range analysis for the Length attribute has been added,
resulting in elimination of some range checks, and also
some additional warnings at compile time for cases where
the result is known to be out of range

NF-314-7722-016 Improved error msg for name conflict

The error message for a conflict between an enumeration
literal and a later declared constant of the same name has
been improved.

NF-314-7723-005 GLIDE xref works even if compile errors

The new switch -gnatQ can be used to force generation of an
ALI file even if there are compile errors.  This is most
useful in connection with GLIDE and similar tools, since it
means that cross-reference information is available even
after compiler errors.

NF-314-7723-012 Unreferenced labels generate warnings

In -gnatwu mode, GNAT now diagnoses labels that are not
referenced other than by their initial occurrence.

NF-314-7731-012 New unit GNAT.Dynamic_Tables

A new package GNAT.Dynamic_Tables provides a resizable
one-dimensional array.  It is similar to GNAT.Table except
that the table type is a declared type, so that it can be
used in more general contexts.

NF-314-7801-005 Warning for aliased discriminanted objects

GNAT now generates a warning for an assignment to an
aliased discriminated object that is known to generate a
constraint error at run time.

NF-314-7802-002 GLIDE can go to any file in error message

When an error message from the compiler includes several
file:line references, it is now possible to click on any of
them to display the appropriate file, instead of just the
first one.

NF-314-7814-013 x86 stack traceback for foreign threads

Under x86 targets it is possible to get the stack traceback
through a foreign thread.  This is true for unhandled
exceptions and for GNAT.Traceback services.

NF-314-7817-001 GNAT now compatible with Solaris 2.8

GNAT is now fully compatible with Solaris 2.8.  This
includes proper building and operation of the florist
package (which did need some modifications to be 2.8
compatible).

NF-314-7820-008 Better 'Valid handling for large subtypes

If an object of a discrete type has a larger size than the
base type (e.g.  from the use of a component clause in a
record representation clause), then 'Valid will check all
the bits of the object (previously the code simply use part
of the field, which was an allowable implementation
according to the RM, but nevertheless surprising).

NF-314-7821-010 ASIS tutorial is available

A simple hands-on ASIS tutorial is added to the ASIS
distribution.  It consists of two parts.  One part is based
on the asistant tool and the task is to get the initial
experience with using ASIS queries.  Another part is based
on the ASIS application templates and the task is to
implement simple ASIS tools starting from these templates.
For all the tasks full documented solutions are provided.

NF-314-7821-008 ASIS application templates are available

A set of ASIS application templates is added as a part of
the ASIS distribution.  This set contains the Ada
components which are the same or very similar for many
ASIS-based tools.  These templates may be used as a "quick
start" for ASIS beginners.

NF-314-7822-009 Dynamic elaboration checks improved

Elaboration checks are suppressed for calls to subprograms
in packages to which a pragma Elaborate applies.  The cases
of Elaborate_All and Elaborate_Body already suppressed the
check, but checks were not suppressed for Elaborate.

NF-314-7826-009 gnatdll supports binder arguments

Gnatdll now supports the -bargs parameter passing arguments
to the binder.  For example, this can be used to build a
DLL with stack tracebacks stored in the exception
occurences (gnatbind -E option).

NF-314-7826-010 pragma Comment restriction removed

The placement of pragma Comment is now unrestricted.  This
pragma can appear anywhere within the main unit, including
as the first line of the file.

NF-314-7827-011 Control of warnings for address overlays

The warning switch -gnatwo turns on overlay warnings for
address clauses where implict initialization can cause the
overlaid memory to be clobbered.  The swich -gnatwO turns
off these warnings.  The warnings have been implemented for
a while.  What is new is allowing them to be selectively
turned off (the default is that this warning is enabled).

NF-314-7829-002 Control over validity checking is provided

GNAT now provides a new switch -gnatVx that allows you to
control the level of validity checking.  The options are
n/d/f for none/default/full.  None means no checking for
invalid data, default (which is the default setting)
provides sufficient checking to meet the requirements of
the RM, and full provides extensive validity checking,
particularly useful when used with Normalize_Scalars.

NF-314-7829-003 New warning for hiding loop variables

A common mistake for those familiar with other languages is
to fail to realize that a for loop implicitly declares the
loop variable, and programmers provide a useless and unused
outer level variable definition with the same name.  GNAT
now specifically detects this situation and provides an
explicit warning.

NF-314-7830-008 ASIS Corresponding_Name_Definition_List

The Asis.Expressions.Corresponding_Name_Definition_List
query in ASIS for GNAT is now fully implemented.

NF-314-7830-014 New warning for overlay by access type

The warning for possible unexpected initialization has been
extended to include access types.  The warning is generated
if an access type has an address clause causing overlay,
and there is no pragma Import, so that initialization to
null will take place.  Note that NF-314-7827-011 gives the
capability of controlling such warnings.  Note also that
GNAT 3.13p had a (now corrected error) that caused such
expected initializations to be omitted.

NF-314-7906-017 New package Ada.Interrupts.Signal

A new package Ada.Interrupts.Signal (file a-intsig.ads) has
been created to provide an easier and more portable way of
generating Ada95 interrupts.

NF-314-7910-004 Uniform behavior for Slice subprograms

In packages Ada.Strings.Bounded/Ada.Strings.Unbounded, the
Slice function now returns with the bounds of the slice
expressions, rather than with a lower bound of 1. This was
discussed in the ISO WG9 ARG, and it was agreed that this
was the preferable approach.  This change also improves the
efficiency of these two functions.

NF-314-7914-009 Optimization for object declarations

If an object is declared with an unconstrained nominal type
and the expression is a function call, it is in general
necessary to compute the result of the call first and then
copy that result into the object, after deter- mining the
bounds.  GNAT now suppresses that copy in many cases.  The
copy is still used if the type is controlled, if it is
classwide, or if the object is declared at the library
level.

NF-314-7918-012 Enhanced variant of Spawn in GNAT.OS_Lib

In the package GNAT.OS_Lib, a new Spawn function now
returns the exit status of the executed command as an
Integer value.  The existing Spawn procedure only gives a
boolean result.

NF-314-7924-003 Immediate output switch (-gnate) replaced

The immediate output switch -gnate is no longer defined,
reflecting the fact that this is intended only for use in
diagnostic mode following a compiler crash.  In those cases
where this is needed, the effect can be obtained by use of
the -gnatdO debug switch.  The purpose of this change is to
avoid accidental use of this switch, which disables many
useful error message circuits.

NF-314-7925-003 Protected types visible in entities menu

In addition to subprograms, types and tasks, the entities
menu in GLIDE now includes an entry for protected objects
and types.  This is also available in the speedbar panel.

NF-314-7926-006 Allow SPARK annotations in -gnatyc mode

The -gnatyc mode now allows comments starting with --x
where x is any special character in the lower half of the
ASCII range (16#21#..16#2F#,16#3A#..16#3F#).  This in
particular allows the --# comments that appear as
annotations in the Praxis SPARK language.

NF-314-7929-004 Value_Size and Object_Size output by -gnatR

The -gnatR switch now outputs Value_Size and Object_Size
separately for types where these two values are different.
If the values are the same, then the output simply lists
this common value as the Size value.

NF-314-7930-001 Value_Size and Object_Size for all types.

The Value_Size and Object_Size can now be separately
specified for composite types (records and arrays).  The
meaning is as for scalar types.  The Value_Size is used for
unchecked conversion and packing purposes, and the
Object_Size is used for allocation of objects.

NF-314-7930-006 New attribute Standard'Wchar_T_Size

This attribute returns the size of the C type wchar_t,
which may differ from the Ada Wide_Character type.  The
attribute is primarily intended for the construction of the
wchar_t type in Interfaces.C.

NF-314-7930-007 Changed children of System to be pure

Many more packages in the System hierarchy have been marked
pure.  This change documents that the functions in those
packages are in fact side-effect free, which gives the
compiler more optimization opportunities.

NF-314-7931-001 Additional in-place assignments for
aggregates

Assignments of the form:  S (1 .. N) := (others => Expr);
are now performed in place, without generating a temporary
for the aggregate (as long as Expr is independent of S, of
course).  In addition, array assignments where the
right-hand side is an aggregate with only an others clause
are performed in place even if the bounds of the array are
non-static.

NF-314-7931-002 Improved handling of enumeration image
tables

The handling of enumeration type image tables (for support
of the Value, Image, and Width attributes for enumeration
types has been improved).  The tables are now generated
statically, and are significantly smaller than they were
previously (1-4 bytes overhead per entry instead of 12-15).

NF-314-7931-003 NT Win32Ada binding reformatted for -gnaty

The sources of Win32Ada binding were reformatted to meet
the style requirements for compiling with the -gnaty
switch.

NF-314-8001-002 The -gnatg switch is now fully documented

The -gnatg switch is the GNAT internal implementation
switch.  It is intended only for use by GNAT itself.  The
documentation now fully describes this switch and explains
why it should not be used by application programs.

NF-314-8004-004 Unchecked_Conversion now fully documented

The GNAT Reference Manual now contains complete
documentation on the approach used by GNAT in handling
unchecked conversions where the sizes of the source and
target types are different.

NF-314-8006-002 Improved output for representation
information

The -gnatR switch now takes an optional parameter which can
have the value 0,1,2.  No representation output is
generated in -gnatR0 mode.  In -gnatR1 (same as -gnatR),
representation information is generated for arrays and
records.  For -gnatR2, representation information for all
user declared types and objects is generated.

NF-314-8010-003 Detect duplicate Value/Object_Size clauses

The appearence of more than one Value_Size or Object_Size
clause for a single entity, which was previously allowed
(with the earlier one being ignored), is now detected as an
error, which seems more appropriate and more consistent
with the treatment of duplicate Size clauses.

NF-314-8010-005 Spell checking in GLIDE

The standard ispell command can now be used to spell check
the comments while editing an Ada source file.  The
checking only applies to comments and not to Ada source
code other than comments.

NF-314-8010-012 More flexible GNAT.Threads.Create_Thread

Create_Thread now returns the task id so that this value is
easily known on the client side.

NF-314-8012-002 New warning for unexpected rounding

Warn in cases where the static evaluation rules of Ada as
described in RM 4.9(38) result in different rounding than
would have been obtained at runtime.  This rule is a rather
surprising one, and has caused confusion in the past.
 
NF-314-8014-002 Additional information on unused entities

Warning messages on unused entities (generated by compiling
with -gnatwu) now indicate the kind (variable, function,
etc) of the entity to which the warning applies.

Cross-references are now generated when an entity appears
as a default actual in an instantiation.  This inhibits
warnings if the entity is not used explicitly elsewhere,
and is also used by tools that rely on xref information
(e.g.  GLIDE).

NF-314-8019-001 Documentation on variant object size

An extensive section has been added to the GNAT Reference
manual describing how GNAT treats the Size attribute when
applied to variant record objects.

NF-314-8022-004 Improved documentation for -gnato switch

More extensive documentation is provided for the -gnato
switch that enables overflow checking, emphasizing that
overflow checking is off by default, and explaining the
rationale behind treating overflow checks differently from
other kinds of range checks.

NF-314-8023-003 Document Size Limit

GNAT enforces a maximum Size of objects of 2**31-1, which
since Size is in bits, corresponds to a size of 256
megabytes.  This limit has always been enforced, but it is
now properly documented in the GNAT Reference Manual.

NF-314-8023-005 Improved documentation for GNAT.Task_Lock

The documentation for GNAT.Task_Lock has been enhanced to
make it clear that calling Lock multiple times from the
same task works as expected for nested use of Lock/Unlock.

NF-314-8024-002 C_Pass_By_Copy convention now standardized

The implementation of the C_Pass_By_Copy convention has
been modified to be consistent with the agreed
specification in AI95-00131, which is part of the official
technical corrigendum for Ada 95.  For GNAT, the
modification is that now C_Pass_By_Copy is rejected for any
entities other than record types and subtypes.  Convention
C can always be used instead for other entities (GNAT used
to treat C_Pass_By_Copy as identical to C for other
entities).

NF-314-8025-009 Documentation of GNAT Library Units

The GNAT Reference Manual now contains complete reference
documentation for all GNAT specific units in the GNAT,
System, Interfaces, and System.  This includes several
units that have been present in GNAT, but not previously
documented, including System.Address_Image (to convert
Address values to strings) and Ada.Command_Line.Remove (for
logically removing command line arguments).

NF-314-8028-002 SIGUSR1/SIGUSR2 now handled in GNU/Linux

Using native threads (aka LinuxThreads), it was not
possible to handle the SIGUSR1 and SIGUSR2 signals.  This
limitation has now been removed.  This change affects all
versions of GNAT for GNU/Linux including Debian GNU/Linux
and also Redhat Linux.

NF-314-8030-011 New style-check for exit of named loop

The -gnatye switch now includes checking for missing exit
labels.  It will now cause a warning to be posted if an
exit statement appears which refers to a labeled loop but
the statement does not include the label.

NF-314-8030-014 Improved output from gnatbind -e switch

The output now excludes all output for gnat internal units.
The dependency information for internal units is of
interest only for implementors, and tends to be voluminous
and useless for normal use.  A -de debug flag is introduced
to provide the old behavior for system implementors use.

NF-314-8031-012 More extensive misspelling warnings

The error messages for undefined variables now include
additional cases where a suggestion of a possible
misspelling is provided.  This message now includes cases
where the entity is in a with'ed package and has explicit
qualification.

NF-314-8031-013 Nested package bodies included in -gnatR

The output from the -gnatR switch now includes declarations
that appear in nested package bodies.

NF-314-8031-019 Clear labeling of output in -gnatR output

The output from the -gnatR switch now makes it clear
whether the unit for which representation information is
listed is a spec or a body.

NF-314-8101-005 Alignment warnings for bad address clauses

It is the program's responsibility to ensure that the value
in an address clause is consistent with (i.e.  a multiple
of) the alignment of the object to which it is applied, and
in general this cannot be checked at compile time.  However
it is possible to post warnings in some cases where the
value is known at compile time and is clearly wrong, and
this is now done.

NF-314-8104-007 New Glide variable
ada-prj-gnatfind-switches

This variable can be customized to change the default
switches used for gnatfind when you select the menu item
"Show All References".  For example this can be used to add
the -a switch, in case you often work with read-only ALI
files.

NF-314-8105-007 New convention Win32 equivalent to Stdcall

The convention Win32 is now recognized as equivalent to
Stdcall or DLL (all three conventions are identical in
effect and considered to be conformant).  This eases
porting of code from other compilers that use this
convention name.

NF-314-8106-010 New unit Ada.Exceptions.Is_Null_Occurrence

This GNAT addition to the Ada hierarchy allows a program to
test if an occurrence is the null occurrence
(Null_Occurrence) without enerating an exception.  This
capability is not present in the predefined subprograms in
Ada.Exceptions.

NF-314-8106-010 Warnings for useless type conversions

A warning can be generated for type conversions of the form
a(b) where b is a simple entity name which is of type a
(i.e.  the conversion has no effect).  This warning is
normally off but can be set on by the use of
@code{-gnatwr}.

NF-314-8106-011 Warnings for useless assignments

A warning can be generated for assignments of the form a :=
a; (i.e.  assignments of a variable to itself) which are
obviously useless.  This warning is normally off but can be
set on by the use of @code{-gnatwr}.
 
NF-314-8108-006 Warnings for accidental hiding by child
unit

A warning is generated when a child unit in the context of
a parent hides a compilation unit of the same name.  For
example, Foo.Ada, if it appears in the context of the body
of Foo, will hide an occurrence of the predefined Ada in
the same context, which can lead to surprising visibility
errors later on.

NF-314-8108-004 Better error messages for bad array
aggregate

If an array aggregate is missing elements (e.g.  it has the
index values 1,2,8,9 and is missing 3 .. 7), the error
messages will now give a full list of missing values.
 
NF-314-8114-002 Named numbers included in -gnatwu check

The warning option -gnatwu (check unreferenced entities)
now includes named numbers, so unreferenced named numbers
will now also cause warnings to be generated.

NF-314-8114-016 Better msg placement for with'ed unit not
found

In some cases, the error message for a WITH that directly
or indirectly lead to a file not found could be placed on a
location other than the WITH statement.  It is now always
placed in the most convenient place.

NF-314-8116-001 Support for wide char to string conversions

The library units System.Wch_Con and System.Wch_Cnv provide
a method for converting between wide characters and the
corresponding string representation, using any of the
implemented methods for encoding.

NF-314-8118-003 Backtrace decorators for automatic
backtraces

GNAT.Exception_Traces now includes a backtrace decoration
facility, allowing customization of the way the set of
addresses for a backtrace is output.  A typical use of this
feature is to provide a function that returns the symbolic
information associated with each address, as computed by
GNAT.Traceback.Symbolic.

NF-314-8120-006 Improved dead code detection

The warning circuitry for unreachable code has been
improved.  Now an IF or CASE statement, all of whose
statement sequence end with some transfer of control is
recognized, and code after such a statement is flagged as
dead code with an appropriate warning.

NF-314-8127-007 Improved parser error messages

Some improvements in parser error messages have been made.
If "|" is used in an expression in an inappropriate manner,
the parser suggests that "or" may have been intended.  If a
component is declared in the visible part of a protected
object, the diagnostic reminds that such components can
only be in the private part.

NF-314-8203-008 Default thread library is now LinuxThreads

Under the GNU/Linux operating system, the default tasking
run time is now based on the native LinuxThreads library.
The alternate FSU threads implementation is still available
as an alternative (see file README.TASKING for more
details).  This change applies to all versions of GNU
Linux, including Redhat Linux.

NF-314-8205-001 New package Ada.Characters.Wide_Latin_1

This package provides definitions analogous to those in the
RM defined package Ada.Characters.Latin_1 except that the
type of the constants is Wide_Character instead of
Character.  The provision of this package is in accordance
with RM (A.3(27)).  Note:  this package has been available
for some time, but was not properly documented, so from a
formal point of view was not available to application
programs, but now it is a first class citizen which is
fully documented.

NF-314-8213-003 More flexible placing of address clause

Previously when an address clause and Import pragma were
given for a subprogram, the pragma was required to be given
first.  There is now no restriction on the ordering.
 
NF-314-8214-004 Style violations are now warnings not
errors

Style errors resulting from the use of a pragma Style_Check
or the -gnaty flag are now treated as warnings rather than
errors, which means that an object file can be created if
there are no other errors, and that also the compiler will
find semantic problems even if there are syntactic style
errors.  If the previous behavior of treating these as
errors is desired, the -gnatwe flag can be used.

NF-314-8218-005 New Elaboration_Checks pragma

A new configuration pragma Elaboration_Checks can be used
to select the RM dynamic model of elaboration or the GNAT
default static model.  This may be used in gnat.adc for
partition wide application, or within sources for unit by
unit control.  See also feature NF-314-7530-009.

NF-314-8218-009 More efficient memory allocation

The GNAT run-time file a-raise.c can now easily be
recompiled with lock suppression to improve the efficiency
of memory allocation and deallocation if certain conditions
are met.  See the comment on NO_LOCK in a-raise.c itself
for details.

NF-314-8220-005 Generic sort packages in GNAT now Pure

The units GNAT.Heap_Sort_G (g-hesorg.ads),
GNAT.Bubble_Sort_G (g-busorg.ads) are now Pure instead of
Preelaborate, allowing them to be with'ed and instantiated
by Pure clients.

NF-314-8220-006 Automatic float control for Float
Input-Output

Floating-point conversion in Text_IO no longer relies on
the floating-point processor being correctly set.  This
means that the need for explicit calls to GNAT.Float_Reset
is limited to programs which explicitly use
Long_Long_Float.  This feature is especially helpful on NT,
where system services of all kinds seem to reset the
floating-processor into low precision mode.

NF-314-8225-001 Project file capability for gnatmake

The gnatmake utility is now project file aware, and can be
used with the new GNAT Project Files (see new documentation
section in the users guide).  It now accepts the new
switches -Pproject, -vPx and -Xname=value.

NF-314-8226-007 Better handling of invalid enum opnds for
Image

The Image function for enumeration types yielded rubbish
strings for abnormal and invalid operands (e.g.  created by
unchecked conversions).  A validity check (subject to
control by the -gnatV switch) is now performed so that an
exception (Constraint_Error) is raised for an invalid
operand.

NF-314-8230-001 Style check option for ordered subprograms

The -gnatyo switch (ORDERED_SUBPROGRAMS in the VMS version)
activates a style check that subprogram bodies within a
given scope (e.g.  a package body) must be in alphabetical
order.

NF-314-8302-004 Project file capability for gnatls

The gnatls utility is now project aware, and can be used
with the new GNAT Project Files (see new documentation
section in the users guide).  It now accepts the new
switches -Pproject, -vPx and -Xname=value.

NF-314-8304-001 RPM packages are now provided for GNU/Linux

Under GNU/Linux, GNAT is now provided as either a
compressed tar file as before, or as RPM packages which
means that the installation is simplified on various
versions of GNU/Linux, including Redhat Linux, and Debian
GNU/Linux.

NF-314-8305-003 Better folding of attributes of objects

The Alignment, Size, First, Last, Length, and
Component_Size attributes applied to objects are now
treated as compile time constants if the value can be
determined by the front end.

NF-314-8317-003 Floating-point range checks now catch
NaN's.

In GNAT, Machine_Overflows is False for floating-point
types, which means that operations such as 0.0/0.0 can
generate NaN's.  The RM does not require that NaN's be
caught by subsequent range checks, but it is certainly
convenient if this is the case, and GNAT has now been
modified so that NaN's will always fail any range check and
cause Constraint_Error to be raised.

NF-314-8322-016 Program units now distinguished by gnatxref

The cross-reference section of the ali file now
distinguishes between generic and non-generic units, and
between functions, packages and procedures.  The gnatxref
utility has been enhanced to take advantage of this new
information and now distinguishes these different kinds of
units in identification of entities.

NF-314-8323-004 Additional documentation on elaboration
issues.

A new section has been added to the users guide, entitled
"Additional Elaboration Order Considerations", which
discusses the issue of elaboration ordering requirements
that are not dictated by the language, but rather arise out
of extra-lingual logic requirements of the program.

NF-314-8328-012 Better handling of max size of variant
record
   
If a discriminant range is wider than it needs to be (e.g.
we have a Natural discriminant, which is used as the upper
bound of an array whose maximum bound is 10), then GNAT now
uses the maximum array bound in computing the maximum size
of the record, at least in most simple cases.  In any case
it is a good idea to use a discriminant range that reflects
the range of actual valid values.

NF-314-8330-008 End positions of constructs now in ali file

The cross-reference information in the ALI file now
includes all labels on END lines, and also marks the end of
specs and bodies of tasks, subprograms, packages, protected
types, blocks, loops, entries and accept bodies.  This
information is provided in the output from gnatxref.

NF-314-8407-012 Objects and types distinguished by gnatxref

The cross-reference output output by gnatxref distinguishes
type and object entities (for example an entity is labeled
as an "integer type" or "integer object", rather than
simply being identified as "Type:  integer" in both cases).

NF-314-8409-001 Tree output can be forced with -gnatQ
-gnatt

It is now possible to force tree output using a combination
of the -gnatQ and -gnatt switches (it may also be
appropriate to use -gnatq in this context).  This allows
the use of ASIS on some illegal programs, though if the
error is severe enough to cause a malformed tree, ASIS may
blow up when presented such a tree.

NF-314-8411-002 Boolean types now distinguished by gnatxref

The cross-reference section of the ali file now
distinguishes between boolean types and other enumeration
types, and the gnatxref utility has been enhanced to take
advantage of this new information and now distinguishes
these types in the entity identification information.

NF-314-8412-006 New option for gnatlink for object list
file

The switch -f for gnatlink forces the generation of a
separate file containing a list of objects for the linker,
even if the threshhold for command line length is not
exceeded.  This is useful to get around some cases of
unexpectedly exceeding this limit (e.g.  due to system
environment issues that reduce the limit).  The switch can
only be used on targets for which linker object list files
are implemented.  In addition the limit for generation of
such files on Tru Unix (Alpha) has been reduced to 10_000,
since on some systems the previous limit (30_000) was too
high.

NF-314-8412-010 New file routines in GNAT.OS_Lib

A new routine has been added into GNAT.OS_Lib to rename a
file.  All routines dealing with files now have two
implementations:  one using the String type and one using
an address to specify the filename.  This is a general
clean up to fix inconsistencies.

NF-314-8413-005 Stream size now taken from first subtype

Previously GNAT was using the size of the base type to
determine the number of storage units for use by stream
routines for elementary types.  This is now changed to meet
the new recommendations of AI-195, which suggest using the
size of the first subtype.  GNAT now uses the size of the
first subtype for this determination.

NF-314-8420-006 New tasking run time under Solaris

Under Solaris Sparc, GNAT now comes with a new tasking run
time based on posix threads (rts-pthread).  This run time
has the advantage of being mostly shared across all POSIX
compliant thread implementations, and also provides under
Solaris 8 the semantics of PTHREAD_PRIO_PROTECT and
PTHREAD_PRIO_INHERIT.  The predefined Ceiling_Locking
policy for pragma Locking_Policy is used to specify
PTHREAD_PRIO_PROTECT, and a new implementation defined
policy, Inheritance_Locking, can be used to specify the use
of PTHREAD_PRIO_INHERIT.

NF-314-8430-004 Enhanced style checking for references

For cases in which there is a separate body entity
(packages, subprograms, entries, tasks, protected types,
accept statements, subprogram formals), the switch -gnatyr
now checks the casing of the body entity to make sure that
it is the same as that of the spec entity.

NF-314-8509-011 New package GNAT.Expect

This package provides a set of subprograms similar to what
is available with the standard Tcl Expect tool, allowing
you to easily spawn and communicate with an external
process.  You can use this package to send commands or
inputs to the process, and compare the output with some
expected regular expression.

NF-314-8514-003 Improved error message for access
discriminants

When declaring a self-referential structure as a limited
record that contains a discriminated component that points
to the enclosing record, a common mistake is to define the
type of the component as having a discriminant with a
general access type, rather than as a proper access
discriminant.  This results in an accessibility violation
(RM 3.10.2 (21)).  The new message indicates that the error
is in the discriminant declaration itself.

NF-314-8522-001 Solaris programs do not depend on
libthread.so

On the Solaris operating system, for programs that do not
use tasking, the generated executables no longer depend on
libthread.so so that a link can be successfuly completed
without requiring this library to be present.

NF-314-8526-003 Record'Size evaluated at compile time

In the case where the size of a record type is specified
using a size representation attribute clause, the front end
now folds the attribute reference at compile time.  The
result is still not a static expression, but the quality of
code is improved, and in addition, representation clauses
(such as component clauses) that require values and types
to be statically known at compile time are permitted in
additional cases as a result of this change.



^ permalink raw reply	[relevance 1%]

* Re: Generic Formal Parameter for a Task Type
  2001-03-10  0:14  4%     ` Robert C. Leif, Ph.D.
@ 2001-03-12 16:14  0%       ` Tucker Taft
  0 siblings, 0 replies; 138+ results
From: Tucker Taft @ 2001-03-12 16:14 UTC (permalink / raw)


"Robert C. Leif, Ph.D." wrote:
> 
> From: Bob Leif
> To: Tucker Taft et al.
> You wrote:
> "If you wanted to avoid generics, you could define an abstract limited
> tagged type (say "Has_Task") which had various (abstract) primitive
> operations, including  at least a "Task_ID" function.  You would then
> extend from this type by adding a component of the task type of interest
> (and of course override the abstract primitives as appropriate)."
> 
> Can you include the "Has_Task" in a generic package; or are the two
> approaches mutually exclusive for tasks?

As I mentioned, you can declare a formal derived type, such as
   generic
       type My_Task is new Has_Task with private;
   ...

and inside the generic use the My_Task type to create tasks and
query the information about instances of the type.

I wrote earlier:
> ...
> Why not have a formal function that returns the Task_ID, rather
> than 'Terminated?  That way, you can use the Ada.Task_Identification
> and Ada.Task_Attributes packages to get whatever else you need from the
> task, including task attributes...
> 
> If you wanted to avoid generics, you could define an abstract limited
> tagged type (say "Has_Task") which had various (abstract) primitive
> operations, including  at least a "Task_ID" function.  You would then
> extend from this type by adding a component of the task type of interest
> (and of course override the abstract primitives as appropriate).
> You could then manipulate objects of type Has_Task'Class, or references
> there-to, in a "Java"-like way ;-).  You could also pass in any
> extension of Has_Task to a generic with a formal tagged derived type
> of "type My_Task is new Has_Task with private;".
> 
> The possibilities are endless...

-- 
-Tucker Taft   stt@avercom.net   http://www.averstar.com/~stt/
Chief Technology Officer, AverCom Corporation (A Titan Company) 
Burlington, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/services/ebusiness_applications.html)



^ permalink raw reply	[relevance 0%]

* Re: Generic Formal Parameter for a Task Type
  2001-03-10  3:25  0%     ` James Rogers
@ 2001-03-12 15:33  0%       ` Stephen Leake
  0 siblings, 0 replies; 138+ results
From: Stephen Leake @ 2001-03-12 15:33 UTC (permalink / raw)


James Rogers <jimmaureenrogers@worldnet.att.net> writes:

> Yes, each of these is a possible way to create a system for monitoring
> and controlling a set of tasks. 
> 
> I like your idea of the abstract limited tagged type containing a
> "Task_ID" function. Unfortunately, this still adds a lot of 
> overhead when all I want to do is monitor and control the creation
> of tasks.

By "overhead" here I guess you mean "code I have to write". The
implementation of the Java task hierarchy (which you are trying to get
in Ada) must have about the same amount of run-time "overhead", since
it does the same things. It's just that Java has already done the
implementation.

This is a _feature_ of Ada, since it lets you get exactly the
structure and semantics _you_ want, rather than the particular one the
Java language implementers decided to give you. Once someone has done
it and published it, you are free to reuse that, or do something
different. Java gives you no choice.

> Note that the problem I am trying to solve does not require much
> knowledge about the task, only the ability to create an instance,
> and the ability to query a task attribute.

Java gives you more than that, but you don't complain about "overhead"
there. 

> I fully realize the problem can be solved by building an elaborate
> scaffold of data and code structure. 

Similar to the one Java gives you.

> I was hoping to achieve the results simply and cleanly. 

Look at the Java code implementing the task hierarchy; is it simple
and clean?

> I was hoping to avoid the additional overhead of code bloat
> resulting from building tagged types and associated subprograms.

Be sure you are comparing the same things.

> 
> 
> Jim Rogers Colorado Springs, Colorado USA
> 
> Tucker Taft wrote:
> > 
> > Why not have a formal function that returns the Task_ID, rather
> > than 'Terminated?  That way, you can use the Ada.Task_Identification
> > and Ada.Task_Attributes packages to get whatever else you need from the
> > task, including task attributes...
> > 
> > If you wanted to avoid generics, you could define an abstract limited
> > tagged type (say "Has_Task") which had various (abstract) primitive
> > operations, including  at least a "Task_ID" function.  You would then
> > extend from this type by adding a component of the task type of interest
> > (and of course override the abstract primitives as appropriate).
> > You could then manipulate objects of type Has_Task'Class, or references
> > there-to, in a "Java"-like way ;-).  You could also pass in any
> > extension of Has_Task to a generic with a formal tagged derived type
> > of "type My_Task is new Has_Task with private;".
> > 
> > The possibilities are endless...

-- 
-- Stephe



^ permalink raw reply	[relevance 0%]

* Re: Generic Formal Parameter for a Task Type
  2001-03-09 21:50  5%   ` Tucker Taft
  2001-03-10  0:14  4%     ` Robert C. Leif, Ph.D.
@ 2001-03-10  3:25  0%     ` James Rogers
  2001-03-12 15:33  0%       ` Stephen Leake
  1 sibling, 1 reply; 138+ results
From: James Rogers @ 2001-03-10  3:25 UTC (permalink / raw)


Yes, each of these is a possible way to create a system for monitoring
and controlling a set of tasks. 

I like your idea of the abstract limited tagged type containing a
"Task_ID" function. Unfortunately, this still adds a lot of 
overhead when all I want to do is monitor and control the creation
of tasks.

Note that the problem I am trying to solve does not require much
knowledge about the task, only the ability to create an instance,
and the ability to query a task attribute.

I fully realize the problem can be solved by building an elaborate
scaffold of data and code structure. I was hoping to achieve the
results simply and cleanly. I was hoping to avoid the additional
overhead of code bloat resulting from building tagged types and
associated subprograms.

Jim Rogers
Colorado Springs, Colorado USA

Tucker Taft wrote:
> 
> Why not have a formal function that returns the Task_ID, rather
> than 'Terminated?  That way, you can use the Ada.Task_Identification
> and Ada.Task_Attributes packages to get whatever else you need from the
> task, including task attributes...
> 
> If you wanted to avoid generics, you could define an abstract limited
> tagged type (say "Has_Task") which had various (abstract) primitive
> operations, including  at least a "Task_ID" function.  You would then
> extend from this type by adding a component of the task type of interest
> (and of course override the abstract primitives as appropriate).
> You could then manipulate objects of type Has_Task'Class, or references
> there-to, in a "Java"-like way ;-).  You could also pass in any
> extension of Has_Task to a generic with a formal tagged derived type
> of "type My_Task is new Has_Task with private;".
> 
> The possibilities are endless...



^ permalink raw reply	[relevance 0%]

* RE: Generic Formal Parameter for a Task Type
  2001-03-09 21:50  5%   ` Tucker Taft
@ 2001-03-10  0:14  4%     ` Robert C. Leif, Ph.D.
  2001-03-12 16:14  0%       ` Tucker Taft
  2001-03-10  3:25  0%     ` James Rogers
  1 sibling, 1 reply; 138+ results
From: Robert C. Leif, Ph.D. @ 2001-03-10  0:14 UTC (permalink / raw)
  To: comp.lang.ada

From: Bob Leif
To: Tucker Taft et al.
You wrote:
"If you wanted to avoid generics, you could define an abstract limited
tagged type (say "Has_Task") which had various (abstract) primitive
operations, including  at least a "Task_ID" function.  You would then
extend from this type by adding a component of the task type of interest
(and of course override the abstract primitives as appropriate)."

Can you include the "Has_Task" in a generic package; or are the two
approaches mutually exclusive for tasks?

-----Original Message-----
From: comp.lang.ada-admin@ada.eu.org
[mailto:comp.lang.ada-admin@ada.eu.org]On Behalf Of Tucker Taft
Sent: Friday, March 09, 2001 1:51 PM
To: comp.lang.ada@ada.eu.org
Subject: Re: Generic Formal Parameter for a Task Type


James Rogers wrote:
>
> "Beard, Frank" wrote:
> >
> > Why can't you have something like the following:
> >
> >    generic
> >
> >       type Item is limited private;
> >       with function Terminated(the_Item : Item) return boolean;
> >
> >    package Xyz is
> >
> >       procedure Monitor(the_Item : Item);
> >       ...
> >
> >    end Xyz;
> >
> > You instantiate the package with the task type and supply the
> > Terminated function, which would look something like:
> >
> >    function Terminated(the_Task : Task_Type) return boolean is
> >    begin
> >       return the_Task'terminated;
> >    end Terminated;
> >
> > So, inside your generic where you are monitoring the task, you
> > call the supplied function.  Of course, you would have to supply
> > a function for every task attribute you wanted to check.  I know
> > it's not as clean as using the attribute directly, but it's not
> > that bad.
> >
> > I haven't tried to test this but the spec part compiles and it
> > seems like it should work, but I might be missing something.
>
> Yep. That works. Thanks for the inspiration.
>
> This is still a bit nastier than I hoped for. As you say, it requires
> a function for each attribute. ...

Why not have a formal function that returns the Task_ID, rather
than 'Terminated?  That way, you can use the Ada.Task_Identification
and Ada.Task_Attributes packages to get whatever else you need from the
task, including task attributes...

If you wanted to avoid generics, you could define an abstract limited
tagged type (say "Has_Task") which had various (abstract) primitive
operations, including  at least a "Task_ID" function.  You would then
extend from this type by adding a component of the task type of interest
(and of course override the abstract primitives as appropriate).
You could then manipulate objects of type Has_Task'Class, or references
there-to, in a "Java"-like way ;-).  You could also pass in any
extension of Has_Task to a generic with a formal tagged derived type
of "type My_Task is new Has_Task with private;".

The possibilities are endless...


> Jim Rogers
> Colorado Springs, Colorado USA

--
-Tucker Taft   stt@avercom.net   http://www.averstar.com/~stt/
Chief Technology Officer, AverCom Corporation (A Titan Company)
Burlington, MA  USA (AverCom was formerly the Commercial Division of
AverStar:
http://www.averstar.com/services/ebusiness_applications.html)





^ permalink raw reply	[relevance 4%]

* RE: Generic Formal Parameter for a Task Type
@ 2001-03-09 22:53  0% Beard, Frank
  0 siblings, 0 replies; 138+ results
From: Beard, Frank @ 2001-03-09 22:53 UTC (permalink / raw)
  To: 'comp.lang.ada@ada.eu.org'


-----Original Message-----
From: Tucker Taft [mailto:stt@averstar.com]

> Why not have a formal function that returns the Task_ID, rather
> than 'Terminated?  That way, you can use the Ada.Task_Identification
> and Ada.Task_Attributes packages to get whatever else you need from the
> task, including task attributes...

Good idea.  It didn't cross my mind. I still think too much in Ada 83 terms.

> If you wanted to avoid generics, you could define an abstract limited
> tagged type (say "Has_Task") which had various (abstract) primitive 
> operations, including  at least a "Task_ID" function.  You would then 
> extend from this type by adding a component of the task type of interest
> (and of course override the abstract primitives as appropriate).  
> You could then manipulate objects of type Has_Task'Class, or references
> there-to, in a "Java"-like way ;-).  You could also pass in any
> extension of Has_Task to a generic with a formal tagged derived type
> of "type My_Task is new Has_Task with private;".

Yeah!  Whatever you said.




^ permalink raw reply	[relevance 0%]

* Re: Generic Formal Parameter for a Task Type
  @ 2001-03-09 21:50  5%   ` Tucker Taft
  2001-03-10  0:14  4%     ` Robert C. Leif, Ph.D.
  2001-03-10  3:25  0%     ` James Rogers
  0 siblings, 2 replies; 138+ results
From: Tucker Taft @ 2001-03-09 21:50 UTC (permalink / raw)


James Rogers wrote:
> 
> "Beard, Frank" wrote:
> >
> > Why can't you have something like the following:
> >
> >    generic
> >
> >       type Item is limited private;
> >       with function Terminated(the_Item : Item) return boolean;
> >
> >    package Xyz is
> >
> >       procedure Monitor(the_Item : Item);
> >       ...
> >
> >    end Xyz;
> >
> > You instantiate the package with the task type and supply the
> > Terminated function, which would look something like:
> >
> >    function Terminated(the_Task : Task_Type) return boolean is
> >    begin
> >       return the_Task'terminated;
> >    end Terminated;
> >
> > So, inside your generic where you are monitoring the task, you
> > call the supplied function.  Of course, you would have to supply
> > a function for every task attribute you wanted to check.  I know
> > it's not as clean as using the attribute directly, but it's not
> > that bad.
> >
> > I haven't tried to test this but the spec part compiles and it
> > seems like it should work, but I might be missing something.
> 
> Yep. That works. Thanks for the inspiration.
> 
> This is still a bit nastier than I hoped for. As you say, it requires
> a function for each attribute. ...

Why not have a formal function that returns the Task_ID, rather
than 'Terminated?  That way, you can use the Ada.Task_Identification
and Ada.Task_Attributes packages to get whatever else you need from the
task, including task attributes...

If you wanted to avoid generics, you could define an abstract limited
tagged type (say "Has_Task") which had various (abstract) primitive 
operations, including  at least a "Task_ID" function.  You would then 
extend from this type by adding a component of the task type of interest
(and of course override the abstract primitives as appropriate).  
You could then manipulate objects of type Has_Task'Class, or references
there-to, in a "Java"-like way ;-).  You could also pass in any
extension of Has_Task to a generic with a formal tagged derived type
of "type My_Task is new Has_Task with private;".

The possibilities are endless...


> Jim Rogers
> Colorado Springs, Colorado USA

-- 
-Tucker Taft   stt@avercom.net   http://www.averstar.com/~stt/
Chief Technology Officer, AverCom Corporation (A Titan Company) 
Burlington, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/services/ebusiness_applications.html)



^ permalink raw reply	[relevance 5%]

* Re: Generic Formal Parameter for a Task Type
  2001-03-09  4:26  6%     ` Pat Rogers
@ 2001-03-09  4:58  0%       ` James Rogers
  0 siblings, 0 replies; 138+ results
From: James Rogers @ 2001-03-09  4:58 UTC (permalink / raw)




Pat Rogers wrote:
> 
> See RM C.7.1 for package Ada.Task_Identification, specifically function
> Is_Terminated.  That may be enough...
> 

According to RM C.7.1(5):
"A value of the type Task_ID identifies an existent task. The constant
Null_Task_Id does not identify and task. Each object of the type
Task_ID is default initialized to the value of Null_Task_Id."

This means that I would need to create the task object outside the
generic package. Inside the generic package I could not clearly
identify the limited private type as a task. It could not, therefore
have a Task_ID. My generic package cannot control the creation
of task objects outside its own scope. I must be able to create the
task object within the scope of the generic package.

The best I could do inside the generic package is create a number
of Task_ID objects, all with the default value of Null_Task_Id.

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[relevance 0%]

* Re: Generic Formal Parameter for a Task Type
  @ 2001-03-09  4:26  6%     ` Pat Rogers
  2001-03-09  4:58  0%       ` James Rogers
  0 siblings, 1 reply; 138+ results
From: Pat Rogers @ 2001-03-09  4:26 UTC (permalink / raw)


See RM C.7.1 for package Ada.Task_Identification, specifically function
Is_Terminated.  That may be enough...



"James Rogers" <jimmaureenrogers@worldnet.att.net> wrote in message
news:3AA84FC7.CE523E9D@worldnet.att.net...
> The problem with using a formal limited private type is in the
> need to determine if one of the tasks being monitored has terminated.
>
> The 'Terminated attribute only applies to Task objects, either
> directly, or implicitly through an access to the task object.
>
> A limited private type is too general. It is not viewed within the
> generic as a task type. I know. I tried this first.
>
> The only way to make such a system work is to creat a limited record
> type containing an access to task type. You could then create a
> function taking a parameter of the record type, returning the proper
> response from the 'Terminated attribute.
>
> Although this is easily done, it is not what I wanted. I had hoped
> to be able to create a generic package directly usable with most
> any task type.
>
> This appears to be one problem not solvable in Ada, yet easily
> solved in Java.
>
> I would like to add a generic task type formal parameter to the
> list of improvements for the next version of Ada.
>
> Jim Rogers
> Colorado Springs, Colorado USA
>
> Pat Rogers wrote:
> >
> > "James Rogers" <jimmaureenrogers@worldnet.att.net> wrote in message
> > news:3AA80A68.A2C8B042@worldnet.att.net...
> > > I have looked through "Ada as a Second Language" and the Ada Reference
> > > manual. I cannot find any proper form to pass a task type as a
> > > generic formal parameter.
> > >
> > > Is there a generic formal parameter form for this purpose?
> > >
> > > I wanted to create a generic package I call Task_Governor. This
> > > package would control the number of tasks one could create at once.
> > > The idea is that task resources may be limited. This package would
> > > allow someone to limit the number of tasks to a maximum specified.
> > > An instantiation of the package would monitor the tasks it started
> > > and allow another to be started when one of the tasks terminated.
> > >
> > > My problem is that I cannot figure out how to specify a task type
> > > as a generic formal parameter.
> >
> > There is no generic formal task type; you have to use a limited private
> > formal.
> >
> > ---
> > Patrick Rogers                       Consulting and Training in:
> > http://www.classwide.com        Real-Time/OO Languages
> > progers@classwide.com          Hard Deadline Schedulability Analysis
> > (281)648-3165                          Software Fault Tolerance
>





^ permalink raw reply	[relevance 6%]

* Re: gcov in multithreaded applications
    2000-08-30  0:00  5% ` Robert A Duff
@ 2000-08-31 21:58  5% ` Jean-Pierre Rosen
  1 sibling, 0 replies; 138+ results
From: Jean-Pierre Rosen @ 2000-08-31 21:58 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1537 bytes --]


<daelen@my-deja.com> a �crit dans le message news: 8oip2j$ut0$1@nnrp1.deja.com...
> I am working with Gnat 3.13a on Windows NT 4.0.
>
> I would like to use gcov to profile our application containing several
> tasks.
> The problem is that the da-files are written when the application exits,
> but because most tasks contain infinit loops, the main program will not
> exit.
> I tried Win32.Winbase.ExitProcess but no da-files are written then.
>
> - so how to write intermediate profiling info to the da-files without
> having to exit the application.
> - or how to exit or terminate the application in such a way that the da-
> files are written.
> Note that aborting the tasks is not an option because not all tasks-
> names are known or in scope.
>
Yes it is. There is a very simple way to abort all tasks in a system.
In the main procedure (or some library package) have:
   Anonymous_Task : constant Task_ID := Current_Task;

and then:
   Abort_Task (Anonymous_Task);

(of course, you need to with Ada.Task_Identification). Since the main program is executed by the anonymous task, and since all tasks
have (directly or indirectly) the anonymous task as one of their masters, this is guaranteed to kill everything. Have a look at
package Debug from Adalog's component page (http://pro.wanadoo.fr/adalog/compo2.htm) for more details on that kind of techniques.

--
---------------------------------------------------------
           J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://pro.wanadoo.fr/adalog





^ permalink raw reply	[relevance 5%]

* Re: gcov in multithreaded applications
  @ 2000-08-30  0:00  5% ` Robert A Duff
  2000-08-31 21:58  5% ` Jean-Pierre Rosen
  1 sibling, 0 replies; 138+ results
From: Robert A Duff @ 2000-08-30  0:00 UTC (permalink / raw)


daelen@my-deja.com writes:

> Note that aborting the tasks is not an option because not all tasks-
> names are known or in scope.

Task names don't need to be visible in order to abort them.  You can use
package Ada.Task_Identification.  You could have each infinitely-looping
task register itself (ie put its ID in some data structure).  Then you
could abort all those tasks at the appropriate time, from some central
place.

Alternatively, you could make each task do an ATC:

    task body T is
    begin
        select
            delay 10.0;
        then abort
            loop -- infinite loop here
                ...
            end loop;
        end select;
    end T;

Then all the tasks will go away after approx 10 seconds.

A better solution would be to simply write out the profiling data -- it
seems ugly to add complexity to your application just for the sake of
profiling.  I imagine there's a way to do that, but I don't know what it
is.

- Bob




^ permalink raw reply	[relevance 5%]

* Re: Operator visibility/inheritance for derived private type? (Repost)
  2000-01-27  0:00  8% Operator visibility/inheritance for derived private type? (Repost) Rod Chapman
@ 2000-01-28  0:00  7% ` Tucker Taft
  0 siblings, 0 replies; 138+ results
From: Tucker Taft @ 2000-01-28  0:00 UTC (permalink / raw)


Rod Chapman wrote:
> 
> Confused of Bath writes:
> 
>   Imagine I have a package exporting a private type with an
> explicitly redeclared "=" operator - Ada.Task_Identification.Task_ID
> for instance.  I want to derive another private type from
> this, exporting only a subset of the operations of the original,
> so I write
> 
> with Ada.Task_Identification;
> package Rod.TI is
>    type Task_ID is private;
>    function Current_Task return Boolean;
> private
>    type Task_ID is new Ada.Task_Identification.Task_ID;
> end Rod.TI;
> 
> If a user of this package does
> 
>    A, B : Rod.TI.Task_ID;
>  begin
>    if A = B then ...
> 
> which "=" is called?  Do I get some simple comparison of
> A and B or should I get a call of
> Ada.Task_Identification."="?

Semantically, you end up with a "call" on Ada.Task_Identification."=", but 
that might of course be a built-in "simple comparison" operation.
It certainly doesn't need to be an out-of-line function call.

> GNAT (3.12a3 on NT) seems to be generating the former,
> but I'm not sure if the language requires the latter,
> and GNAT is simply doing an optimisation.  If
> I _definintely_ want the call to Ada.Task_Identification."=",
> so I need to explicitly redeclare my own "=" for
> Rod.TI.Task_ID?  Which language rule(s)
> am I missing to explain what going on?

How do you know that GNAT is generating a "simple comparison" but
not a "call" on Task_Identification."=", since they very well might
be one and the same thing?

You could check GNAT by writing your own package, and making your
"=" a user-defined function.  In that case, GNAT should generate
an out-of-line call on your function.  However, since Ada.Task_Identification
is provided by the GNAT implementators, it seems quite likely that
the "=" on task IDs uses the built-in equality operation, presuming
it does the "right thing."   I wouldn't really call this an "optimization,"
but rather just the expected way of doing things.

> Cheers,
>  Rod Chapman
>  Praxis Critical Systems

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




^ permalink raw reply	[relevance 7%]

* Operator visibility/inheritance for derived private type? (Repost)
@ 2000-01-27  0:00  8% Rod Chapman
  2000-01-28  0:00  7% ` Tucker Taft
  0 siblings, 1 reply; 138+ results
From: Rod Chapman @ 2000-01-27  0:00 UTC (permalink / raw)


Confused of Bath writes:

  Imagine I have a package exporting a private type with an
explicitly redeclared "=" operator - Ada.Task_Identification.Task_ID
for instance.  I want to derive another private type from
this, exporting only a subset of the operations of the original,
so I write

with Ada.Task_Identification; 
package Rod.TI is
   type Task_ID is private;
   function Current_Task return Boolean;
private
   type Task_ID is new Ada.Task_Identification.Task_ID;
end Rod.TI;

If a user of this package does

   A, B : Rod.TI.Task_ID;
 begin
   if A = B then ...

which "=" is called?  Do I get some simple comparison of
A and B or should I get a call of
Ada.Task_Identification."="?

GNAT (3.12a3 on NT) seems to be generating the former,
but I'm not sure if the language requires the latter,
and GNAT is simply doing an optimisation.  If
I _definintely_ want the call to Ada.Task_Identification."=",
so I need to explicitly redeclare my own "=" for
Rod.TI.Task_ID?  Which language rule(s)
am I missing to explain what going on?

Cheers,
 Rod Chapman
 Praxis Critical Systems




^ permalink raw reply	[relevance 8%]

* Purposes of Ada.Task_Identification
@ 1999-06-24  0:00 14% Jim Rogers
  1999-06-24  0:00 11% ` Robert I. Eachus
                   ` (2 more replies)
  0 siblings, 3 replies; 138+ results
From: Jim Rogers @ 1999-06-24  0:00 UTC (permalink / raw)


 I occasionally wonder what the intended purpose of the package
Ada.Task_Identification is. You cannot use the Task_ID to call
a task entry.

You can determine whether or not two task access objects access the
same task. You can determine whether or not a task is terminated
or callable. Finally, you can abort a task via the Task_ID.

Of course, you can determine whether or not a task is callable or
terminated without using Ada.Task_Identification. You can also
abort a task without using Ada.Task_Identification.

Is the only real use of this package to determine if two different
ID objects refer to the same task? Is this a common need? I have
never used a system that needs this ability.

--
Jim Rogers
Colorado Springs, Colorado USA


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




^ permalink raw reply	[relevance 14%]

* Re: Purposes of Ada.Task_Identification
  1999-06-24  0:00 14% Purposes of Ada.Task_Identification Jim Rogers
  1999-06-24  0:00 11% ` Robert I. Eachus
  1999-06-24  0:00  7% ` Tucker Taft
@ 1999-06-24  0:00 11% ` tmoran
  2 siblings, 0 replies; 138+ results
From: tmoran @ 1999-06-24  0:00 UTC (permalink / raw)


> I occasionally wonder what the intended purpose of the package
>Ada.Task_Identification is.
  It's sometimes handy for a resource locking routine to know if
the currect request in fact comes from the current owner of the
resource.  A comparison of the Id of the owner to that of the
requestor will answer that question.
  Some compilers will return True for Is_Callable(the environment task)
while the main program is running, and False after it has terminated
(and is waiting for child tasks to terminate).  I understand there's
an AI in the works to make this standard practice.  Where it works,
it allows a long-running task to detect that the program is trying
to stop, and to stop itself.  This handles situations where a
"select ... or terminate", or an abort, are inappropriate.
  Sometimes in debugging a multi-tasking system it's nice to be
able to log some activity and include in the log which task performed
that activity.
  That's just how I use Ada.Task_Identification.




^ permalink raw reply	[relevance 11%]

* Re: Purposes of Ada.Task_Identification
  1999-06-24  0:00 14% Purposes of Ada.Task_Identification Jim Rogers
@ 1999-06-24  0:00 11% ` Robert I. Eachus
  1999-06-24  0:00  7% ` Tucker Taft
  1999-06-24  0:00 11% ` tmoran
  2 siblings, 0 replies; 138+ results
From: Robert I. Eachus @ 1999-06-24  0:00 UTC (permalink / raw)


Jim Rogers wrote:
> 
>  I occasionally wonder what the intended purpose of the package
> Ada.Task_Identification is. You cannot use the Task_ID to call
> a task entry.
> 
> You can determine whether or not two task access objects access the
> same task. You can determine whether or not a task is terminated
> or callable. Finally, you can abort a task via the Task_ID.
> 
> Of course, you can determine whether or not a task is callable or
> terminated without using Ada.Task_Identification. You can also
> abort a task without using Ada.Task_Identification.
> 
> Is the only real use of this package to determine if two different
> ID objects refer to the same task? Is this a common need? I have
> never used a system that needs this ability.

    No.  There are several uses for Ada.Task_Identification, however,
determining whether two tasks are the same task is not a justification
for it.

    First, in Ada 83, you could only abort a task if you statically knew
its type.  (This does not mean that the task to be aborted had to be
statically determined, but that the type of the task had to be.)  Using
Ada.Task_Identification, you can do things like having arrays of
Task_IDs, and manage heterogenous tasks from a single manager.

    Second, look at the package Ada.Task_Attributes.  This package is
very useful for inheriting values from the parent task, and then being
able to update a local copy without requiring a synchronization with the
parent.  Think Environment Variables in Unix.  The definition of this
package requires a way to refer to a task independent of its type.  So
Ada.Task_Identification is necessary to support this feature.  (This is
the primary reason it is in Ada 95.)

    Oh, one other "neat" feature of Ada.Task_Attributes.  A task can
define task specific data that can be referenced by the called task
during a rendezvous. (You want the data from the called task of
course.)  One of the most important uses of this is for data that can be
maintained without task synchronization.  In other words, setting the
data requires a rendezvous, but it can be read without synchronization. 
Hmmm. That's still not very clear.  Let's say you have comm ports that
can be assigned to tasks.  As long as that task owns the comm port,
communication through the (hardware) port doesn't require any software
level synchronization.  The routines for seizing and releasing the ports
is encapsulated in a protected object, but normal operations don't
require any synchronization.  (Of course, you could make the port id a
parameter in all the calls, but why tempt fate and dumb programming
errors?)

    Third, Task_IDs can be used to dynamically change task priorities
(see D.5).  Very useful if you are building your own scheduler, or more
likely want to elevate the priority of the task while it holds some
critical resource.  (Of course, you want to save the normal priority
value and deal with all the issues of locking order. 
Ada.Task_Attributes is great for this.  Just assign a number to each
lock and refuse to let a task acquire a lower numbered lock than one it
is holding.  When you release a lock, if it is the highest numbered lock
held, then revert to the priority when the next lower lock was
acquired.) 

   And last, there is one cute idiom that involves
Ada.Task_Identification.  The main program runs inside an "environment
task."  Aborting the environment task aborts the main program, all of
its tasks, and all tasks created by library level packages.
-- 

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 11%]

* Re: Purposes of Ada.Task_Identification
  1999-06-24  0:00 14% Purposes of Ada.Task_Identification Jim Rogers
  1999-06-24  0:00 11% ` Robert I. Eachus
@ 1999-06-24  0:00  7% ` Tucker Taft
  1999-06-24  0:00 11% ` tmoran
  2 siblings, 0 replies; 138+ results
From: Tucker Taft @ 1999-06-24  0:00 UTC (permalink / raw)


Jim Rogers wrote:
> 
>  I occasionally wonder what the intended purpose of the package
> Ada.Task_Identification is. ...

> Is the only real use of this package to determine if two different
> ID objects refer to the same task?

Task IDs are used in a number of other packages.  For example,
the Dynamic_Priorities package relies on task IDs for setting
and getting the priority of another task.  As others have pointed
out, task IDs are also useful for managing a heterogenous
collection of tasks by stuffing their task IDs into an array.

> --
> Jim Rogers
> Colorado Springs, Colorado USA

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




^ permalink raw reply	[relevance 7%]

* Re: Aborting
  @ 1999-06-21  0:00  5%   ` Jean-Pierre Rosen
  0 siblings, 0 replies; 138+ results
From: Jean-Pierre Rosen @ 1999-06-21  0:00 UTC (permalink / raw)



Keith Thompson a �crit dans le message ...
>Jan Kroken <jankr@nntp.ifi.uio.no> writes:
>> Is there any other way than pragma import(C,Exit,"exit") I can
abort
>> an Ada program from another place than the main procedure?
>
>Raise an exception that's handled only in the main program.  (I'm not
>sure what this does to tasks, though.)
>
Here is a solution that works OK in the presence of tasking:
(assume you have the proper "with Ada.Task_Identification":
In a *library* package, declare:
   Main_Task : Task_ID := Current_Task;
This will give you the task Id of the anonymous task which is the
ancestor of all other tasks.

Then do:
   Abort_Task (Main_Task);

It will terminate all tasks, but all controlled objects will be
properly finalized (not sure this would happen if you call the C
"exit" function).
---------------------------------------------------------
           J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://perso.wanadoo.fr/adalog






^ permalink raw reply	[relevance 5%]

* Re: an error in Re: tasking
  @ 1998-10-07  0:00  7%   ` Frank Ecke
  0 siblings, 0 replies; 138+ results
From: Frank Ecke @ 1998-10-07  0:00 UTC (permalink / raw)


On Wed, 07 Oct 1998 11:20:32 +0200, grave <grave@ipnsun5.in2p3.fr> wrote:

> I'm wanting to kill a task to let an exception propagate and kill the
> process.  How can I do this if the task is already excuting some part of
> code like this :
> 
> select
>    entry start;
>    Do_Some_Stuff_Here;
> or
>    terminate;
> end select;
> 
> Here I'm wanting to kill the task when it works in Do_Some_Stuff_Here;
> 
> Is this possible ?


You select should read

   select
      accept Start;
      Do_Some_Stuff_Here;
   or
      terminate;
   end select;

for it is not possible to declare an entry within a branch of a select
statement.

   To kill (or abort) a task, use ``abort Task_Name {, Task_Name};'' (see
ARM 9.8).  In order to abort the task from within Do_Some_Stuff_Here (i.e., to
let that task kill itself), you may issue

   Self : Ada.Task_Identification.Task_ID :=
     Ada.Task_Identification.Current_Task;

   ...

   Ada.Task_Identification.Abort_Task(Self);

   Note that trying to kill the task (from outside) ``when it works in
Do_Some_Stuff_Here'' gives raise to a race condition since you cannot be sure
that the task to be killed is already (or still) inside Do_Some_Stuff_Here when
you issue the abort.

   Note further that if Do_Some_Stuff_Here were part of the accept statement
corresponding to the Start entry, it would be executed as part of an abort-
deferred operation, namely the rendezvous between the caller and the callee,
and could thus not be aborted.

> I'm wanting to kill a task to let an exception propagate and kill the
> process.

I am a bit puzzled by this statement.  Could you please give further
explanations?


Frank

--
Frank Ecke <franke@minet.uni-jena.de>


       In a world without walls and fences, who needs windows and gates?




^ permalink raw reply	[relevance 7%]

* Re: Future Ada language revisions?
  @ 1998-10-02  0:00  3% ` Robert I. Eachus
  0 siblings, 0 replies; 138+ results
From: Robert I. Eachus @ 1998-10-02  0:00 UTC (permalink / raw)


In article <6um7on$db5$1@nnrp1.dejanews.com> bpr5549@my-dejanews.com writes:

  > PS: In case anyone is wondering, my main peeve is the restriction
  > on out mode function parameters, which I just don't understand,
  > even when I'm trying to open minded. I have yet to hear a good
  > defense of this restriction, so if anyone has one, I'm all ears,
  > errr, eyes.

   I don't have strong feelings either way here, with a slight bias
toward allowing it in interfaces to make interfacing to C easier.
(Flame retardant:  Of course in C you can't have a function that
changes a function parameter, but the workaround it to require the
user to pass a pointer to an appropriate sized area.  You can, of
course, do exactly the same in Ada, but it means that the caller has
to be responsible for managing the memory.)

   But let me give the reasoning from the winning side:  There are
four cases where functions with side-effects are needed. 

   1) Memoizing functions, like random number generators.  This can be
done neatly enough in Ada, but in fact the twin requirements of Annex
A semantics and good performance make this a little tricky.  However,
users are unlikely to have to deal with any case as tough as the A.5.2
generators.  (The tough part is A.5.2(46): "Any storage associated with
an object of type Generator should be reclaimed on exit from the scope
of the object.")

   2) Functions which return more than one unconstrained value.  Again
Ada offers a disciplined way to do this since you can always declare a
record type and return that.  The known special cases in Ada 83 were
dealt with elsewhere, such as with Ada.Task_Identification.Task_ID.

   3) Functions which are operations of an object, with side effects
on that object.  The solution here is to make the complete object type
an access type, and hide that fact completely from outside users.  The
introduction of finalization in Ada 95 vastly simplifies the amount of
work to do this right in Ada 95.

   4) Interfacing to languages which permit functions to modify
parameters directly.  The prime case is PL/I.  (I like PL/I, I've
written a lot of code in PL/I, including parts of three Ada
compilers.)  Of course, PL/I is relatively much less popular than it
was when Ada 83 was standardized.

   So in every case where it is needed, the drawbacks are much less in
Ada 83.  On the other hand, if you do pull a fast one in Ada and write
a function with a side effect, READERS of the code will be very
surprised, and may miss the intent of the function, and certainly the
fact that such a call could have side effects or change its
parameters.  So allowing such functions has a distributed cost in
shops where no functions with side effects are ever written.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 3%]

* Re: is_callable(environment)?
  1998-07-22  0:00  5% is_callable(environment)? Tom Moran
@ 1998-07-23  0:00  5% ` Tucker Taft
  0 siblings, 0 replies; 138+ results
From: Tucker Taft @ 1998-07-23  0:00 UTC (permalink / raw)


Tom Moran (tmoran@bix.com) wrote:

: ... but I wonder
: if I'm just very lucky, or if most compilers take the allowance of
: C.7.1(21) and allow 'caller to return a task_id of the environment
: task, and if is_callable on the environment task becomes false when it
: reaches the end of the main program and before its dependent tasks
: have terminated and library level controlled objects have finalized.

The environment task is a task, so 'Caller, 
Ada.Task_Identification.Current_Task, etc., all need to work on it.

There is also nothing that disallows Is_Callable(env-task-id), so
calling it should be "safe."  However, it is pretty easy to
imagine that the mechanism for waiting for library-level tasks
follows a different path in the run-time system than that used
when exiting an "explicit" task body, so it seems possible that
Is_Callable(env-task) might remain true indefinitely (or perhaps false
indefinitely).  Clearly, you will need to test this out on
each Ada run-time you intend to use.

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[relevance 5%]

* is_callable(environment)?
@ 1998-07-22  0:00  5% Tom Moran
  1998-07-23  0:00  5% ` is_callable(environment)? Tucker Taft
  0 siblings, 1 reply; 138+ results
From: Tom Moran @ 1998-07-22  0:00 UTC (permalink / raw)


An app has a library level task that would like to use a select with a
terminate alternative, but can't since the task must periodically poll
hardware via a delay alternative.  Using
ada.task_identification.is_callable as in
  main_program : task_id;
begin
  accept start_up do
     main_program := start_up'caller;
  end start_up;
...
  loop
     exit when not is_callable(main_program);
     select ...
appears to work on the three compilers I've tried so far, but I wonder
if I'm just very lucky, or if most compilers take the allowance of
C.7.1(21) and allow 'caller to return a task_id of the environment
task, and if is_callable on the environment task becomes false when it
reaches the end of the main program and before its dependent tasks
have terminated and library level controlled objects have finalized.




^ permalink raw reply	[relevance 5%]

* Re: Q:Task Identification ?
    1998-05-08  0:00  6% ` Stephen Leake
@ 1998-05-10  0:00  5% ` Robert Dewar
  1 sibling, 0 replies; 138+ results
From: Robert Dewar @ 1998-05-10  0:00 UTC (permalink / raw)



<<I am using DEC Ada compiler under OpenVMS_AXP v7.1.

Is there any way to obtain task identifier which differs
one task from the others in one program ?
>>


Look at the package Get_Task_Info, which is part of the DEC Ada 83 distribution
for OpenVMS (and is therefore also included in the GNAT OpenVMS implementation
of Ada 95). 

GET_CURRENT_TASK_TYPE_NAME gives the (string) name of the task type

If you have multiple tasks of the same type, then you can use 
GET_CURRENT_TASK_ID which returns a unique NATURAL value to
distinguish them (e.g. convert this number to a decimal digit string).

There is no way to get the name of the task object in DEC Ada (Ada 95
does not guarantee that such a method exists either, but you can
expect Ada.Task_Identification.Image to do something useful (and
in particular with GNAT, you get a unique and usefully informative string,
that deals with arrays of tasks etc.)





^ permalink raw reply	[relevance 5%]

* Re: Q:Task Identification ?
  @ 1998-05-08  0:00  6% ` Stephen Leake
  1998-05-08  0:00  0%   ` Larry Kilgallen
  1998-05-10  0:00  5% ` Robert Dewar
  1 sibling, 1 reply; 138+ results
From: Stephen Leake @ 1998-05-08  0:00 UTC (permalink / raw)



Margarit Nickolov wrote:
> 
> I am using DEC Ada compiler under OpenVMS_AXP v7.1.
> 
> Is there any way to obtain task identifier which differs
> one task from the others in one program ?

see the standard package Ada.Task_Identification

-- Stephe




^ permalink raw reply	[relevance 6%]

* Re: Q:Task Identification ?
  1998-05-08  0:00  6% ` Stephen Leake
@ 1998-05-08  0:00  0%   ` Larry Kilgallen
  0 siblings, 0 replies; 138+ results
From: Larry Kilgallen @ 1998-05-08  0:00 UTC (permalink / raw)



In article <35534370.3F2B8149@gsfc.nasa.gov>, Stephen Leake <stephen.leake@gsfc.nasa.gov> writes:
> Margarit Nickolov wrote:
>> 
>> I am using DEC Ada compiler under OpenVMS_AXP v7.1.
>> 
>> Is there any way to obtain task identifier which differs
>> one task from the others in one program ?
> 
> see the standard package Ada.Task_Identification

That might be the answer for Ada 95, but DEC Ada is Ada 83.

Larry Kilgallen




^ permalink raw reply	[relevance 0%]

* ADA CORE TECHNOLOGIES ANNOUNCES THE RELEASE OF GNAT VERSION 3.10p
@ 1997-09-14  0:00  2% Robert Dewar
  0 siblings, 0 replies; 138+ results
From: Robert Dewar @ 1997-09-14  0:00 UTC (permalink / raw)



Ada Core Technologies has released the following versions of release
3.10p of the GNAT Ada 95 compiler. These versions should be available
shortly on the various mirror sites that provide latest GNAT versions

DEC Unix
HPPA HPUX
x86 Linux
MIPS IRIX
POWER PC AIX
SPARC SOLARIS
SPARC SUNOS
x86 NT/Win95
x86 OS/2
Power PC (Mac) Machten

Corresponding source and documentation releases have also been made.

The following is a brief summary of the new features in 3.10p (in comparison
with the previous 3.09 public release). Ada Core Technologies will continue
to develop the GNAT technology, and make public releases from time to time
reflecting the state of this important developing technology.

For details on commercial support for these and other versions of GNAT, send
mail to sales@gnat.com.

Latest features in GNAT version 3.10
====================================

   Generic units are now compiled. This allows proper handling of some
   complex order of elaboration issues. If you are using gnatmake, then
   generics will be compiled automatically. If you are not using
   gnatmake (e.g. you are using a makefile with make), you may need to
   adjust your build procedures to accomodate this new requirement

   A new tool, gnatls, provides capabilities for listing the units in a
   given compilation environment, together with their status.

   A new set of GNAT library units provides full SPITBOL compatible pattern
   matching capabilities, as well as associative tables and some other
   useful SPITBOL-inspired features. See files g-spitbo.ads, g-spipat.ads,
   g-sptabo.ads, g-sptain.ads, g-stunst.ads.

   A new GNAT unit g-debuti.ads provides some standard debugging utilities
   and capabilities.

   A new Ada child, see a-suteio.ads, provides Text_IO capabilities for
   the Ada.Strings.Unbounded.Unbounded_String type.

   A function File_Exists has been added to GNAT.IO_Aux to test if a
   file exists (without having to open it).

   Deferred constants may now be completed using pragma Import so that
   the value of the constant is supplied by an external unit in some
   language other than Ada.

   A number of missing semantic checks have been added. Most notably, GNAT
   now correctly requires conversions from the anonymous type corresponding
   to an access parameter to a named access type and properly disallows use
   of null literals for anonymous access types.

   A new set of warning messages now allows full diagnosis of possible access
   before elaboration problems at compile time. By systematically eliminating
   the warning messages, it is feasible to ensure that a large application
   cannot possibly run into an access before elaboration, and to ensure this
   in a portable manner.

   The binder now generates a far more friendly elaboration order. In the
   default mode, it guarantees a successful elaboration order, and gives
   an error message if this guarantee is not possible.

   A new attribute, applicable to library units, x'elaborated, returns a
   Boolean value indicating whether X has been elaborated. It is always
   true for preelaborated, pure and predefined units, and also for units
   for which Elaborate_Body is specified. Otherwise it determines if the
   body of the specified unit has been elaborated yet. This is primarily
   intended for use by the compiler itself in checking for access before
   elaboration, but it can be used by user programs.

   The error messages for the case of an operator with incorrectly typed
   operands have been enhanced to give more information about the errors.

   Two tools, gnatpsta and gnatpsys, can be used to generate source language
   representations of packages Standard and System, including all relevant
   constants in numeric form. These are generated by actually looking at
   what the values are (so they are guaranteed to give correct results).

   A new convention Stubbed is available. A stubbed subprogram will cause
   Program_Error to be raised on any call. Furthermore, if you use convention
   Stubbed in a pragma Import, then no body need be supplied for the
   subprogram.

   Entry families constrained by task discriminants are now implemented (this
   combination of features had been overlooked, and was not yet tested by the
   ACVC suite).

   A new function GNAT.OS_Lib.Is_Writable_File determines if a given file
   exists and is writable.

   Pragma Discard_Names is now respected for enumeration types, so that the
   image tables are actually discarded if the pragma applies. 

   A new feature in gnatmake causes any write protected ali files to be
   treated like system files, i.e. when using -f, they will not be recompiled
   unless the -a switch is also used. This allows user libraries to have the
   same status as the Ada runtime library.

   A new switch (-i for in place) for gnatmake requests that gnatmake put
   ali files and object files back in the same place they were found, so
   that gnatmake can be used to automatically update a multi-directory
   program structure.

   Ada.Task_Identification.Image now returns a meaningful image for a task
   based on the variable name used to create the task. This name is also
   available while debugging (via the call interface). The generation of
   these names can be suppressed by using pragma Discard_Names with no
   argument.

   The gnatchop utility now detects and rejects attempts to generate more
   than one copy of a file with the same name unless -w is specified. This
   is particularly useful when using file name krunching, because it means
   that cases of multiple units crunching to the same name are detected.

   In the Solaris version, foreign threads (those created outside Ada) are
   now recognized automatically and converted to Ada tasks for proper
   treatment by the Ada runtime as Ada tasks.

   The switch -gnatN now properly enables possible inlining for all
   subprograms, as though pragma Inline had been specified for every
   possible subprogram. This may improve code quality, but note that
   very large amounts of memory may be needed to compile with this switch.

   The Ada aware features of GDB have been substantially enhanced. GDB now
   understands more Ada data structures. A new command break exception allows
   convenient breakpoints on specified or all exceptions. On many targets,
   tasking handling is greatly improved. A new command info tasks lists the
   status of all tasks in the system. For details see the new GDB manual,
   included in the release, that contains an enhanced section on debugging
   of Ada code.

   Two choices of threads libraries are now offered on Solaris and Linux.
   On Solaris there is a choice of using native Solaris threads or FSU
   threads with the default being native threads.
   On Linux there is a choice of using FSU threads or native Linuxthreads
   with the default being FSU threads.

   On AIX there is a timeslicing option for tasking using the pragma
   Time_Slice. This is using FSU threads.

   The GNAT runtime library now consists of a single archive file, libgnat.a,
   rather than a collection of individual object modules as was the case
   in previous versions of GNAT.

   The adainclude directory is now located at the same level as the adalib
   directory, and the GNU include directory. The adainclude directory was
   formerly at the same level as the bin directory.





^ permalink raw reply	[relevance 2%]

* Re: Recursive Protected types getting deadlocked! (longish)
  1997-09-07  0:00  7% Recursive Protected types getting deadlocked! (longish) Dale Stanbrough
@ 1997-09-08  0:00  7% ` Tucker Taft
  0 siblings, 0 replies; 138+ results
From: Tucker Taft @ 1997-09-08  0:00 UTC (permalink / raw)



Dale Stanbrough (dale@goanna.cs.rmit.EDU.AU) wrote:

: I've written a small semaphore that records the task id of the owner,
: allowing recusive lock taking (i'm looking at how Java tasking works).

: The following code seems to deadlock however. It seems that when a
: 2nd task is woken up on the Queued entry, it does so in the context
: of the first Task (or so the Image function tells me...).

: This to me seems very strange. Is it likely to be an error in Gnat, 
: or is it a misunderstanding on my part as to how this all works...

Any "convenient" thread may perform an entry body (RM95 9.5.3(22)).  
This flexibility can be critical to minimizing unnecessary context 
switches and lock transfers.  Hence, asking for "Current_Task" from
inside an entry body is not useful.  If you need to get the 
identity of the thread which initiated an entry call, use 
the 'Caller attribute (C.7.1(14)).

For example, inside Seize you should use "Seize'Caller"
rather than "Current_Task"; inside Release you should use
"Release'Caller".

: Dale

: -----------------------------
: with semaphores; use semaphores;
: with ada.task_identification; use ada.task_identification;

: procedure main2 is

:    a : recursive_semaphore;

:    task type wow;

:    task body wow is
:    begin
:       A.Seize ;
:       delay 1.0;
:       A.Seize ;

:       delay 1.0;

:       A.release;

:       delay 1.0;
:       A.release;
:   end;

:    task_1 : wow;
:    task_2 : wow;
:     
: begin
:    null;
: end;

: -------------------------
: with Ada.Task_Identification; use Ada.Task_Identification;
: package Semaphores is


:     protected type Recursive_Semaphore is
:         entry     Seize;
:         procedure Release;
:     private
:         entry Queue;
:         Lock_Holder : Task_Id;
:         Held        : Natural := 0;
:     end Recursive_Semaphore;

: end Semaphores;

: --------
: with text_io; use text_io;

: package body Semaphores is
:       protected body Recursive_Semaphore is

:       -----------
:       -- Seize --
:       -----------

:       entry Seize  when True is
:       begin
:          Put_Line ("Seize called by ... " & Image (Current_Task));
:          put_line ("   owner is " & Image (Lock_Holder));
:          if Held /= 0 then
:             -- am i requesting it again?
:             -- If so then increment the count so we know when
:             -- to release it

:             if Lock_Holder = Current_Task then
:                Put_LIne ("Lock being grabbed by " & Image (Current_Task));
:                Held := Held + 1;

:                Put_LIne ("held is now " & Held'img);
:             else
:                Put_Line ( Image (Current_Task) & " requeueing");
:                requeue Queue;
:             end if;

:          else
:             Put_Line (Image (Current_Task) & " grabbing lock");
:             Held := 1;
:             Lock_Holder := Current_Task;
:          end if;

:       end Seize;


:       -------------
:       -- Release --
:       -------------

:       procedure Release is
:       begin
:          Put_Line ("Release called by " & Image (Current_Task));

:          if Held = 0 then
:             -- someone tried to release it when it wasn't held!
:             raise Tasking_Error;

:          elsif Current_Task /= Lock_Holder then
:             -- held, but not by me!
:             raise Tasking_Error;
:          else
:             Held := Held - 1;
:             Put_Line ("   held is now " & Held'img);
:          end if;

:       end Release;
:        

:       -----------
:       -- Queue --
:       -----------

:       --  Queued task manages to get the lock!

:       entry Queue when Held = 0 is
:       begin
:          Put_Line (Image (Current_Task) & " Queue, getting lock");
:          Held := 1;
:          Lock_Holder := Current_Task;

:          put_Line ("image is ...." & Image (Current_Task));
:       end Queue;

:    end Recursive_Semaphore;

: end Semaphores;

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[relevance 7%]

* Recursive Protected types getting deadlocked! (longish)
@ 1997-09-07  0:00  7% Dale Stanbrough
  1997-09-08  0:00  7% ` Tucker Taft
  0 siblings, 1 reply; 138+ results
From: Dale Stanbrough @ 1997-09-07  0:00 UTC (permalink / raw)



I've written a small semaphore that records the task id of the owner,
allowing recusive lock taking (i'm looking at how Java tasking works).

The following code seems to deadlock however. It seems that when a
2nd task is woken up on the Queued entry, it does so in the context
of the first Task (or so the Image function tells me...).

This to me seems very strange. Is it likely to be an error in Gnat, 
or is it a misunderstanding on my part as to how this all works...


Dale

-----------------------------
with semaphores; use semaphores;
with ada.task_identification; use ada.task_identification;

procedure main2 is

   a : recursive_semaphore;

   task type wow;

   task body wow is
   begin
      A.Seize ;
      delay 1.0;
      A.Seize ;

      delay 1.0;

      A.release;

      delay 1.0;
      A.release;
  end;

   task_1 : wow;
   task_2 : wow;
    
begin
   null;
end;

-------------------------
with Ada.Task_Identification; use Ada.Task_Identification;
package Semaphores is


    protected type Recursive_Semaphore is
        entry     Seize;
        procedure Release;
    private
        entry Queue;
        Lock_Holder : Task_Id;
        Held        : Natural := 0;
    end Recursive_Semaphore;

end Semaphores;

--------
with text_io; use text_io;

package body Semaphores is
      protected body Recursive_Semaphore is

      -----------
      -- Seize --
      -----------

      entry Seize  when True is
      begin
         Put_Line ("Seize called by ... " & Image (Current_Task));
         put_line ("   owner is " & Image (Lock_Holder));
         if Held /= 0 then
            -- am i requesting it again?
            -- If so then increment the count so we know when
            -- to release it

            if Lock_Holder = Current_Task then
               Put_LIne ("Lock being grabbed by " & Image (Current_Task));
               Held := Held + 1;

               Put_LIne ("held is now " & Held'img);
            else
               Put_Line ( Image (Current_Task) & " requeueing");
               requeue Queue;
            end if;

         else
            Put_Line (Image (Current_Task) & " grabbing lock");
            Held := 1;
            Lock_Holder := Current_Task;
         end if;

      end Seize;


      -------------
      -- Release --
      -------------

      procedure Release is
      begin
         Put_Line ("Release called by " & Image (Current_Task));

         if Held = 0 then
            -- someone tried to release it when it wasn't held!
            raise Tasking_Error;

         elsif Current_Task /= Lock_Holder then
            -- held, but not by me!
            raise Tasking_Error;
         else
            Held := Held - 1;
            Put_Line ("   held is now " & Held'img);
         end if;

      end Release;
       

      -----------
      -- Queue --
      -----------

      --  Queued task manages to get the lock!

      entry Queue when Held = 0 is
      begin
         Put_Line (Image (Current_Task) & " Queue, getting lock");
         Held := 1;
         Lock_Holder := Current_Task;

         put_Line ("image is ...." & Image (Current_Task));
      end Queue;

   end Recursive_Semaphore;

end Semaphores;




^ permalink raw reply	[relevance 7%]

* Re: Equivalent to C++'s 'this' for tasks?
    1997-05-22  0:00  5% ` Dale Stanbrough
@ 1997-05-22  0:00  5% ` Robert I. Eachus
  1 sibling, 0 replies; 138+ results
From: Robert I. Eachus @ 1997-05-22  0:00 UTC (permalink / raw)



In article <5ltfe8$edr$1@goanna.cs.rmit.edu.au> Dale Stanbrough <dale@goanna.cs.rmit.EDU.AU> writes:

  > If I wanted to create a task...

  > would it be possible in the body of a to construct/obtain
  > a pointer to the task?

   See C.7.1, package Ada.Task_Identification.  If the Ada compiler
you are using doesn't provide this package (it is in the Systems
Programming Annex), then there are other messier solutions.

   However, since this package isn't all that hard to implement, I
suspect that even with an Ada 83 compiler the easiest solution is to
build it yourself.  (You will probably have to look at some
disassembled code to find the right run-time calls if the compiler
implementor doesn't provide that documenation.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 5%]

* Re: Equivalent to C++'s 'this' for tasks?
  @ 1997-05-22  0:00  5% ` Dale Stanbrough
  1997-05-22  0:00  5% ` Robert I. Eachus
  1 sibling, 0 replies; 138+ results
From: Dale Stanbrough @ 1997-05-22  0:00 UTC (permalink / raw)



Robert I. Eachus writes:

"   See C.7.1, package Ada.Task_Identification.  If the Ada compiler
 you are using doesn't provide this package (it is in the Systems
 Programming Annex), then there are other messier solutions.
 
    However, since this package isn't all that hard to implement, I
 suspect that even with an Ada 83 compiler the easiest solution is to
 build it yourself.  (You will probably have to look at some
 disassembled code to find the right run-time calls if the compiler
 implementor doesn't provide that documenation.)"


No, this won't do at all. There is no way to make entry calls from a
task id, so how could the objects that are passed this id query the
state of the task?

I would like something that doesn't require delving into stuff that
the rationale claims is mainly used for building scheduling systems.


Dale




^ permalink raw reply	[relevance 5%]

* Re: Equality operator overloading in ADA 83
  @ 1997-04-22  0:00  3%     ` Robert A Duff
  0 siblings, 0 replies; 138+ results
From: Robert A Duff @ 1997-04-22  0:00 UTC (permalink / raw)



In article <335CAEFE.35DC@elca-matrix.ch>,
Mats Weber  <Mats.Weber@elca-matrix.ch> wrote:
>The same holds for Ada.Strings.Unbounded, and there was some discussion
>on this a year ago or so here in c.l.a. Is anything being done so that
>an AI is issued to ensure this (if AIs still exist) ?

This is AI95-123, which has been approved by the ARG, but not (yet) by
WG9.  I've included it below.  In general, I believe that ACVC tests do
not get written based on AIs until WG9 has approved.

In case anyone's interested, the AI's are stored on
sw-eng.falls-church.va.us, in /public/adaic/standards/95com/ada-issues.

- Bob

!standard 04.05.02 (24)                               97-03-19  AI95-00123/05
!class binding interpretation 96-07-23
!status ARG approved 10-0-2 (subject to editorial review)  96-10-07
!status work item (letter ballot was 6-6-0) 96-10-03
!status ARG approved 8-0-0 (subject to letter ballot) 96-06-17
!status work item 96-04-04
!status received 96-04-04
!priority High
!difficulty Medium
!subject Equality for Composite Types

!summary 96-11-19

The primitive equality operators of language defined types compose
properly, when the type is used as a component type, or a generic actual
type.

For any composite type, the order in which "=" is called for components
is not defined by the language.  Furthermore, if the result is
determined before calling "=" on some components, the language does not
define whether "=" is called on those components.

!question 96-07-23

The following language-defined types are private, and have an explicitly
defined primitive "=" operator:

    System.Address
    Ada.Strings.Maps.Character_Set
    Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String
    Ada.Strings.Unbounded.Unbounded_String
    Ada.Strings.Wide_Maps.Wide_Character_Set
    Ada.Task_Identification.Task_ID

This would seem to imply that the composability of these "=" operators
depends on whether the implementation chooses to implement them as
tagged types, by 4.5.2(14-24):

  14   For a type extension, predefined equality is defined in terms of the
  primitive (possibly user-defined) equals operator of the parent type and of
  any tagged components of the extension part, and predefined equality for any
  other components not inherited from the parent type.

  15   For a private type, if its full type is tagged, predefined equality is
  defined in terms of the primitive equals operator of the full type; if the
  full type is untagged, predefined equality for the private type is that of
  its full type.
  ...
  21   Given the above definition of matching components, the result of the
  predefined equals operator for composite types (other than for those
  composite types covered earlier) is defined as follows:

     22  If there are no components, the result is defined to be True;

     23  If there are unmatched components, the result is defined to be
         False;

     24  Otherwise, the result is defined in terms of the primitive equals
         operator for any matching tagged components, and the predefined
         equals for any matching untagged components.

This would cause portability problems.

Also, in the above definition, what does "in terms of" mean?  For a
composite type, if some parts have an "=" with side effects, does the
language define whether all of these side effects happen, and in what
order?

!recommendation 96-11-16

(See summary.)

!wording 96-07-23

!discussion 97-03-19

Composability of equality means three things:

    1. If a composite type has a component of type T with a user-defined
       equality operator, then the predefined equality of the composite
       type calls the user-defined equality operator of type T (for that
       component).

    2. If an actual type T for a generic formal type has a user-defined
       equality operator, then the predefined equality on the generic
       formal type calls the user-defined equality operator of type T.

    3. If a parent type T has a user-defined equality operator, then the
       predefined equality of a type extension of T calls the
       user-defined equality on T (for the parent part), in addition to
       comparing the extension parts.

Non-composability means that the predefined equality is called for T,
despite the fact that T has a user-defined equality operator.  Of
course, if there is no user-defined equality, then equality always
composes properly.

Number 3 is irrelevant here, since none of the types in question is
(visibly) tagged.

For a private type, if the underlying type is tagged, or if there is no
user-defined equality, then equality composes.  Otherwise, it does not.
(Here, "underlying type" means the full type, or if that comes from a
private type, then the underlying type of *that* type, and so on.)

However, for the private types mentioned in the question, the RM does
not specify whether the underlying type is tagged, nor whether the
equality operator is truly user-defined (as opposed to just being the
normal bit-wise equality).

It is important that the composability of "=" for these types be defined
by the language.  We choose to make them composable.  An implementation
can achieve this by making the full type tagged.  Alternatively, the
implementation could simply use the predefined "=" for these types.
(Alternatively, an implementation could treat these types specially,
making them untagged, but with composable equality.  However, this would
add some complexity to the compiler.)

Here is an analysis of implementation concerns for each type in
question:

    - System.Address: The intent is for this type to directly represent 
      a hardware address.  Therefore, it is probably not feasible to
      to implement it as a tagged type.  The simplest implementation of
      equality of Addresses is thus the normal bit-wise equality.  This
      is what most users would expect, anyway.

      On certain segmented architectures, it is possible for two
      different addresses to point to the same location.  The same thing
      can happen due to memory mapping, on many machines.  Such
      addresses will typically compare unequal, despite the fact that
      they point to the same location.

    - Ada.Strings.Maps.Character_Set: A typical implementation will use
      an array of Booleans, so bit-wise equality will be used, so it
      will compose.

    - Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String: Two
      reasonable implementations are: (1) Nul-out the unused
      characters, and use bit-wise equality, and (2) use a tagged type
      with a user-defined equality.  Either way, equality will compose.
      This is, admittedly, a slight implementation burden, because it
      rules out an untagged record with user-defined equality.

    - Ada.Strings.Unbounded.Unbounded_String: A tagged (controlled) type
      will normally be necessary anyway, for storage reclamation.  In a
      garbage-collected implementation, a tagged type is not strictly
      necessary, but we choose to require composability anyway.

    - Ada.Strings.Wide_Maps.Wide_Character_Set: Some sort of data
      structure built out of access types is necessary anyway, so the
      extra overhead of composability is not a serious problem; the
      implementation can simply make the full type tagged.

    - Ada.Task_Identification.Task_ID: This will typically be a
      pointer-to-TCB of some sort (access-to-TCB, or
      index-into-table-of-TCB's).  In any case, bit-wise equality will
      work, so equality will compose.

As to the second question, the RM clearly does not define any order of
calling "=" on components, nor does it say whether the results are
combined with "and" or "and then".  Equality operators with side effects
are questionable in any case, so we allow implementations freedom to do
what is most convenient and/or most efficient.  Consider equality of a
variant record: The implementation might first check that the
discriminants are equal, and if not, skip the component-by-component
comparison.  Alternatively, the implementation might first compare the
common elements, and *then* check the discriminants.  A third
possibility is to first compare some portions with a bit-wise equality,
and then (conditionally) call user-defined equality operators on the
other components.  All of these implementations are valid.

!appendix 97-03-19

...




^ permalink raw reply	[relevance 3%]

* Task_ID through different executions
@ 1996-06-18  0:00  5% Sergio Silva
  1996-06-18  0:00  4% ` Tucker Taft
  0 siblings, 1 reply; 138+ results
From: Sergio Silva @ 1996-06-18  0:00 UTC (permalink / raw)



Hello,

I have been looking at the LRM for the foolwing info but I can't find an
exact answer. Does anybody know it?

I need to find out if Ada.Task_Identification.Current_Task  and
Entry'Caller return the same value in different executions?

I am trying to use them to monitor rendezvous sequences and eventually 
reproduce such sequences so I need them to return the same value. 

In the case it is implementation dependent: I am using gnat 3.0.3 on
SUN/OS 4.1.4 and on Solaris 2.5

Regards,

Sergio
 


------------------------------------------------------------------------
Sergio Silva-Barradas
Dip.to di Elettronica e Informazione            
Politecnico di Milano                      Ph:       +(39)(2) 2399 3638 
P.zza Leonardo da Vinci 32                 Fax:      +(39)(2) 2399 3411 
I20133 Milan, Italy                        e-mail: silva@elet.polimi.it




^ permalink raw reply	[relevance 5%]

* Re: Task_ID through different executions
  1996-06-18  0:00  5% Task_ID through different executions Sergio Silva
@ 1996-06-18  0:00  4% ` Tucker Taft
  0 siblings, 0 replies; 138+ results
From: Tucker Taft @ 1996-06-18  0:00 UTC (permalink / raw)



Sergio Silva (silva@elet.polimi.it) wrote:
: Hello,

: I have been looking at the LRM for the following info but I can't find an
: exact answer. Does anybody know it?

: I need to find out if Ada.Task_Identification.Current_Task  and
: Entry'Caller return the same value in different executions?

There is no guarantee that these values will be the same from
one execution to the next.

: I am trying to use them to monitor rendezvous sequences and eventually 
: reproduce such sequences so I need them to return the same value. 

You might be better off defining your own task attribute (see RM95 C.7.2), 
and using the Task_ID to fetch the attribute.  You could presumably
assign task attributes in a repeatable manner.

: In the case it is implementation dependent: I am using gnat 3.0.3 on
: SUN/OS 4.1.4 and on Solaris 2.5

: Sergio Silva-Barradas
: Dip.to di Elettronica e Informazione            
: Politecnico di Milano                      Ph:       +(39)(2) 2399 3638 
: P.zza Leonardo da Vinci 32                 Fax:      +(39)(2) 2399 3411 
: I20133 Milan, Italy                        e-mail: silva@elet.polimi.it

-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Cambridge, MA  USA




^ permalink raw reply	[relevance 4%]

* Re: gnat debuggers?
  @ 1996-04-18  0:00  6% ` Robert Dewar
  0 siblings, 0 replies; 138+ results
From: Robert Dewar @ 1996-04-18  0:00 UTC (permalink / raw)


Patrik worried that GDB did not have the following feature:

2) Setting breakpoints on exception occurence.

This is possible, see gnatinfo.txt for documentation (breakpoint __gnat_raise)

As for breakpoints in tasks, for me it works to set a conditional breakpoint
that tests current_task. You have to with ada.task_identification in your
program.





^ permalink raw reply	[relevance 6%]

* Re: How to print Task_ID type? (GNAT SunOS)
  1996-04-03  0:00  5% How to print Task_ID type? (GNAT SunOS) Greg Bond
@ 1996-04-04  0:00  5% ` Robert Dewar
  1996-04-04  0:00  0%   ` Greg Bond
  0 siblings, 1 reply; 138+ results
From: Robert Dewar @ 1996-04-04  0:00 UTC (permalink / raw)


Greg asks

"Can one of the Text_IO packages be used to print a Task_ID type (or any
access Integer type for that matter...)? I'm using GNAT under SunOS
which defines the Task_ID type in Ada.Task_Identification as private,
but implements it as an Integer access type. If one of the Text_IO
packages won't work, then what will?"

Certainly not, private means private, neither you nor Text_IO can
mess with a private type in another package. Well you culd use
unchecked conversion after looking in the private part, but that
would NOT be pleasant code.

What do you really need to do here? Doesn't the Image function for
Task_Id do what you want? That's what it's for!

   function Image (T : Task_Id) return String;





^ permalink raw reply	[relevance 5%]

* Re: How to print Task_ID type? (GNAT SunOS)
  1996-04-04  0:00  5% ` Robert Dewar
@ 1996-04-04  0:00  0%   ` Greg Bond
  0 siblings, 0 replies; 138+ results
From: Greg Bond @ 1996-04-04  0:00 UTC (permalink / raw)


Robert Dewar wrote:
> 
> Greg asks
> 
> "Can one of the Text_IO packages be used to print a Task_ID type (or any
> access Integer type for that matter...)? I'm using GNAT under SunOS
> which defines the Task_ID type in Ada.Task_Identification as private,
> but implements it as an Integer access type. If one of the Text_IO
> packages won't work, then what will?"
> 
> Certainly not, private means private, neither you nor Text_IO can
> mess with a private type in another package. Well you culd use
> unchecked conversion after looking in the private part, but that
> would NOT be pleasant code.
> 
> What do you really need to do here? Doesn't the Image function for
> Task_Id do what you want? That's what it's for!
> 
>    function Image (T : Task_Id) return String;


Indeed it is. My oversight. This function does not handle the more 
general problem I posed though. Is there a general facility for printing 
access types? The GNAT implementation of the Image function above is a 
system level (i.e. platform dependent) routine specifically for the 
Task_ID type. The only Ada references I've got are Barnes for Ada 95 and 
the ALRM, both of which are woefully inadequate on the topic of Ada I/O.





--
* Greg Bond                         * Dept. of Electrical Eng.  
* email: bond@ee.ubc.ca             * Univ. of British Columbia      
* voice: (604) 822 0899             * 2356 Main Mall                 
* fax:   (604) 822 5949             * Vancouver, BC              
* web: http://www.ee.ubc.ca/~bond   * Canada, V6T 1Z4




^ permalink raw reply	[relevance 0%]

* How to print Task_ID type? (GNAT SunOS)
@ 1996-04-03  0:00  5% Greg Bond
  1996-04-04  0:00  5% ` Robert Dewar
  0 siblings, 1 reply; 138+ results
From: Greg Bond @ 1996-04-03  0:00 UTC (permalink / raw)


Can one of the Text_IO packages be used to print a Task_ID type (or any 
access Integer type for that matter...)? I'm using GNAT under SunOS 
which defines the Task_ID type in Ada.Task_Identification as private, 
but implements it as an Integer access type. If one of the Text_IO 
packages won't work, then what will?

--
* Greg Bond                         * Dept. of Electrical Eng.  
* email: bond@ee.ubc.ca             * Univ. of British Columbia      
* voice: (604) 822 0899             * 2356 Main Mall                 
* fax:   (604) 822 5949             * Vancouver, BC              
* web: http://www.ee.ubc.ca/~bond   * Canada, V6T 1Z4




^ permalink raw reply	[relevance 5%]

* Re: 32 and 64 bit floats
       [not found]               ` <dewar.820957348@schonberg>
@ 1996-01-08  0:00  4%             ` Keith Thompson
  0 siblings, 0 replies; 138+ results
From: Keith Thompson @ 1996-01-08  0:00 UTC (permalink / raw)


In <dewar.820957348@schonberg> dewar@cs.nyu.edu (Robert Dewar) writes:
> Keith says
> 
> "I think we both agree that the sentence is poorly worded.  In any case,
> it's obsolete.  AI-00459, which was approved by the ARG and WG9 and
> applies to Ada 83 implementations, states that predefined integer types
> may have the same range, and RM95-3.5.4(25) says, "Different predefined
> integer types are allowed to have the same base range.""
> 
> Oops, no! AI's do not make anything in the RM obsolete, they merely
> point you to the right interpretation, so the existence of AI-00459 just
> goes to prove that my interpretatoin was right, and yours wrong (it's
> sort of like papal councils telling you after the fact whether you have
> sinned :-)

Well, that's the theory behind the AI's, but in practice some of them
do contradict (and effectively make obsolete) clear wording in the
reference manual.  I won't try to extend the papal council analogy.  8-)}

For example, the Ada 83 RM clearly states that integer division by zero
raises Numeric_Error (assuming the check is not suppressed), yet AI-00387
allows and encourages implementations to raise Constraint_Error instead.
Similarly for Ada 95, AI-00101 (not yet formally approved) says that
Ada.Task_Identification.Abort_Task's parameter is of mode "in", even
though the RM clearly shows its mode as "in out".

Furthermore, the wording of AI-00459 (the one that allows different
predefined integer types to have the same range) does not attempt to claim
that the original wording in the Ada 83 RM allows this interpretation.
It merely justifies the change on the basis that the restriction serves
no useful purpose.

I'm not saying that this is bad, merely that not all AIs are really just
"interpretations" of the original text, or even of the original intent.

I once heard that either Algol or Algol 68 had a similar mechanism for
issuing official interpretations of the language standard.  The committee
once issued an "interpretation" stating that, in a particular sentence
in the reference manual, the word "is" shall be interpreted to mean
"is not".  (I don't have a source for this story, and I can't guarantee
its accuracy.)

In the unlikely event that anyone else is interested in this, the text
of AI-00459 is at
<ftp://sw-eng.falls-church.va.us/public/AdaIC/standards/83com/ai-00459-bi.wa>.

-- 
Keith Thompson (The_Other_Keith)  kst@thomsoft.com (kst@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
Et tu, Barada Nikto?




^ permalink raw reply	[relevance 4%]

Results 1-138 of 138 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
     [not found]     <DKCBsL.6yq@irvine.com>
     [not found]     ` <dewar.820254515@schonberg>
     [not found]       ` <30e6cca7.34638660@news.onramp.net>
     [not found]         ` <DKHEsJ.68M@thomsoft.com>
     [not found]           ` <dewar.820553584@schonberg>
     [not found]             ` <DKrB37.E1E@thomsoft.com>
     [not found]               ` <dewar.820957348@schonberg>
1996-01-08  0:00  4%             ` 32 and 64 bit floats Keith Thompson
1996-04-03  0:00  5% How to print Task_ID type? (GNAT SunOS) Greg Bond
1996-04-04  0:00  5% ` Robert Dewar
1996-04-04  0:00  0%   ` Greg Bond
1996-04-17  0:00     gnat debuggers? Patrik Sj�gren
1996-04-18  0:00  6% ` Robert Dewar
1996-06-18  0:00  5% Task_ID through different executions Sergio Silva
1996-06-18  0:00  4% ` Tucker Taft
1997-04-21  0:00     Equality operator overloading in ADA 83 Manuel Wenger
1997-04-22  0:00     ` Matthew Heaney
1997-04-22  0:00       ` Mats Weber
1997-04-22  0:00  3%     ` Robert A Duff
1997-05-21  0:00     Equivalent to C++'s 'this' for tasks? Dale Stanbrough
1997-05-22  0:00  5% ` Dale Stanbrough
1997-05-22  0:00  5% ` Robert I. Eachus
1997-09-07  0:00  7% Recursive Protected types getting deadlocked! (longish) Dale Stanbrough
1997-09-08  0:00  7% ` Tucker Taft
1997-09-14  0:00  2% ADA CORE TECHNOLOGIES ANNOUNCES THE RELEASE OF GNAT VERSION 3.10p Robert Dewar
1998-05-06  0:00     Q:Task Identification ? Margarit Nickolov
1998-05-08  0:00  6% ` Stephen Leake
1998-05-08  0:00  0%   ` Larry Kilgallen
1998-05-10  0:00  5% ` Robert Dewar
1998-07-22  0:00  5% is_callable(environment)? Tom Moran
1998-07-23  0:00  5% ` is_callable(environment)? Tucker Taft
1998-09-27  0:00     Future Ada language revisions? bpr5549
1998-10-02  0:00  3% ` Robert I. Eachus
1998-10-07  0:00     tasking grave
1998-10-07  0:00     ` an error in tasking grave
1998-10-07  0:00  7%   ` Frank Ecke
     [not found]     <vhir9n7rj0e.fsf@orvarodd.ifi.uio.no>
1999-06-19  0:00     ` Aborting Keith Thompson
1999-06-21  0:00  5%   ` Aborting Jean-Pierre Rosen
1999-06-24  0:00 14% Purposes of Ada.Task_Identification Jim Rogers
1999-06-24  0:00 11% ` Robert I. Eachus
1999-06-24  0:00  7% ` Tucker Taft
1999-06-24  0:00 11% ` tmoran
2000-01-27  0:00  8% Operator visibility/inheritance for derived private type? (Repost) Rod Chapman
2000-01-28  0:00  7% ` Tucker Taft
2000-08-30  0:00     gcov in multithreaded applications daelen
2000-08-30  0:00  5% ` Robert A Duff
2000-08-31 21:58  5% ` Jean-Pierre Rosen
2001-03-08 22:38     Generic Formal Parameter for a Task Type James Rogers
2001-03-09  0:16     ` Pat Rogers
2001-03-09  3:34       ` James Rogers
2001-03-09  4:26  6%     ` Pat Rogers
2001-03-09  4:58  0%       ` James Rogers
2001-03-09  4:20     Beard, Frank
2001-03-09  5:24     ` James Rogers
2001-03-09 21:50  5%   ` Tucker Taft
2001-03-10  0:14  4%     ` Robert C. Leif, Ph.D.
2001-03-12 16:14  0%       ` Tucker Taft
2001-03-10  3:25  0%     ` James Rogers
2001-03-12 15:33  0%       ` Stephen Leake
2001-03-09 22:53  0% Beard, Frank
2002-01-31  2:49  1% ACT announces availability of GNAT 3.14p Robert Dewar
2002-02-04 23:15     How do I end the program? David Starner
2002-02-06  3:16  8% ` Steve Doiel
2002-02-06  7:46  0%   ` Dale Stanbrough
2002-02-06  8:40  0%     ` Martin Dowie
2002-07-12 17:13 12% Ada.Task_Identification.Abort_Task (Environment_Task) ; Marin David Condic
2002-07-13 13:45  6% ` Simon Wright
2002-07-13 22:12  7%   ` Robert Dewar
2002-07-13 14:12  6% ` Robert A Duff
2002-07-15 12:52  5%   ` Marin David Condic
2002-07-15 23:31  7%     ` tmoran
2002-07-18 21:32  7%     ` Robert A Duff
2002-07-19 12:55  5%       ` Marin David Condic
2002-07-20 17:18  6%         ` Robert A Duff
2002-07-22 12:53  5%           ` Marin David Condic
2002-07-23  6:08  7%             ` tmoran
2002-07-23 13:02  4%               ` Marin David Condic
2002-07-24  8:34  7%                 ` Lutz Donnerhacke
2002-07-24 13:58  6%                   ` Marin David Condic
2002-07-24  8:35  7%                 ` Fabien Garcia
2002-07-24 23:20  7%                 ` Dmitry A.Kazakov
2002-07-25  0:43  6%                 ` Robert Dewar
2002-07-25  1:04  7%                 ` tmoran
2002-07-16 20:43 13% ` Simon Wright
     [not found]     <c923f575.0208130627.479e0b3d@posting.google.com>
2002-08-14  6:41  7% ` stupid question: how can I finish a program? Emil Moholth
2002-08-14 14:00  0%   ` Marin D. Condic
2002-08-14  7:37  7% ` Martin Dowie
2003-01-09 10:33     String library with garbage collection? I. Marks
2003-01-09 19:50     ` Craig Carey
2003-01-09 20:46       ` James S. Rogers
2003-01-10  0:14         ` Craig Carey
2003-01-10  3:52           ` James S. Rogers
2003-01-10 11:35  5%         ` Craig Carey
2003-02-04 12:04  7% gnat Dynamic Priority Dispatching Anomalies Ian Broster
2003-04-29 22:04  4% Suspicious reentrant semaphore Jano
2003-04-30  8:06     ` Dmitry A. Kazakov
2003-05-01 12:33  6%   ` Jano
2003-04-30 17:39  5% ` Randy Brukardt
2003-07-18  9:36     terminate applications christoph.grein
2003-07-18 10:54  8% ` Jeffrey Creem
2003-07-18 11:51  0%   ` Marin David Condic
2003-07-18 15:18         ` Jeffrey Creem
2003-07-19 15:44           ` Marin David Condic
2003-07-20  2:03             ` Robert I. Eachus
2003-07-20 11:04               ` Marin David Condic
2003-07-20 17:53                 ` Robert I. Eachus
2003-07-21 12:02                   ` Marin David Condic
2003-07-21 20:31                     ` Robert I. Eachus
2003-07-22 12:11                       ` Marin David Condic
2003-07-22 12:26                         ` Arnaud Charlet
2003-07-22 12:36                           ` Marin David Condic
2003-07-22 13:23                             ` Arnaud Charlet
2003-07-22 23:23                               ` Marin David Condic
2003-07-23  4:02  6%                             ` Robert I. Eachus
2003-07-23 12:28                                   ` Marin David Condic
2003-07-24 16:06  6%                                 ` Robert I. Eachus
2003-07-23 21:24  6% Priority Ceiling Stephan Heinemann
2003-07-31 19:40  8% No_Abort_Statements Stephan Heinemann
2004-01-04  5:58     To raise an exception in task and handle/catch it in outer-block Frank
2004-01-03 22:03     ` tmoran
2004-01-04 20:58       ` Frank
2004-01-10  2:20         ` Craig Carey
2004-01-10 21:05  3%       ` Frank
2004-05-20 14:47     Task discriminants Dave Levy
2004-05-20 17:30     ` Martin Krischik
2004-05-21  7:57  5%   ` Dmitry A. Kazakov
2004-06-04 12:59  0%     ` Andersen Jacob Sparre
2004-11-04 15:23  5% generic and visibility mferracini
2004-11-05  3:39  0% ` John Woodruff
2005-02-16 20:35     Finalization of a record containing a task Bj?rn
2005-02-16 20:49     ` Stephen Leake
2005-02-16 21:20       ` Adrien Plisson
2005-02-17  9:13         ` Dmitry A. Kazakov
2005-02-18  0:13           ` Robert A Duff
2005-02-18  2:34  7%         ` Randy Brukardt
2005-06-22 18:08  5% task time-out&abort e.coli
2005-06-22 18:40  0% ` Dmitry A. Kazakov
2005-06-22 19:44  0% ` Mark Lorenzen
2007-05-08 21:55     Finalization of static package variables Manuel Collado
2007-05-09 15:15     ` Adam Beneschan
2007-05-09 22:00       ` Manuel Collado
2007-05-09 23:27         ` Adam Beneschan
2007-05-16  0:36           ` Randy Brukardt
2007-05-16 14:06             ` Adam Beneschan
2007-05-16 19:10  7%           ` Randy Brukardt
2007-05-22  4:41  0%             ` christoph.grein
2008-05-28 19:14     [Ravenscar] run tasks on events Sebastian Hanigk
2008-05-30  7:26     ` Niklas Holsti
2008-05-30  8:57       ` Sebastian Hanigk
2008-05-30 10:47         ` Niklas Holsti
2008-05-30 11:59  6%       ` stefan-lucks
2009-08-02 12:13     exit a program Autoscontro difettoso
2009-08-02 14:38  6% ` Robert A Duff
2009-12-04 11:09     gnat: Execution_Time is not supported in this configuration singo
2009-12-04 12:10  5% ` Georg Bauhaus
2009-12-07  8:08  0%   ` singo
2010-12-27 18:26  5% An Example for Ada.Execution_Time anon
2011-11-23  1:50     Class with task destructor Rego, P.
2011-11-23  2:44  4% ` Adam Beneschan
2011-11-23  8:35     ` Dmitry A. Kazakov
2011-11-23  9:05       ` Simon Wright
2011-11-30  1:11         ` Rego, P.
2011-11-30  2:21           ` Adam Beneschan
2011-11-30  8:41             ` Dmitry A. Kazakov
2011-12-01  0:35  4%           ` Randy Brukardt
2012-01-23 19:59     "C - like: THIS" pointer to a task type inside a task function Dmitry A. Kazakov
2012-01-23 22:17  7% ` tmoran
2012-01-25 10:11     task abortion tonyg
2012-01-25 10:43     ` Dmitry A. Kazakov
2012-01-26  9:12  5%   ` tonyg
2012-01-26 16:47  0%     ` Anh Vo
2012-01-31 13:25  0%       ` tonyg
2012-04-06 15:20     In case you need to remember mockturtle
2012-04-06 20:09  5% ` anon
2012-10-30 22:03     Tasking troubles, unexpected termination Shark8
2012-10-30 23:01     ` Adam Beneschan
2012-10-31  1:05       ` Anh Vo
2012-10-31  2:17  6%     ` Shark8
2012-12-05 13:53     Task with access to itself? Jacob Sparre Andersen
2012-12-06  9:38  6% ` Egil Høvik
2012-12-06 19:53  0%   ` Adam Beneschan
2013-08-09 16:50     4 beginner's questions on the PL Ada Emanuel Berg
2013-08-09 17:09     ` Adam Beneschan
2013-08-09 19:01       ` Randy Brukardt
2013-08-09 21:38  7%     ` Emanuel Berg
2013-08-09 22:00  0%       ` Jeffrey Carter
2013-08-09 22:16             ` Emanuel Berg
2013-08-10  0:39               ` Anh Vo
2013-08-10  1:24                 ` Emanuel Berg
2013-08-10  6:16  5%               ` Simon Wright
2013-08-12 17:39  6%               ` Anh Vo
2013-08-12 19:57  0%                 ` Simon Wright
2013-08-12 20:13  0%                   ` Anh Vo
2013-08-12 19:47  5%         ` Randy Brukardt
2014-06-15 10:10     Termination of periodic tasks Natasha Kerensikova
2014-06-15 16:54     ` Jeffrey Carter
2014-06-16 14:02       ` Natasha Kerensikova
2014-06-16 17:08         ` Jeffrey Carter
2014-06-17  6:57           ` Natasha Kerensikova
2014-06-17  7:37             ` Dmitry A. Kazakov
2014-06-17  7:47               ` Natasha Kerensikova
2014-06-17  8:45                 ` Dmitry A. Kazakov
2014-06-17  9:00                   ` Natasha Kerensikova
2014-06-17 12:55                     ` Dmitry A. Kazakov
2014-06-17 14:51                       ` J-P. Rosen
2014-06-17 16:44                         ` Dmitry A. Kazakov
2014-06-17 20:00  4%                       ` Randy Brukardt
2014-06-17 20:16  0%                         ` Jeffrey Carter
2014-10-14  1:17     passing messages between the tasks compguy45
2014-10-14  1:49     ` Adam Beneschan
2014-10-14 19:43       ` Shark8
2014-10-14 20:42         ` Jeffrey Carter
2014-10-14 21:08           ` compguy45
2014-10-14 22:22  4%         ` Shark8
2014-12-15 16:52     Access parameters and accessibility Michael B.
2014-12-16  7:45     ` Randy Brukardt
2014-12-16 19:46       ` Michael B.
2014-12-17  2:02         ` Adam Beneschan
2014-12-17 23:18  4%       ` Randy Brukardt
2014-12-18  0:56  0%         ` Robert A Duff
2014-12-18  1:17  0%           ` Randy Brukardt
2015-04-06 17:27  5% ANN: STM32F4 GNAT Run Time Systems 20150406 Simon Wright
2016-02-07 22:45  5% ANN: Cortex GNAT RTS 20160207 Simon Wright
2016-03-14 17:42  5% ANN: Cortex GNAT RTS 20160314 Simon Wright
2016-04-21 10:23  6% timer_server triggers Task_Termination handler Per Dalgas Jakobsen
2016-05-22 14:20  4% ANN: Cortex GNAT RTS 20160522 Simon Wright
2017-07-25 23:19  2% Real tasking problems with Ada Robert Eachus
2017-07-26 19:42     ` sbelmont700
2017-07-27  2:00  5%   ` Robert Eachus
2017-08-01  4:41  0% ` Randy Brukardt
2017-08-02  3:44  4%   ` Robert Eachus
2017-08-03  4:16  0%     ` Randy Brukardt
2017-08-03  8:03  0%     ` Simon Wright
2017-08-04 23:16  0%       ` Randy Brukardt
2017-09-21 18:14     Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders Victor Porton
2017-09-21 21:30     ` AdaMagica
2017-09-22 12:16       ` Victor Porton
2017-09-22 19:25         ` Simon Wright
2017-09-22 22:15           ` Victor Porton
2017-09-23  8:09             ` Dmitry A. Kazakov
2017-09-23  9:16  5%           ` Jeffrey R. Carter
2017-10-28 20:02  4% Read-write mutex sometimes fails on deadlock pascal.malaise
2017-12-01 21:39     How to tell whether program finalization can be suppressed Simon Wright
2017-12-01 22:43  4% ` Randy Brukardt
2017-12-02 11:12  0%   ` AdaMagica
2018-04-15 13:40     Finalization of library level tasks Dmitry A. Kazakov
2018-04-15 14:02     ` Jeffrey R. Carter
2018-04-15 14:12       ` Dmitry A. Kazakov
2018-04-15 14:54         ` Jeffrey R. Carter
2018-04-15 15:15           ` Dmitry A. Kazakov
2018-04-15 15:46             ` AdaMagica
2018-04-15 17:17               ` AdaMagica
2018-04-15 17:40                 ` Dmitry A. Kazakov
2018-04-15 19:32  7%               ` Egil H H
2018-04-15 20:09  0%                 ` Dmitry A. Kazakov
2018-04-25 23:49  0%                   ` Randy Brukardt
2018-04-16  5:19                   ` J-P. Rosen
2018-04-16  7:30                     ` Dmitry A. Kazakov
2018-04-16  7:55                       ` J-P. Rosen
2018-04-16  8:13                         ` Dmitry A. Kazakov
2018-04-16  8:32                           ` J-P. Rosen
2018-04-16 15:26                             ` Dmitry A. Kazakov
2018-04-17  9:51                               ` AdaMagica
2018-04-17 12:31                                 ` Dmitry A. Kazakov
2018-04-17 15:37                                   ` Jeffrey R. Carter
2018-04-17 15:57                                     ` Dmitry A. Kazakov
2018-04-17 20:55                                       ` J-P. Rosen
2018-04-17 21:23                                         ` Dmitry A. Kazakov
2018-04-18  5:26                                           ` J-P. Rosen
2018-04-26  0:02  5%                                         ` Randy Brukardt
2018-04-25 23:46  5%         ` Randy Brukardt
2020-01-30  8:55     Last chance handler on a PC ahlan
2020-01-30 19:35     ` ahlan
2020-01-30 20:02  5%   ` Jeffrey R. Carter
2020-01-30 20:26  0%     ` Niklas Holsti
2020-06-10 11:14  6% How to terminate all running tasks? Gilbert Gosseyn
2020-06-10 12:12  0% ` Niklas Holsti

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