This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Implement task barriers in Ada


Ada 2012 added a Synchronous_Barrier type to allow many tasks to be blocked
and be released at once, similar to the functionality provided by POSIX
barriers. See AI-0174 for details.

The following test case should compile quietly in Ada2012 mode and execute
without any output message:

pragma Task_Dispatching_Policy (FIFO_Within_Priorities);

with System;

with Ada.Synchronous_Barriers;
with Ada.Synchronous_Task_Control;

with Ada.Text_IO; use Ada.Text_IO;

procedure Test_Barriers is
   Number_Of_Tasks : constant := 1_000;

   Barrier : Ada.Synchronous_Barriers.Synchronous_Barrier (Number_Of_Tasks);

   protected type Task_Ctrl is
      entry Wait;
      procedure Notify;
      function Is_Notified return Boolean;
   private
      Barrier : Boolean := False;
   end Task_Ctrl;

   protected body Task_Ctrl is
      entry Wait when Barrier is
      begin
         null;
      end Wait;

      procedure Notify is
      begin
         Barrier := True;
      end Notify;

      function Is_Notified return Boolean is
      begin
         return Barrier;
      end Is_Notified;
   end Task_Ctrl;

   type Container;

   task type Worker (Wrapper : not null access Container) is
      pragma Priority (System.Priority'Last);
   end Worker;

   type Container is limited
      record
         Who        : Worker (Container'Access);
         Started    : Task_Ctrl;
         Finished   : Task_Ctrl;
         The_Chosen : Boolean;
      end record;

   task body Worker is
   begin
      --  Task started
      Wrapper.Started.Notify;

      --  Wait to synchronize with the others
      Ada.Synchronous_Barriers.Wait_For_Release (Barrier, Wrapper.The_Chosen);

      --  Task finishing
      Wrapper.Finished.Notify;
   end Worker;

   Worker_Array : array (1 .. Number_Of_Tasks - 1) of Container;

   Environment_Chosen : Boolean := False;
   Chosen_Found : Boolean := False;

begin
   --  Make sure that all tasks are started
   for Element of Worker_Array loop
      Element.Started.Wait;
   end loop;

   --  All tasks have started execution, and they should all be waiting
   --  on the barrier.

   for Element of Worker_Array loop
      if Element.Finished.Is_Notified then
         Put_Line ("A task passed through the barrier");
      end if;
   end loop;

   Ada.Synchronous_Barriers.Wait_For_Release (Barrier, Environment_Chosen);

   --  Make sure that all tasks are finished
   for Element of Worker_Array loop
      Element.Finished.Wait;
   end loop;

   --  Verify that just task was chosen to carry the notification of the
   --  open barrier.
   for Element of Worker_Array loop
      if Chosen_Found and then Element.The_Chosen then
         Put_Line ("More than one task chosen to carry notification");
      else
         Chosen_Found := Chosen_Found or else Element.The_Chosen;
      end if;
   end loop;

   --  Verify whether the environment task should carry the token
   if Environment_Chosen = Chosen_Found then
      Put_Line ("Problem with notifications");
   end if;
end Test_Barriers;

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-29  Jose Ruiz  <ruiz@adacore.com>

	* impunit.adb (Non_Imp_File_Names_12): Add a-synbar for new Ada 2012
	package Ada.Synchronous_Barriers.
	* a-synbar.ads, a-synbar.adb, a-synbar-posix.ads, a-synbar-posix.adb:
	Add new specs and bodies for Ada.Synchronous_Barriers. There is a
	default implementation using protected objects and another one
	a-synbar-posix using POSIX barriers as the underlying support.
	* gcc-interface/Makefile.in (LIBGNAT_TARGET_PAIRS for Linux (x86,
	x86_64, ia64) and MIPS IRIX): Use the a-synbar-posix implementation of
	Ada.Synchronous_Barriers which uses POSIX barriers (more efficient).
	Clean up dependencies .
	* Makefile.rtl (GNATRTL_TASKING_OBJS): Add a-synbar.o

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]