!standard D.2.1(1.2/2) 10-02-18 AI05-0166-1/02 !standard D.2.1(6/2) !standard 9.5.1(16) !standard D.2.4(2/2) !standard D.2.4(9/2) !class Amendment 09-10-22 !status work item 09-10-22 !status received 09-10-22 !priority Medium !difficulty Easy !subject Yield for non-preemptive dispatching !summary A support package for non-preemptive dispatching is proposed that allows a task to offer to be preempted by a higher priority task, but not by one of equal priority. A further 'yield' procedure is included to improve the readability and maintainability of programs. It replaces the current need to include 'delay 0.0' to force a preemption. !problem With non-preemptive dispatching the only current non-blocking dispatching point is a non-blocking delay_statement. We need another kind so that a task in a system scheduled by non-preemptive dispatching can indicate that it is prepared to be preempted by tasks of higher priority but not by those of equal priority. !proposal Add to package Ada.Dispatching: procedure Yield; -- Bounded error if executed within a -- protected operation Add the following library package: package Ada.Dispatching.Non_Preemptive is procedure Yield_To_Higher; procedure Yield_To_Same_Or_Higher renames Yield; end Ada.Dispatching.Non_Preemptive; With non-preemptive dispatching the only current non-blocking dispatching point is a non-blocking delay_statement - D.2.4(9/2). With this new package a call to Yield_To_Higher will cause a task switch if there is a runnable task with an active priority higher than the calling task's active priority. Note this can be called from within a protected object. To program cooperative scheduling a task explicitly includes the points at which it is able to be preempted. It does this by using either 'delay 0.0' or 'delay until Ada.Real_Time.Time_First' (the latter being the one available with Ravenscar). As these statements are not actually concerned with delaying the task they are potentially misleading (to the human reader/maintainer of the code). The procedure Yield is equivalent to these delay statements; and would therefore cause the same bounded error if called from within a protected action. !wording Add to package Ada.Dispatching (D.2.1(1.2/2)): procedure Yield; Add after D.2.1(6/2): A call of Yield is a task dispatching point (see D.2.1). It is a bounded error to call Yield from within a protected action. Add after 9.5.1(16): * a call to Ada.Dispatching.Yield; Add after D.2.4(2/2): The following language-defined library package exists: package Ada.Dispatching.Non_Preemptive is procedure Yield_To_Higher; procedure Yield_To_Same_Or_Higher renames Yield; end Ada.Dispatching.Non_Preemptive; A call of Yield_To_Higher is a task dispatching point for this policy. If the task at the head of the highest priority ready queue has a higher active priority than the calling task then calling task is preempted. Replace D.2.4(9/2): For this policy, a non-blocking delay-statement, a call to Yield_To_Higher and a call to Yield_To_Same_Or_Higher or Yield are the only non-blocking events that are task dispatching points (see D.2.1). !discussion This AI was raised by an industrial user of non-preemptive scheduling, and was discussed and endorsed by the 14th IRTAW. Details are contained in the workshop paper: Providing Additional Real-Time Capability and Flexibility for Ada 2005, by Rod White. !example ** TBD ** --!corrigendum D.2.4(9/2) !ACATS test Add an ACATS C-Test of this package. !appendix ****************************************************************