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=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,2c6139ce13be9980 X-Google-Attributes: gidfac41,public X-Google-Thread: 103376,3d3f20d31be1c33a X-Google-Attributes: gid103376,public X-Google-Thread: 1108a1,2c6139ce13be9980 X-Google-Attributes: gid1108a1,public X-Google-Thread: f43e6,2c6139ce13be9980 X-Google-Attributes: gidf43e6,public From: leew@micrologic.com (Lee Webber) Subject: Re: Safety-critical development in Ada and Eiffel Date: 1997/08/19 Message-ID: <33f9d570.10895527@wizard.pn.com>#1/1 X-Deja-AN: 265302111 References: <33f455bb.475760@wizard.pn.com> Organization: Pioneer Global Newsgroups: comp.object,comp.software-eng,comp.lang.ada,comp.lang.eiffel Date: 1997-08-19T00:00:00+00:00 List-Id: On Tue, 19 Aug 1997 05:15:59 GMT, donh@syd.csa.com.au (Don Harrison) wrote: >Lee Webber wrote: > >:On Thu, 14 Aug 1997 07:38:08 GMT, donh@syd.csa.com.au (Don Harrison) >:wrote: >:>various design strategies can be applied to minimise locking. >: ^^^^^^^^^^^^^^^^^^^ >: >:I would be interested in your expanding on this. > >Looks like you think your bogometer's gone off again. :) In spades. >:In particular, how would you implement this in SCOOP: >: >: gain exclusive access to A >: perform time-consuming work using A and local resources >: gain exclusive access to A and B jointly >: perform work using A, B and local resources computed above >: release A, retain B >: perform time-consuming work using B and local resources >: computed above >: release access to B >: >:making sure that neither A nor B is held when it is not needed. >:(You may assume that all competing processes attempt to acquire A and B in >:the order above -- otherwise there is no solution other than the >:trivial that avoids deadlock.) > >The solution I'm thinking of would use: > > - A staged approach in which intermediate data is computed. > - Express messages to yield to higher "priority" threads. > - A transaction-based approach to apply the results at the end on > successful completion. > >I don't have the time to thrash out the details, but it should work and should >be safe. > I'll help you out, then. It can't be done under SCOOP, **assuming as I did in my problem that each stage uses the results from the previous ones so you can't rearrange the code**. The reason for this is simple: SCOOP ties acquisition and release of objects to entry and exit from subroutines. Therefore, the objects will be obtained and released LIFO; you can't release objects other than in the opposite order you acquired them. This avoids deadlocks, but at the possible cost of efficiency, as in my example. Express messages don't help. In order to seize control of an object prematurely, you have to cause an exception in the context of the holder, thus destroying that context. (Checkpoints, and other such hacks to allow resumption of processing at the same call level as the exception, are treated here with the disdain they deserve.) Attempting to rebuild the context involves reacquiring all the objects and rolling back their states[1], thus making the efficiency problem far worse. Nor can you say that compiler optimization should allow the implicit release of A as soon as the last feature call on it is complete. The problem here is that B may call A, and the client may be depending on that call being synchronized with the calls it itself made -- a guarantee made by SCOOP because the call is made in the scope of the client's routine. In order to make that guarantee, and unless you want to do system flow analysis, you can't release any separate objects until all of them have been used for the last time in the routine. [1] This raises a serious problem in the use of challenge/yield. It is true that the exception in the separate object being invoked allows it to restore its invariant. But what its client probably wants to do is to roll back the state of the object to what it was at the entry to the routine -- and it doesn't own the object to tell it to do that. (You could clone the object at the top of the routine just in case, but cloning a separate object is not my idea of fun.)