-- $Id: threads.ads,v 1.3 2008/11/20 18:49:43 baker Exp baker $ -- Provides thread abstraction, implementing services typically -- provided by an operating system to schedule the execution of a -- thread. with Virtual_Times; use Virtual_Times; with Generic_Queues; with Events; with Jobs; -- but *not* Tasks! -- To avoid mutual dependence, tasks (arrival and workload -- generation objects) can see the threads (system processes) that -- they influence, but not vice versa. package Threads is type Thread is limited private; type Thread_Ref is access all Thread; -------------------------- -- Scheduling Policies -- -------------------------- -- Allow us to define plug-in modules to implement -- a variety of per-thread scheduling policies. -- Each policy may need policy-specific -- per-thread parameters and state information. package Scheduling_Parameters is -- used to specify scheduling parameters, such as budget -- and replenishment periodic for aperiodic servers type Object is abstract tagged null record; end Scheduling_Parameters; type Parameters_Class_Ref is access all Scheduling_Parameters.Object'Class; package Scheduling_Policies_State is -- used to store policy-specific per-thread data -- such as budget replenishment info type Object is abstract tagged null record; end Scheduling_Policies_State; type Policy_State_Class_Ref is access all Scheduling_Policies_State.Object'Class; package Scheduling_Policies is type Object is abstract tagged record Data : Policy_State_Class_Ref; T : Thread_Ref; end record; procedure Bind_Thread (P : in out Object; T : Thread_Ref); procedure Init (P : in out Object) is abstract; -- Initializes or resets policy-dependent -- per-thread scheduling state -- The following are "hooks" that allow -- insertion of policy-specific actions -- at key points during execution. procedure New_Job (P : in out Object; J : in Jobs.Job) is abstract; -- a thread starts executing a new job. -- e.g., with EDF scheduling, the deadline of -- the job determines the thread priority procedure Suspend (P : in out Object) is abstract; -- a thread has suspended itself. -- e.g., with polling server, the thread -- gives up its remaining budget procedure Unsuspend (P : Object) is abstract; -- a thread wakes up. -- e.g., with an aperiodic server, a job arrives -- to an empty server job queue, and the job -- resumes contention for execution procedure New_Current_Thread (P : Object) is abstract; -- the thread scheduler has switched threads -- e.g., if it switches to the idle thread, -- this may be a time to replenish server budgets procedure Go (P : in out Object) is abstract; -- a thread has resumed execution -- e.g., this may be a time to set a timer to -- lower the thread priority when it has used -- up a chunk of budget procedure Stop (P : in out Object) is abstract; -- a thread has stopped execution -- e.g., this may be a time to schedule -- a replenishment, and to cancel -- a timer that would notify us of budget -- exhaustion end Scheduling_Policies; type Policies_Class_Ref is access all Scheduling_Policies.Object'Class; ------------------------- -- Thread operations -- ------------------------- procedure Initialize; -- of the entire threads world -- also call this to reset the threads for a new run; -- does not delete any existing threads, but does -- reset their internal states procedure Bind_Policy (T : in out Thread_Ref; P : Policies_Class_Ref); procedure Schedule; function New_Thread (Go : Events.Class_Ref; Stop : Events.Class_Ref; Name : String) return Thread_Ref; procedure New_Job (T : Thread_Ref; J : Jobs.Job); -- tells thread (and its scheduler) that we have -- started a new job, and so may need to change -- deadline procedure Unsuspend (T : Thread_Ref); -- tells thread that it should not execute; -- the initial thread state is suspended procedure Suspend (T : Thread_Ref); function Name (T: Thread) return String; procedure Set_Debug (Level : Integer); private type Thread is record -- scheduling policy plug-ins Policy : Policies_Class_Ref; Policy_State : Policy_State_Class_Ref; -- interface for tasks Go : Events.Class_Ref; Stop : Events.Class_Ref; -- scheduling state: Is_Suspended : Boolean; -- is logically not ready to run -- for example, periodic thread waiting for next period Priority : Time; -- larger is higher Is_In_Ready_Queue : Boolean; -- actually in queue Name : String (1 .. 4); end record; -- The following are for potential read-access by child -- packages Last_Dispatching_Time : Time; Last_Idle_Time : Time; Current : Thread_Ref; Idle_Thread : Thread_Ref := null; Total_Idle : Time; function ">" (L, R : Thread_Ref) return Boolean; package Threads_Queues is new Generic_Queues (Thread_Ref); -- Thread queues have numerically smallest priority on top -- This works well for EDF and deadline monotonic scheduling Ready_Queue : Threads_Queues.Object; -- A list of all threads known to the system. Should not -- include the idle thread. All_Threads : Threads_Queues.Object; -- The following are for the use of policies that need to -- prevent a thread from running, because it is out of budget, -- without actually suspending it. procedure Policy_Suspend (T : Thread_Ref); procedure Policy_Unsuspend (T : Thread_Ref; New_Priority : Time); end Threads;