aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/a-coinho-shared.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2014-07-16 15:57:28 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2014-07-16 15:57:28 +0200
commit8942b30c7c1a6500f56bdf93ba96c54da370ba8c (patch)
tree28cb986e265381c95622992e637affa7b3e12cb0 /gcc/ada/a-coinho-shared.adb
parentd6f824bf7f4d82ab9b96b31d56b88fa1f2b1f166 (diff)
downloadgcc-8942b30c7c1a6500f56bdf93ba96c54da370ba8c.zip
gcc-8942b30c7c1a6500f56bdf93ba96c54da370ba8c.tar.gz
gcc-8942b30c7c1a6500f56bdf93ba96c54da370ba8c.tar.bz2
[multiple changes]
2014-07-16 Vadim Godunko <godunko@adacore.com> * a-coinho-shared.adb (Adjust): Create copy of internal shared object and element when source container is locked. (Copy): Likewise. (Query_Element): Likewise. (Update_Element): Likewise. (Constant_Reference): Likewise. Raise Constraint_Error on attempt to get reference for empty holder. (Reference): Likewise. 2014-07-16 Thomas Quinot <quinot@adacore.com> * exp_ch4.adb (Find_Hook_Context): New subprogram, extracted from Process_Transient_Oject. * exp_ch4.ads: Ditto. * exp_ch9.adb (Build_Class_Wide_Master): Insert the _master declaration as an action on the topmost enclosing expression, not on a possibly conditional subexpreession. From-SVN: r212645
Diffstat (limited to 'gcc/ada/a-coinho-shared.adb')
-rw-r--r--gcc/ada/a-coinho-shared.adb125
1 files changed, 106 insertions, 19 deletions
diff --git a/gcc/ada/a-coinho-shared.adb b/gcc/ada/a-coinho-shared.adb
index defdf3a..be45c90 100644
--- a/gcc/ada/a-coinho-shared.adb
+++ b/gcc/ada/a-coinho-shared.adb
@@ -57,7 +57,20 @@ package body Ada.Containers.Indefinite_Holders is
overriding procedure Adjust (Container : in out Holder) is
begin
if Container.Reference /= null then
- Reference (Container.Reference);
+ if Container.Busy = 0 then
+ -- Container is not locked, reuse existing internal shared object.
+
+ Reference (Container.Reference);
+ else
+ -- Otherwise, create copy of both internal shared object and
+ -- element.
+
+ Container.Reference :=
+ new Shared_Holder'
+ (Counter => <>,
+ Element =>
+ new Element_Type'(Container.Reference.Element.all));
+ end if;
end if;
Container.Busy := 0;
@@ -113,16 +126,34 @@ package body Ada.Containers.Indefinite_Holders is
------------------------
function Constant_Reference
- (Container : aliased Holder) return Constant_Reference_Type
- is
- Ref : constant Constant_Reference_Type :=
- (Element => Container.Reference.Element.all'Access,
- Control => (Controlled with Container'Unrestricted_Access));
- B : Natural renames Ref.Control.Container.Busy;
+ (Container : aliased Holder) return Constant_Reference_Type is
begin
- Reference (Ref.Control.Container.Reference);
- B := B + 1;
- return Ref;
+ if Container.Reference = null then
+ raise Constraint_Error with "container is empty";
+
+ elsif Container.Busy = 0
+ and then not System.Atomic_Counters.Is_One
+ (Container.Reference.Counter)
+ then
+ -- Container is not locked and internal shared object is used by
+ -- other container, create copy of both internal shared object and
+ -- element.
+
+ Container'Unrestricted_Access.Reference :=
+ new Shared_Holder'
+ (Counter => <>,
+ Element => new Element_Type'(Container.Reference.Element.all));
+ end if;
+
+ declare
+ Ref : constant Constant_Reference_Type :=
+ (Element => Container.Reference.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access));
+ begin
+ Reference (Ref.Control.Container.Reference);
+ Ref.Control.Container.Busy := Ref.Control.Container.Busy + 1;
+ return Ref;
+ end;
end Constant_Reference;
----------
@@ -133,10 +164,21 @@ package body Ada.Containers.Indefinite_Holders is
begin
if Source.Reference = null then
return (Controlled with null, 0);
- else
+ elsif Source.Busy = 0 then
+ -- Container is not locked, reuse internal shared object.
+
Reference (Source.Reference);
return (Controlled with Source.Reference, 0);
+ else
+ -- Otherwise, create copy of both internal shared object and elemet.
+
+ return
+ (Controlled with
+ new Shared_Holder'
+ (Counter => <>,
+ Element => new Element_Type'(Source.Reference.Element.all)),
+ 0);
end if;
end Copy;
@@ -224,6 +266,19 @@ package body Ada.Containers.Indefinite_Holders is
begin
if Container.Reference = null then
raise Constraint_Error with "container is empty";
+
+ elsif Container.Busy = 0
+ and then not System.Atomic_Counters.Is_One
+ (Container.Reference.Counter)
+ then
+ -- Container is not locked and internal shared object is used by
+ -- other container, create copy of both internal shared object and
+ -- element.
+
+ Container'Unrestricted_Access.Reference :=
+ new Shared_Holder'
+ (Counter => <>,
+ Element => new Element_Type'(Container.Reference.Element.all));
end if;
B := B + 1;
@@ -284,15 +339,34 @@ package body Ada.Containers.Indefinite_Holders is
end Reference;
function Reference
- (Container : aliased in out Holder) return Reference_Type
- is
- Ref : constant Reference_Type :=
- (Element => Container.Reference.Element.all'Access,
- Control => (Controlled with Container'Unrestricted_Access));
+ (Container : aliased in out Holder) return Reference_Type is
begin
- Reference (Ref.Control.Container.Reference);
- Container.Busy := Container.Busy + 1;
- return Ref;
+ if Container.Reference = null then
+ raise Constraint_Error with "container is empty";
+
+ elsif Container.Busy = 0
+ and then not System.Atomic_Counters.Is_One
+ (Container.Reference.Counter)
+ then
+ -- Container is not locked and internal shared object is used by
+ -- other container, create copy of both internal shared object and
+ -- element.
+
+ Container.Reference :=
+ new Shared_Holder'
+ (Counter => <>,
+ Element => new Element_Type'(Container.Reference.Element.all));
+ end if;
+
+ declare
+ Ref : constant Reference_Type :=
+ (Element => Container.Reference.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access));
+ begin
+ Reference (Ref.Control.Container.Reference);
+ Ref.Control.Container.Busy := Ref.Control.Container.Busy + 1;
+ return Ref;
+ end;
end Reference;
---------------------
@@ -387,6 +461,19 @@ package body Ada.Containers.Indefinite_Holders is
begin
if Container.Reference = null then
raise Constraint_Error with "container is empty";
+
+ elsif Container.Busy = 0
+ and then not System.Atomic_Counters.Is_One
+ (Container.Reference.Counter)
+ then
+ -- Container is not locked and internal shared object is used by
+ -- other container, create copy of both internal shared object and
+ -- element.
+
+ Container'Unrestricted_Access.Reference :=
+ new Shared_Holder'
+ (Counter => <>,
+ Element => new Element_Type'(Container.Reference.Element.all));
end if;
B := B + 1;