From: Randy Brukardt on 24 Feb 2010 18:48 Am 22.02.2010, 02:51 Uhr, schrieb Bj�rn Persson <bjorn(a)rombobj�rn.se>: > I had intended to switch from Charles to Ada.Containers, but I changed my > mind when I learned that Ada.Containers can't even be read by multiple > tasks at once. For the record, we've studied this several times and have always concluded that hidden synchronization is dangerous. That is, synchronization should be explicit. Beyond that, it is impossible to come up with a reasonable definition of what should be locked -- it really depends on the use of the containers. In the case of the containers, task safety of iterators and similar features is something that defies a reasonable definition. The problem gets worse if you include features used together (such as using First and Next to create a loop of some sort). We'd probably need to make the locks visible in order for them to be useful. It's easy to wrap container operations in a protected object, and that is always allowed (such operations are not potentially blocking). That allows tailoring the locking for the actual usage, and even hiding the actual container to prevent abuse. Randy.
From: Georg Bauhaus on 25 Feb 2010 04:22 Randy Brukardt schrieb: > Am 22.02.2010, 02:51 Uhr, schrieb Bj�rn Persson <bjorn(a)rombobj�rn.se>: > >> I had intended to switch from Charles to Ada.Containers, but I changed my >> mind when I learned that Ada.Containers can't even be read by multiple > > tasks at once. > It's easy to wrap container operations in a protected object, and that is > always allowed (such operations are not potentially blocking). That allows > tailoring the locking for the actual usage, and even hiding the actual > container to prevent abuse. Indeed, arent' there advantages in hiding data stores like Ada.Containers behind some facade, whether the use is sequential or not: everything else always smells of exposed internal data structures, or lack of abstraction. There need to be good reasons for using List, Set, etc. as is, I think. Just like there should be good reasons to expose arrays.
From: Stephen Leake on 25 Feb 2010 07:23 "Randy Brukardt" <randy(a)rrsoftware.com> writes: > Am 22.02.2010, 02:51 Uhr, schrieb Björn Persson <bjorn(a)rombobjörn.se>: > >> I had intended to switch from Charles to Ada.Containers, but I changed my >> mind when I learned that Ada.Containers can't even be read by multiple > > tasks at once. > > For the record, we've studied this several times and have always concluded > that hidden synchronization is dangerous. That is, synchronization should be > explicit. Beyond that, it is impossible to come up with a reasonable > definition of what should be locked -- it really depends on the use of the > containers. I agree with this, but I think the OP was implying that you needed locking even for read-only access of Ada.Containers from multiple tasks; is that true? I don't see why it should be; each task declares its own cursors, which don't interfere with each other. Of course, there's nothing enforcing the read-only, so this is not very safe. -- -- Stephe
From: Alex R. Mosteo on 25 Feb 2010 09:16 Stephen Leake wrote: > "Randy Brukardt" <randy(a)rrsoftware.com> writes: > >> Am 22.02.2010, 02:51 Uhr, schrieb Björn Persson <bjorn(a)rombobjörn.se>: >> >>> I had intended to switch from Charles to Ada.Containers, but I changed >>> my mind when I learned that Ada.Containers can't even be read by >>> multiple >> > tasks at once. >> >> For the record, we've studied this several times and have always >> concluded that hidden synchronization is dangerous. That is, >> synchronization should be explicit. Beyond that, it is impossible to come >> up with a reasonable definition of what should be locked -- it really >> depends on the use of the containers. > > I agree with this, but I think the OP was implying that you needed > locking even for read-only access of Ada.Containers from multiple > tasks; is that true? I don't see why it should be; each task declares > its own cursors, which don't interfere with each other. I think that the downward closure subprograms update some flags inside the container. E.g., in gnat doubly linked lists, within the Query_Element: procedure Query_Element (Position : Cursor; Process : not null access procedure (Element : Element_Type)); Pretty read-only, it seems, but inside you find: declare C : List renames Position.Container.all'Unrestricted_Access.all; B : Natural renames C.Busy; L : Natural renames C.Lock; begin B := B + 1; L := L + 1; (...) So, basically, yes, even certain read-only uses are not thread-safe (Element would be, at least in gnat implementation). Never though of this before, but even wrapping a call to that in a protected function would be dangerous, since protected functions are concurrent? And that's a procedure with only "in" arguments, which would be callable from such a function. Am I right here?
From: sjw on 25 Feb 2010 15:19 On Feb 25, 2:16 pm, "Alex R. Mosteo" <alejan...(a)mosteo.com> wrote: > Never though of this before, but even wrapping a call to that in a protected > function would be dangerous, since protected functions are concurrent? And > that's a procedure with only "in" arguments, which would be callable from > such a function. > > Am I right here? I believe you are: LRM 9.5.1(1), "protected functions provide concurrent read-only access to the data". My normal mode of operation is to wrap the use of the Container (OK, Booch Component!) in a package and use a lock to ensure single- threaded access, with the Container outside any PO.
First
|
Prev
|
Pages: 1 2 Prev: ANNOUNCE: XML EZ OUT and Log4Ada in Debian Next: Mine Detector in Fedora |