comp.lang.ada
 help / color / mirror / Atom feed
* Protected Adjust?
@ 2009-04-17  7:52 Dimonax
  2009-04-17  8:40 ` Dmitry A. Kazakov
  2009-04-17 18:21 ` sjw
  0 siblings, 2 replies; 3+ messages in thread
From: Dimonax @ 2009-04-17  7:52 UTC (permalink / raw)


How does one encapsulate a Controlled type inside a Protected type such 
that Initialize, Finalize, and Ajust can be done concurrently?

Basically I'm locking a Variable into a Cache, and I don't want that 
variable being copied in and out of the Cache. i.e. Each Task has to be 
able to operate on the variable in-place.

I'm using the low level mlock()/munlock() system calls to create the 
cache.(Locks the memory to RAM and prevents paging/swapping).

So far, I'm thinking this...

Pragma Profile(Ravenscar);
with Ada.Finalization;  --Yeah, this works even with Ravenscar profile. --
package mutators is

	type Item_Type is tagged null record;

	type Mutable is new Ada.Finalization.Controlled with private;

private

	type Item_Pointer is access Item_Type;

	type Mutable is new Ada.Finalization.Controlled with record
		Mutable_Item : Item_Pointer;
	end record;

	-- Catchy type name eh? ;-> --
	Protected Type Mutual_Excluder is
		-- This procedure is called by Initialize --
		procedure Create(Item : in Item_Type); 
		
		-- This procedure is called by Adjust. --
		procedure Update(Item : in out Item_Pointer);

		-- This procedure is called by Finalize --
		procedure Destroy(Item : in out Item_Pointer);

	private

		Item_Holder : Item_Type;
		Item_Location : Item_Pointer := Item_Holder'Access;

	end Mutual_Excluder;

	procedure Initialize(Mutable_Object : in out Mutable);
	procedure Adjust(Mutable_Object : in out Mutable);
	procedure Finalize(Mutable_Object : in out Mutable);

end mutators;


Should I have the seperate Item_Type and handle that seperately? Or 
should I just pass the entire Mutable Object in and out of the protected 
procedures?

The goal of this excercise is to be able to use the Adjust procedure from 
different tasks exclusively.

Tips, advice?

Freejack




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

* Re: Protected Adjust?
  2009-04-17  7:52 Protected Adjust? Dimonax
@ 2009-04-17  8:40 ` Dmitry A. Kazakov
  2009-04-17 18:21 ` sjw
  1 sibling, 0 replies; 3+ messages in thread
From: Dmitry A. Kazakov @ 2009-04-17  8:40 UTC (permalink / raw)


On Fri, 17 Apr 2009 07:52:57 GMT, Dimonax wrote:

> How does one encapsulate a Controlled type inside a Protected type such 
> that Initialize, Finalize, and Ajust can be done concurrently?

Hmm, you cannot copy protected objects, they are limited.

> Basically I'm locking a Variable into a Cache, and I don't want that 
> variable being copied in and out of the Cache. i.e. Each Task has to be 
> able to operate on the variable in-place.

OK. So the model is that a variable is processed in-place while other
participants are blocked?

A full list of alternatives might look like:

1. Safe copying in/out and dealing concurrently with a copy (non-blocking)
2. Dealing with the object from a protected action (non-blocking)
3. Locking, dealing with the object outside protected action, unlocking
(blocking)

(all alternatives are exposed to various problems, so the choice really
depends on what you are doing)

> I'm using the low level mlock()/munlock() system calls to create the 
> cache.(Locks the memory to RAM and prevents paging/swapping).

I cannot tell how this is related to protected objects.

