comp.lang.ada
 help / color / mirror / Atom feed
* pragma Thread_Local_Storage on record?
@ 2016-03-01 13:45 hanslad
  2016-03-01 14:44 ` Florian Weimer
  2016-03-01 15:52 ` J-P. Rosen
  0 siblings, 2 replies; 7+ messages in thread
From: hanslad @ 2016-03-01 13:45 UTC (permalink / raw)



Hello,
 I am trying to use the pragma Thread_Local_Storage on a record as follows:
In specification file:

...
   package Local_Buffers is new Buffers(Any_Worker);
   package Local_Mailboxes is new Local_Buffers.Mailboxes;
   use Local_Buffers;
   use Local_Mailboxes;
   
   type Core is record
      Wait_Queue : Any_Buffer;
      Core_No    : UInt32;
      Current    : WorkerId ;
      Parent     : WorkerId ;
      Msgs       : UInt64;
   end record;
...

and body file goes like this:

...

   Curr_Core : Core;
   pragma Volatile(Curr_Core);
   pragma Thread_Local_Storage( Curr_Core);
...

I get the following errors:

cores.adb:27:04: Thread_Local_Storage variable "Curr_Core" is improperly initialized
cores.adb:27:04: only allowed initialization is explicit "null" or static expression

What am I doing wrong here?
If the code snippets I provided is not sufficient for to see the real problem, please give me a hint and I will provide more code.

Thanks!

HP 

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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 13:45 pragma Thread_Local_Storage on record? hanslad
@ 2016-03-01 14:44 ` Florian Weimer
  2016-03-01 15:22   ` hanslad
  2016-03-01 15:52 ` J-P. Rosen
  1 sibling, 1 reply; 7+ messages in thread
From: Florian Weimer @ 2016-03-01 14:44 UTC (permalink / raw)


>    type Core is record
>       Wait_Queue : Any_Buffer;
>       Core_No    : UInt32;
>       Current    : WorkerId ;
>       Parent     : WorkerId ;
>       Msgs       : UInt64;
>    end record;

> I get the following errors:
>
> cores.adb:27:04: Thread_Local_Storage variable "Curr_Core" is improperly initialized
> cores.adb:27:04: only allowed initialization is explicit "null" or static expression
>
> What am I doing wrong here?
> If the code snippets I provided is not sufficient for to see the
> real problem, please give me a hint and I will provide more code.

I suspect that one of the components of type Core is itself a record
and has a component which is not statically initialized.

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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 14:44 ` Florian Weimer
@ 2016-03-01 15:22   ` hanslad
  2016-03-01 15:55     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 7+ messages in thread
From: hanslad @ 2016-03-01 15:22 UTC (permalink / raw)



> I suspect that one of the components of type Core is itself a record
> and has a component which is not statically initialized.

Indeed, the Wait_Queue is a synchronized interface:

generic
   type Element is private;
package Buffers is
   type Buffer is synchronized interface;
   type Any_Buffer is access all Buffer'Class;
   Procedure Put(Buf: in out Buffer; Item: in Element)
   is abstract;
   Procedure Get(Buf: in out Buffer; Item: out Element)
   is abstract;
end Buffers; 

===============================================================

with Buffers;
generic
package Buffers.Mailboxes is
   type Buffer_Store is array(Positive range <>) of Element;

   protected type MailBox(Max_Capacity : Positive) is
        new Buffer with
      overriding entry Put(Item : in Element);
      overriding entry Get(Item : out Element);
   private
      First : Positive := 1;
      Last : Positive := Max_Capacity;
      Number_In_Buffer : Natural := 0;
      Box_Store        : Buffer_Store(1 .. Max_Capacity);
   end MailBox;
end Buffers.Mailboxes;
====================================================================
package body Buffers.Mailboxes is
   protected body MailBox is
      entry Get(Item : out Element)
        when Number_In_Buffer /= 0 is
      begin
         Item := Box_Store(First);
         First := First mod Max_Capacity + 1;
         Number_In_Buffer := Number_In_Buffer - 1;
      end Get;

      entry Put(Item : in Element)
        when Number_In_Buffer /= Max_Capacity is
      begin
         Last := Last mod Max_Capacity + 1;
         Box_Store(Last):= Item;
         Number_In_Buffer := Number_In_Buffer + 1;
      end Put;

      function Buffer_Capacity return Positive is
      begin
         return Number_In_Buffer;
      end Buffer_Capacity;
   end MailBox;
end Buffers.Mailboxes;

Any idea on how I could implement such buffer in a Thread local data structure(record)?

HP 


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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 13:45 pragma Thread_Local_Storage on record? hanslad
  2016-03-01 14:44 ` Florian Weimer
