From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,853d46c8ab5c7ada X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news2.google.com!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!209.197.12.242.MISMATCH!nx01.iad01.newshosting.com!newshosting.com!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed.arcor.de!newsspool3.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Protected Adjust? Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Fri, 17 Apr 2009 10:40:42 +0200 Message-ID: NNTP-Posting-Date: 17 Apr 2009 10:40:43 CEST NNTP-Posting-Host: 899f8279.newsspool4.arcor-online.net X-Trace: DXC=j:N7D^IcW;nPKPPVf;4hUj4IUKkgb@`JWFTfHUel X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:5479 Date: 2009-04-17T10:40:43+02:00 List-Id: 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