From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id EF9C33849AD6 for ; Thu, 16 May 2024 09:26:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EF9C33849AD6 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EF9C33849AD6 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::333 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715851585; cv=none; b=Q4iQbRs6ZszXQE7+LzT8/H7KH0MbLCt0IvqxliWsuhD3LeF9AaB0/7G9yt6zMHD/awDWgGhoGq0CWM1PatfywKk0O7B2oaEzxPCb28Rq5GARYOGvkcKWb2KG6zt7e37HwiZibWwOPgk4MvJY0D8DW5JNofBx2e9C3zm0RgFD0oU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715851585; c=relaxed/simple; bh=pLIuMwf6LFPlUFANmrsecKtuKYoCskeF7J/YGZC/Is8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=OA2Hoyxn/5J7H/8JGN3CzxtamAXwLZP5YecBedK1UzYw5qpcZX6Cx3BncvM5u6pcWP+tQ8fyxgrw1WCTg028EBP8WQOFAFCMp9TmwzGg0sly6GI77khiNdHTr+KGrcT6OdVnL7AbHfHQj+j8tPGYVenVrkbZerv8aPahthAmrCg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-4201986d60aso26895995e9.3 for ; Thu, 16 May 2024 02:26:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1715851576; x=1716456376; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KgZAKgRhkVrRnFahRFcF+82AETRcGYjgyPWc3Td0Utg=; b=X6MV6Vc5V1rO1n76GuJAc5lVs7j50rlB11lNW9ba7wfyL6wLJOsydv7xG+Kd5cy3wm Vw45gYUVXycnttt9/fo4RWjpHCKJG9TBksUIwbLGcjF3Kzu/p3KUG3LA9U3G8gtwf1Uk k88lyMiZZ9nCmFlnClD1cWHvTdOB4aXGMNJbTGH8rhkMld4nwpQttNcGnOM/3NnBfKxy 1c4+oVkvNPaVKUhYJuBlcxB+7oRjq0WrkdefAd+Z5DM9L3AXZ4pnmcS2HDXAEde/8CMT yTm0dulSzKPcsgOG0DoduQ7EzQNxMSa0HpF7TKX8cAapnnpjguBZS2ejNVHx0zyXP994 rdzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715851576; x=1716456376; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KgZAKgRhkVrRnFahRFcF+82AETRcGYjgyPWc3Td0Utg=; b=feuYa9Y0mtuxNFqNq/7VyMIaYp6m1hmEaEsXzDv+So17PwBc0oKtuHPxXbjWTdoJyf 6jhIR9VXni7sZyD7v43vatxokGVRNDgOJ6eptOu8QZb54MCK97uURdqdQlAxrN6Zc5Cr 2iWfBcLFcPKt9bZ+cCsGk4F52kp1LAqiF0rvkd1aVkKCnv1fHkj/YihYCE2vQYJKgfA4 qN4nQGkqekup8DAuuNF4MBb2qpRh5U4USAKO19v6k2cfD9kMg2G+M7GsOxdHM38LeJJe EXTZWvWo16wV/TNZmb2CoOv2ux40xwbDd1H8jm9MOCkFT1CLXPMBNgi3QnRrb0ae0xiU K6pQ== X-Gm-Message-State: AOJu0YxVmrHMWzTsaREvQbH3X92RYTTnFZVgxUp9aIqivNSED7y3e57+ xRqP1mW4IQWia/dtocMaqXWSFqgV/FLcPcCpmTz3YwXqvFI2tV3HPJtbwm+BssJ+k+AZVadwnos = X-Google-Smtp-Source: AGHT+IH7oaCA6AQecZgBrfsRohniN3XUGvVJZQMzWOSxKowkS3WM3KL0vGcToDt1/UCcGXRpQkKUsA== X-Received: by 2002:a05:600c:2042:b0:41c:8123:f8a5 with SMTP id 5b1f17b1804b1-41feab40c4bmr132854665e9.23.1715851576598; Thu, 16 May 2024 02:26:16 -0700 (PDT) Received: from poulhies-Precision-5550.telnowedge.local (lmontsouris-659-1-24-67.w81-250.abo.wanadoo.fr. [81.250.175.67]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41fd10cf8besm135802635e9.1.2024.05.16.02.26.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 May 2024 02:26:16 -0700 (PDT) From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [COMMITTED 10/35] ada: Implement per-finalization-collection spinlocks Date: Thu, 16 May 2024 11:25:39 +0200 Message-ID: <20240516092606.41242-10-poulhies@adacore.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240516092606.41242-1-poulhies@adacore.com> References: <20240516092606.41242-1-poulhies@adacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Eric Botcazou This changes the implementation of finalization collections from using the global task lock to using per-collection spinlocks. Spinlocks are a good fit in this context because they are very cheap and therefore can be taken with a fine granularity only around the portions of code implementing the shuffling of pointers required by attachment and detachment actions. gcc/ada/ * libgnat/s-finpri.ads (Lock_Type): New modular type. (Collection_Node): Add Enclosing_Collection component. (Finalization_Collection): Add Lock component. * libgnat/s-finpri.adb: Add clauses for System.Atomic_Primitives. (Attach_Object_To_Collection): Lock and unlock the collection. Save a pointer to the enclosing collection in the node. (Detach_Object_From_Collection): Lock and unlock the collection. (Finalize): Likewise. (Initialize): Initialize the lock. (Lock_Collection): New procedure. (Unlock_Collection): Likewise. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/libgnat/s-finpri.adb | 79 +++++++++++++++++++++++++++++------- gcc/ada/libgnat/s-finpri.ads | 12 +++++- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/gcc/ada/libgnat/s-finpri.adb b/gcc/ada/libgnat/s-finpri.adb index 8026b3fb284..09f2761a5b9 100644 --- a/gcc/ada/libgnat/s-finpri.adb +++ b/gcc/ada/libgnat/s-finpri.adb @@ -32,7 +32,8 @@ with Ada.Exceptions; use Ada.Exceptions; with Ada.Unchecked_Conversion; -with System.Soft_Links; use System.Soft_Links; +with System.Atomic_Primitives; use System.Atomic_Primitives; +with System.Soft_Links; use System.Soft_Links; package body System.Finalization_Primitives is @@ -42,7 +43,21 @@ package body System.Finalization_Primitives is new Ada.Unchecked_Conversion (Address, Collection_Node_Ptr); procedure Detach_Node_From_Collection (Node : not null Collection_Node_Ptr); - -- Removes a collection node from its associated finalization collection + -- Remove a collection node from its associated finalization collection. + -- Calls to the procedure with a Node that has already been detached have + -- no effects. + + procedure Lock_Collection (Collection : in out Finalization_Collection); + -- Lock the finalization collection. Upon return, the caller owns the lock + -- to the collection and no other call with the same actual parameter will + -- return until a corresponding call to Unlock_Collection has been made by + -- the caller. This means that it is not possible to call Lock_Collection + -- more than once on a collection without a call to Unlock_Collection in + -- between. + + procedure Unlock_Collection (Collection : in out Finalization_Collection); + -- Unlock the finalization collection, i.e. relinquish ownership of the + -- lock to the collection. --------------------------- -- Add_Offset_To_Address -- @@ -69,7 +84,7 @@ package body System.Finalization_Primitives is To_Collection_Node_Ptr (Object_Address - Header_Size); begin - Lock_Task.all; + Lock_Collection (Collection); -- Do not allow the attachment of controlled objects while the -- associated collection is being finalized. @@ -89,22 +104,23 @@ package body System.Finalization_Primitives is pragma Assert (Finalize_Address /= null, "primitive Finalize_Address not available"); - Node.Finalize_Address := Finalize_Address; - Node.Prev := Collection.Head'Unchecked_Access; - Node.Next := Collection.Head.Next; + Node.Enclosing_Collection := Collection'Unrestricted_Access; + Node.Finalize_Address := Finalize_Address; + Node.Prev := Collection.Head'Unchecked_Access; + Node.Next := Collection.Head.Next; Collection.Head.Next.Prev := Node; Collection.Head.Next := Node; - Unlock_Task.all; + Unlock_Collection (Collection); exception when others => - -- Unlock the task in case the attachment failed and reraise the - -- exception. + -- Unlock the collection in case the attachment failed and reraise + -- the exception. - Unlock_Task.all; + Unlock_Collection (Collection); raise; end Attach_Object_To_Collection; @@ -180,11 +196,11 @@ package body System.Finalization_Primitives is To_Collection_Node_Ptr (Object_Address - Header_Size); begin - Lock_Task.all; + Lock_Collection (Node.Enclosing_Collection.all); Detach_Node_From_Collection (Node); - Unlock_Task.all; + Unlock_Collection (Node.Enclosing_Collection.all); end Detach_Object_From_Collection; -------------- @@ -213,14 +229,14 @@ package body System.Finalization_Primitives is end Is_Empty_List; begin - Lock_Task.all; + Lock_Collection (Collection); -- Synchronization: -- Read - attachment, finalization -- Write - finalization if Collection.Finalization_Started then - Unlock_Task.all; + Unlock_Collection (Collection); -- Double finalization may occur during the handling of stand-alone -- libraries or the finalization of a pool with subpools. @@ -258,6 +274,11 @@ package body System.Finalization_Primitives is Obj_Addr := Curr_Ptr.all'Address + Header_Size; + -- Temporarily release the lock because the call to Finalize_Address + -- may ultimately invoke Detach_Object_From_Collection. + + Unlock_Collection (Collection); + begin Curr_Ptr.Finalize_Address (Obj_Addr); exception @@ -267,9 +288,13 @@ package body System.Finalization_Primitives is Save_Occurrence (Exc_Occur, Fin_Occur); end if; end; + + -- Retake the lock for the next iteration + + Lock_Collection (Collection); end loop; - Unlock_Task.all; + Unlock_Collection (Collection); -- If one of the finalization actions raised an exception, reraise it @@ -387,8 +412,21 @@ package body System.Finalization_Primitives is Collection.Head.Prev := Collection.Head'Unchecked_Access; Collection.Head.Next := Collection.Head'Unchecked_Access; + + Collection.Lock := 0; end Initialize; + --------------------- + -- Lock_Collection -- + --------------------- + + procedure Lock_Collection (Collection : in out Finalization_Collection) is + begin + while Atomic_Test_And_Set (Collection.Lock'Address, Acquire) loop + null; + end loop; + end Lock_Collection; + ------------------------------------- -- Suppress_Object_Finalize_At_End -- ------------------------------------- @@ -398,4 +436,15 @@ package body System.Finalization_Primitives is Node.Finalize_Address := null; end Suppress_Object_Finalize_At_End; + ----------------------- + -- Unlock_Collection -- + ----------------------- + + procedure Unlock_Collection (Collection : in out Finalization_Collection) is + procedure Lock_Store is new Atomic_Store (Lock_Type); + + begin + Lock_Store (Collection.Lock'Address, 0, Release); + end Unlock_Collection; + end System.Finalization_Primitives; diff --git a/gcc/ada/libgnat/s-finpri.ads b/gcc/ada/libgnat/s-finpri.ads index 874a82f5349..4ba13dadec0 100644 --- a/gcc/ada/libgnat/s-finpri.ads +++ b/gcc/ada/libgnat/s-finpri.ads @@ -214,13 +214,19 @@ private -- Collection node type structure type Collection_Node is record + Enclosing_Collection : Finalization_Collection_Ptr := null; + -- A pointer to the collection to which the node is attached + Finalize_Address : Finalize_Address_Ptr := null; + -- A pointer to the Finalize_Address procedure of the object Prev : Collection_Node_Ptr := null; Next : Collection_Node_Ptr := null; - -- Finalization_Collections are managed as a circular doubly-linked list + -- Collection nodes are managed as a circular doubly-linked list end record; + type Lock_Type is mod 2**8 with Size => 8; + -- Finalization collection type structure type Finalization_Collection is @@ -233,6 +239,10 @@ private -- A flag used to detect allocations which occur during the finalization -- of a collection. The allocations must raise Program_Error. This may -- arise in a multitask environment. + + Lock : Lock_Type; + pragma Atomic (Lock); + -- A spinlock to synchronize concurrent accesses to the collection end record; -- This operation is very simple and thus can be performed in line -- 2.43.2