The Terminated flag for a task was being queried without first aquiring
the task lock. It is not clear that this unsychronized access has ever
caused a problem in practice, but the thread-sanitizer tool flags it.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* libgnarl/s-tassta.adb (Free_Task): Acquire the Task_Lock
before, rather than after, querying the task's Terminated flag.
Add a corresponding Task_Unlock call.
diff --git a/gcc/ada/libgnarl/s-tassta.adb b/gcc/ada/libgnarl/s-tassta.adb
--- a/gcc/ada/libgnarl/s-tassta.adb
+++ b/gcc/ada/libgnarl/s-tassta.adb
@@ -910,12 +910,12 @@ package body System.Tasking.Stages is
Self_Id : constant Task_Id := Self;
begin
+ Initialization.Task_Lock (Self_Id);
+
if T.Common.State = Terminated then
-- It is not safe to call Abort_Defer or Write_Lock at this stage
- Initialization.Task_Lock (Self_Id);
-
Lock_RTS;
Initialization.Finalize_Attributes (T);
Initialization.Remove_From_All_Tasks_List (T);
@@ -930,6 +930,7 @@ package body System.Tasking.Stages is
-- upon termination.
T.Free_On_Termination := True;
+ Initialization.Task_Unlock (Self_Id);
end if;
end Free_Task;