protected object entry protected broker
task
Entry_Queues Next_Queue
Entry index: 1 Entry index: 2 Entry index: 3 Next_Queue Next_Queue Next_Agent Next_Agent Next_Agent Next_Agent Next_Agent Next_Agent
Next_Agent Next_Agent
Next_Agent
Figure 34
Oak’s implementation of protected object entry queues using linked list.
Listing 65
Oakland.Protected_Objects
oakland.protected_objects.ads
141 ACTON A REAL-TIME EXECUTIVE FOR ADA
Within Oak, the procedure Oak.Protected_Objects.Process_Enter_Request
handles the entry request. While the kernel processes the request, Oak will not dispatch the task until the request completes with the task gaining access to the protected object or the request fails. If unsuccessful, the kernel places the task into the Enter_PO_Refused state; otherwise, the task becomes dis- patchable with an Inside_PO state. Figure 35 describes the operation of Pro- cess_Enter_Request. To note:
Validate request Oak validates the parameters associated with the entry re- quest, ensuring the requested protected object’s broker exists and the entry ID is valid. The check also enforces the Priority Ceiling Protocol, ensuring the priority of task issuing the request has a priority not above the protected object’s ceiling priority.
Record request entry ID Enables tasks on a broker’s Contending_Tasks list
to resubmit their entry request when they are latter admitted to the protected object.
Scheduling Oak conceptually removes tasks from their schedulers when they are inside a protected object (on the broker’s Task_Within list) because Oak dispatches these tasks from their protected broker rather than their sched- uler agent. However, as an optimisation, Oak does not perform the removal since the kernel implements the Priority Ceiling Protocol: always selecting the task from the broker before the task’s runnable queue because of the broker’s precedence. Oak, though, does remove tasks on the Contending_Tasks and
Entry_Queues lists because these tasks are not dispatchable.
Entry servicing When Oak places a task on an entry queue it causes a re-eval- uation of the protected object’s entry barriers to check if any barriers have opened (since a barrier may use the queue’s Count attribute, as per ARM 9.5.3). An error raised during an entry check causes the entry request to fail.
Exception raised within barriers In this scenario, Oak sets the state of the requesting task and the tasks already on the protected object’s entry queues to Entering_PO_Refused. The procedure then purges the entry queues as per ARM 9.5.3:7 and places the formally queued tasks back on their scheduler agents. Broker lock On multiprocessor systems, Oak requires kernel agents accessing a protected broker object to hold its Broker_Lock.
A task requests its exit from a protected object by calling the Oakland procedure
Oakland.Protected_Objects.Exit_Protected_Object:
procedure Exit_Protected_Object (PO : in Protected_Id);
The procedure Oak.Protected_Objects.Process_Exit_Request, shown in Fig- ure 36 on page 144, handles the exit request within Oak. It verifies that the exiting task is inside the protected object before transferring the protected broker to a task on an entry queue with an open barrier, if such a task exists. Otherwise, Oak deactivates the broker by removing it from the kernel agent’s
Active_Protected_Brokers list. protected object entry
Caller state to Enter_PO_Refused Obtain protected broker lock
Set task state to Inside_PO Remove task from entry queue
Remove task from scheduler
Remove task from scheduler
Add task to entry queue
Add task to Task_Within list
Release broker lock
Add broker to kernel, state to Runnable
Release broker lock
Release broker lock
Queued tasks state to Enter_PO_Refused Entering task state to Enter_PO_Refused
Add queued tasks to schedulers
Purge entry queues
Add task to Contending_Task Record task's request within its task agent
◉ No
◉ Has task
◉ Zero (protected subprogram access)
◉ Open ◉ Exception raised ◉ Exception raised ◉ Yes ◉ Closed ◉ No ◉ Yes ◉ Empty
◉ Non-zero (protected entry access) ♦ Valid entry request:
♦ Protected broker's Task_Within:
♦ Entry_ID is:
♦ Entry barrier is:
♦ Eligible entry call to service:
Figure 35
The Oak.Protected_Objects. Process_Enter_Request
procedure.
143 ACTON A REAL-TIME EXECUTIVE FOR ADA
On multiprocessor systems, tasks from other processors will have queue on the broker’s Contending_Tasks list while the exiting task had operated inside
the protected object. Once Oak incorporates support for multiprocessor sys- tems, it is anticipated the Process_Exit_Request will use a future inter-kernel messaging system to pass the protected broker to the kernel responsible for the task selected from the broker’s Contending_Tasks list.19 Once the target kernel agent receives the broker, the kernel will extract its task from the broker’s
Contending_Tasks list and add the task back to its scheduler. Subsequently, the target kernel agent will re-issue the task’s protected object entry request by calling Oak.Protected_Objects.Process_Enter_Request, using the entry request parameters stored within the task’s agent. During the handover of the protected broker between kernel agents, the broker remains locked with ownership of the lock being handed over as part of the exchange.
19. Assuming a multiprocessor Oak will have a separate kernel agent running on each processor and an inter-kernel messaging system facilitating the exchange of messages between kernels.
Figure 36
The Oak.Protected_Objects. Process_Exit_Request
procedure.
Caller state to Exit_PO_Refused Obtain protected broker lock
Release broker lock
Remove task from queue
Notify task's processor
Set state to Inside_PO
Add task to Task_Within list
Remove broker from kernel
Remove broker from kernel
Add task to scheduler
Release broker lock Set broker state to inactive
Queued tasks state to Enter_PO_Refused
Add queued tasks to schedulers
Purge entry queues Remove task from Task_Within list
Set task state to Runnable
◉ No ◉ Exception raised ◉ Yes ◉ Yes ◉ No ◉ No ◉ Yes ♦ Valid exit request:
♦ Entry call to service:
♦ Contending tasks:
A user can attach user-defined handlers to two sources of interrupts in Acton: external interrupts and Oak Timers. External interrupts originate from outside the processor core via an interrupt controller. By contrast, Oak Timers pro- vide an abstraction over the system timer: sharing the same interrupt source but trigged when their specified time has passed. Three forms of Oak Timers exist: Cycle_Timers, Timing_Event_Timers and Scheduler_Timers. To adapt to the needs of the different timer kinds, the single Oak Timer type uses a variant record to provide specific support for each timer kind (as described in Oak Timers on page 112). The system timer takes a form dictated by the
facilities provided by the microcontroller; the timer may exist within software, via external hardware or within the processor core itself.
Aside from the Oak Timers abstraction, Acton does not expose a processor core’s internal interrupt sources to the user, reserving them for internal use. Internal interrupts link closely to the functionality of Oak and are processor specific— details not explored here. By contrast, Oak adopts a common system handler for external and system timer interrupts: the kernel runs to dispatch the appropriate interrupt agent with the user’s interrupt handler.
Ada’s protected procedure handlers and timing events provide the user-defined interrupt handlers for external interrupts and Oak timers respectively. Oak also uses Oak Timers to implement execution budgets and deadlines for cyclic tasks, with the handling of these timers determined by the Event_Response
type associated with each timer (as defined by the Cyclic Task Specification).
Finally, the handling of scheduler timers differs from the other timers as they support Oak’s operation and not the user’s (see Management of Scheduler Agents by Oak on page 120).
Cycle timers support cyclic tasks. Each task agent contains two cycle timers supporting the Cyclic Task Specification’s responses to missed deadlines and
budget exhaustions (Cyclic Tasks on page 130). The user specifies the handling
behaviour of these timers through the Deadline_Response and Budget_Re- sponse task attributes, with Oak only supporting the No_Response and Handler
options.20 A cycle timer uses the ceiling priority of the handler’s protected object when the timer uses the Handler response; otherwise, the timer uses
the cyclic task’s priority. Management of these timers falls on the Oak.Agent. Tasks.Cycle.New_Cycle procedure and Oak’s run loop (Cyclic Tasks on page
130 and The Oak Run-Loop on page 114).
Oak uses timing event timers to implement Ada’s timing events (ARM D.15), with the user interface provided through the Ada.Real_Time.Timing_Events
package. Internally, an Oak Timer captures the timing event semantics, leaving the Timing_Event type to just reference the timer (Listing 66). The Set_Handler
procedures send a Set_Timing_Event_Handler request to Oak, with Oak assign- ing a new Oak Timer to the timing event object if it lacks one. The associated Oak Timer assumes the Interrupt_Priority'Last priority as per ARM D.15.14.
20. Since Oak currently lacks asynchronous transfer of control and task abortion.