1with Ada.Text_IO;
2use Ada.Text_IO;
3with Ada.Real_Time;
4use Ada.Real_Time;
5with Ada.Task_Attributes;
6use Ada.Task_Attributes;
7with Ada.Scheduling;
8use Ada.Scheduling;
9
10package Task_Scheduler_Pkg is
11
12-- Define the maximum number of tasks
13Max_Tasks : constant := 10;
14
15-- Task type with a priority attribute
16task type Prioritized_Task (Task_Name : String) is
17entry Set_Priority (New_Priority : Priority);
18entry Get_Priority (Priority_Value : out Priority);
19entry Execute;
20end Prioritized_Task;
21
22-- Procedure to create and start a new task
23procedure Create_Task (Name : String; Initial_Priority : Priority) return Prioritized_Task'Identity;
24
25-- Procedure to update the priority of an existing task
26procedure Update_Task_Priority (Task_ID : Prioritized_Task'Identity; New_Priority : Priority);
27
28-- Procedure to retrieve the priority of an existing task
29function Get_Task_Priority (Task_ID : Prioritized_Task'Identity) return Priority;
30
31-- Main scheduling loop (simulated)
32procedure Run_Scheduler;
33
34private
35
36-- Internal representation of a task with its attributes
37type Task_Record is record
38ID : Prioritized_Task'Identity;
39Name : String;
40Priority : Priority;
41end record;
42
43-- Array to hold task records
44Tasks : array (1 .. Max_Tasks) of Task_Record;
45Task_Count : Integer := 0;
46
47-- Helper function to find a task by its ID
48function Find_Task (Task_ID : Prioritized_Task'Identity) return Integer;
49
50end Task_Scheduler_Pkg;
51
52package body Task_Scheduler_Pkg is
53
54-- Implementation of the Prioritized_Task task type
55task body Prioritized_Task is
56Current_Priority : Priority := Ada.Scheduling.Default_Priority;
57begin
58loop
59-- Wait for an entry call or the Execute entry
60select
61when Current_Priority /= Ada.Scheduling.Default_Priority =>
62accept Execute;
63-- Simulate task execution
64Put_Line (Task_Name & " executing with priority " & Priority'Image(Current_Priority));
65delay Ada.Real_Time.Milliseconds (100);
66or
67accept Set_Priority (New_Priority : Priority) do
68-- Update the task's priority
69Current_Priority := New_Priority;
70Put_Line (Task_Name & " priority set to " & Priority'Image(Current_Priority));
71-- In a real system, this would involve calling OS-level functions
72-- to change the task's scheduling priority.
73-- For this example, we just update the internal record.
74-- Ada.Scheduling.Set_Priority(Current_Priority);
75end Set_Priority;
76or
77accept Get_Priority (Priority_Value : out Priority) do
78Priority_Value := Current_Priority;
79end Get_Priority;
80or
81terminate;
82end select;
83end loop;
84end Prioritized_Task;
85
86-- Procedure to create a new task
87function Create_Task (Name : String; Initial_Priority : Priority) return Prioritized_Task'Identity is
88begin
89if Task_Count >= Max_Tasks then
90Put_Line ("Error: Max tasks reached.");
91return Prioritized_Task'Identity'First; -- Indicate error
92end if;
93
94Task_Count := Task_Count + 1;
95Tasks(Task_Count).ID := new Prioritized_Task(Name => Name);
96Tasks(Task_Count).Name := Name;
97Tasks(Task_Count).Priority := Initial_Priority;
98
99-- Set the initial priority of the task
100Update_Task_Priority(Tasks(Task_Count).ID, Initial_Priority);
101
102Put_Line ("Task " & Name & " created with initial priority " & Priority'Image(Initial_Priority));
103return Tasks(Task_Count).ID;
104end Create_Task;
105
106-- Procedure to update task priority
107procedure Update_Task_Priority (Task_ID : Prioritized_Task'Identity; New_Priority : Priority) is
108Task_Index : Integer;
109begin
110Task_Index := Find_Task(Task_ID);
111if Task_Index /= 0 then
112-- Call the task's entry to set its priority
113Prioritized_Task(Task_ID).Set_Priority(New_Priority);
114-- Update the internal record as well
115Tasks(Task_Index).Priority := New_Priority;
116else
117Put_Line ("Error: Task not found for priority update.");
118end if;
119end Update_Task_Priority;
120
121-- Function to get task priority
122function Get_Task_Priority (Task_ID : Prioritized_Task'Identity) return Priority is
123Task_Index : Integer;
124Priority_Val : Priority;
125begin
126Task_Index := Find_Task(Task_ID);
127if Task_Index /= 0 then
128-- Call the task's entry to get its priority
129Prioritized_Task(Task_ID).Get_Priority(Priority_Val);
130return Priority_Val;
131else
132Put_Line ("Error: Task not found for priority retrieval.");
133return Ada.Scheduling.Default_Priority; -- Indicate error
134end if;
135end Get_Task_Priority;
136
137-- Simulated scheduler loop
138procedure Run_Scheduler is
139begin
140Put_Line ("Scheduler started.");
141-- In a real RTOS, this would be the main scheduler loop.
142-- For this example, we'll just trigger task execution.
143for I in 1 .. Task_Count loop
144Prioritized_Task(Tasks(I).ID).Execute;
145end loop;
146Put_Line ("Scheduler finished.");
147end Run_Scheduler;
148
149-- Helper function to find a task by its ID
150function Find_Task (Task_ID : Prioritized_Task'Identity) return Integer is
151begin
152for I in 1 .. Task_Count loop
153if Tasks(I).ID = Task_ID then
154return I;
155end if;
156end loop;
157return 0; -- Not found
158end Find_Task;
159
160end Task_Scheduler_Pkg;