diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2014-07-16 15:57:28 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2014-07-16 15:57:28 +0200 |
commit | 8942b30c7c1a6500f56bdf93ba96c54da370ba8c (patch) | |
tree | 28cb986e265381c95622992e637affa7b3e12cb0 /gcc/ada/a-coinho-shared.adb | |
parent | d6f824bf7f4d82ab9b96b31d56b88fa1f2b1f166 (diff) | |
download | gcc-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.adb | 125 |
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; |