@ 2016-03-01 15:52 ` J-P. Rosen
  1 sibling, 0 replies; 7+ messages in thread
From: J-P. Rosen @ 2016-03-01 15:52 UTC (permalink / raw)


Le 01/03/2016 14:45, hanslad@gmail.com a écrit :
>  I am trying to use the pragma Thread_Local_Storage on a record as follows:
Hmmm... Gnat's RM is not crystal clear, but it says:
"The variable may not have default initialization, and if there is an
explicit initialization, it must be either null for an access variable,
or a static expression for a scalar variable."

This seems to indicate that the variable should be access or scalar
only, so not a record.

However, why do you need this non-portable, system-dependent, feature?
Apparently, this is intended only to allow managing foreign (non-Ada)
threads from an Ada program, or if task attributes are too slow for you.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 15:22   ` hanslad
@ 2016-03-01 15:55     ` Dmitry A. Kazakov
  2016-03-01 16:31       ` hanslad
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry A. Kazakov @ 2016-03-01 15:55 UTC (permalink / raw)


On 01/03/2016 16:22, hanslad@gmail.com wrote:
>
>> I suspect that one of the components of type Core is itself a record
>> and has a component which is not statically initialized.

[..]

I don't see how his could be useful for a messages queue which is 
normally shared between several tasks rather than owned by any. The 
latter looks like a low-level implementation-motivated design.

> Any idea on how I could implement such buffer in a Thread local data structure(record)?

A typical solution is Ada.Task_Attributes instantiated with an access 
type to the object. The object is allocated on demand (access 
dereference by the owner task).

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


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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 15:55     ` Dmitry A. Kazakov
@ 2016-03-01 16:31       ` hanslad
  2016-03-01 17:03         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 7+ messages in thread
From: hanslad @ 2016-03-01 16:31 UTC (permalink / raw)


> I don't see how his could be useful for a messages queue which is 
> normally shared between several tasks rather than owned by any. The 
> latter looks like a low-level implementation-motivated design.

To explain a bit more: This is just an experiment on implement a small framework where a set of tasks(one per core) handles a sent of workers that are messaged by other workers (actor style... I think). The reason for using Thread_Local_Storage is for performance)I read that somewhere that it could be a performance gain using that). The idea is that other workers(handled by other tasks) are sending messages to workers, the workers are at the same time added to the queue of workers, ready for action. I dont know if this makes any sense... :-). If this idea has obvious flaws, please feel free to comment.


> A typical solution is Ada.Task_Attributes instantiated with an access 
> type to the object. The object is allocated on demand (access 
> dereference by the owner task).

I have considered this, but wanted to try the Thread_Local_Storage pragma for performance reasons.

Thanks.



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

* Re: pragma Thread_Local_Storage on record?
  2016-03-01 16:31       ` hanslad
@ 2016-03-01 17:03         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 7+ messages in thread
From: Dmitry A. Kazakov @ 2016-03-01 17:03 UTC (permalink / raw)


On 2016-03-01 17:31, hanslad@gmail.com wrote:
>> I don't see how his could be useful for a messages queue which is
>> normally shared between several tasks rather than owned by any. The
>> latter looks like a low-level implementation-motivated design.
>
> To explain a bit more: This is just an experiment on implement a small
> framework where a set of tasks(one per core) handles a sent of workers
> that are messaged by other workers (actor style... I think). The reason
> for using Thread_Local_Storage is for performance)I read that somewhere
> that it could be a performance gain using that). The idea is that other
> workers(handled by other tasks) are sending messages to workers, the
> workers are at the same time added to the queue of workers, ready for
> action. I dont know if this makes any sense... :-). If this idea has
> obvious flaws, please feel free to comment.

One problem is that you will have to manage worker tasks.

Then you will have to advertise the worker's messages buffer anyway to 
make it visible outside. That would make allocation of the buffer in the 
local task storage useless. If the buffer is known outside it could live 
outside as well. Moreover that would be safer because it will guarantee 
that the buffer reference never gets dangled, e.g. when its owner task 
dies prematurely.

Regarding worker management, a preferable design is to decouple 
producers and consumers (of jobs in this case). That is the producer 
advertises its jobs on some blackboard and consumers (workers) take jobs 
from the blackboard when they are free. All know the blackboard and 
nobody knows anybody else.

>> A typical solution is Ada.Task_Attributes instantiated with an access
>> type to the object. The object is allocated on demand (access
>> dereference by the owner task).
>
> I have considered this, but wanted to try the Thread_Local_Storage
> pragma for performance reasons.

Whatever performance difference might exist it is negligible compared to 
the time when a worker is busy. So a queue look up time is of no 
concern, otherwise, the whole design is bogus, e.g. flooding workers 
with near to zero time jobs.

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


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

end of thread, other threads:[~2016-03-01 17:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-01 13:45 pragma Thread_Local_Storage on record? hanslad
2016-03-01 14:44 ` Florian Weimer
2016-03-01 15:22   ` hanslad
2016-03-01 15:55     ` Dmitry A. Kazakov
2016-03-01 16:31       ` hanslad
2016-03-01 17:03         ` Dmitry A. Kazakov
2016-03-01 15:52 ` J-P. Rosen

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