> So far, I'm thinking this...
> 
> Pragma Profile(Ravenscar);
> with Ada.Finalization;  --Yeah, this works even with Ravenscar profile. --
> package mutators is
> 
> 	type Item_Type is tagged null record;
> 
> 	type Mutable is new Ada.Finalization.Controlled with private;
> 
> private
> 
> 	type Item_Pointer is access Item_Type;
> 
> 	type Mutable is new Ada.Finalization.Controlled with record
> 		Mutable_Item : Item_Pointer;
> 	end record;
> 
> 	-- Catchy type name eh? ;-> --
> 	Protected Type Mutual_Excluder is
> 		-- This procedure is called by Initialize --
> 		procedure Create(Item : in Item_Type); 
> 		
> 		-- This procedure is called by Adjust. --
> 		procedure Update(Item : in out Item_Pointer);
> 
> 		-- This procedure is called by Finalize --
> 		procedure Destroy(Item : in out Item_Pointer);
> 
> 	private
> 
> 		Item_Holder : Item_Type;
> 		Item_Location : Item_Pointer := Item_Holder'Access;
> 
> 	end Mutual_Excluder;
> 
> 	procedure Initialize(Mutable_Object : in out Mutable);
> 	procedure Adjust(Mutable_Object : in out Mutable);
> 	procedure Finalize(Mutable_Object : in out Mutable);
> 
> end mutators;

This looks like 2.

> Should I have the seperate Item_Type and handle that seperately? Or 
> should I just pass the entire Mutable Object in and out of the protected 
> procedures?

Tagged types are by-reference ones. That means you can safely pass Mutable
or Mutable'Class to a procedure, that would not copy it.

> The goal of this excercise is to be able to use the Adjust procedure from 
> different tasks exclusively.
>
> Tips, advice?

The problem with your approach is that Adjust is not an assignment, it is
only a part of. So, whatever you put into Adjust in order to interlock it,
that will be executed after a bitwise copy of a representation of Mutable
has been *concurrently* made.

There are many solutions. If you are aiming at 2 or 3, you could add one
more level of indirection. E.g. smart pointers:

   type Mutable is private; -- Pointer to an implementation
private
   type Mutable_Implementation is new Ada.Finalization.Controlled with ...;

   type Mutable is new Ada.Finalization.Controlled with record
       Ptr : access Mutable_Implementation'Class;
   end record;
   overriding procedure Adjust (Object : in out Mutable);
   ...

package body

   protected Mutex is
      procedure Do_Adjust (Ref : in out Mutable'Class);
   end Mutex;

   procedure Adjust (Object : in out Mutable) is
   begin
      Mutex.Do_Adjust (Object);
   end Adjust;
   
   protected body Mutex is
      procedure Do_Adjust (Ref : in out Mutable'Class) is
      begin  -- Deep copy semantics
         if Ref.Ptr /= null then
            Ref.Ptr := new Mutable_Implementation'Class'(Ref.Ptr.all);
         end if;
      end Do_Adjust;
   end Mutex;

The drawback of this solution, which is 2, is that potentially lengthy
operations like allocation of new Mutable_Implementation in the heap and
then copying it, are performed on the context of a protected action. If
that is too long, you should consider 3.

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



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

* Re: Protected Adjust?
  2009-04-17  7:52 Protected Adjust? Dimonax
  2009-04-17  8:40 ` Dmitry A. Kazakov
@ 2009-04-17 18:21 ` sjw
  1 sibling, 0 replies; 3+ messages in thread
From: sjw @ 2009-04-17 18:21 UTC (permalink / raw)


On Apr 17, 8:52 am, Dimonax <dimo...@nospam.net> wrote:
> How does one encapsulate a Controlled type inside a Protected type such
> that Initialize, Finalize, and Ajust can be done concurrently?

> package mutators is

>         Protected Type Mutual_Excluder is
>                 -- This procedure is called by Initialize --
>                 procedure Create(Item : in Item_Type);
>
>                 -- This procedure is called by Adjust. --
>                 procedure Update(Item : in out Item_Pointer);
>
>                 -- This procedure is called by Finalize --
>                 procedure Destroy(Item : in out Item_Pointer);

There are no instances of Mutual_Excluder so how do these procedures
get called?

> The goal of this excercise is to be able to use the Adjust procedure from
> different tasks exclusively.

Initialize, Adjust, Finalize are only relevant as part of the
implementation of creation/assignment/copying/destruction. I don't see
how you propose to use mutators.Mutable in practice, it's hard to
comment further without some sort of use case.



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

end of thread, other threads:[~2009-04-17 18:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-17  7:52 Protected Adjust? Dimonax
2009-04-17  8:40 ` Dmitry A. Kazakov
2009-04-17 18:21 ` sjw

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