1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
/* -*- C++ -*- */
//=============================================================================
/**
* @file Scheduler.h
*
* @author David Levine
*/
//=============================================================================
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include /**/ "ace/pre.h"
#include "ace/ACE.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Map_Manager.h"
#include "ace/Message_Block.h"
#include "ace/SString.h"
#include "ace/Unbounded_Set.h"
#include "orbsvcs/RtecSchedulerC.h"
#include "orbsvcs/Event_Service_Constants.h"
#include "orbsvcs/Sched/sched_export.h"
/**
* @class ACE_Scheduler
*
* @brief Thread scheduler interface.
*
* This virtual base class is the interface to either an off-line
* scheduler, or to the necessary on-line component of the Scheduler.
*/
class TAO_RTSched_Export ACE_Scheduler
{
public:
typedef u_int mode_t;
typedef RtecScheduler::handle_t handle_t;
typedef RtecScheduler::Dependency_Info Dependency_Info;
typedef RtecScheduler::Preemption_Priority_t Preemption_Priority;
typedef RtecScheduler::OS_Priority OS_Thread_Priority;
typedef RtecScheduler::Preemption_Subpriority_t Sub_Priority;
typedef RtecScheduler::RT_Info RT_Info;
typedef RtecScheduler::Config_Info Config_Info;
typedef RtecScheduler::Time Time;
typedef RtecScheduler::Dispatching_Type_t Dispatching_Type;
typedef RtecScheduler::Scheduling_Anomaly Scheduling_Anomaly;
// Map some types to simplify re-use.
/// Objects are named by unique strings.
typedef const char *Object_Name;
static const mode_t CURRENT_MODE;
enum status_t {
// The following are used both by the runtime Scheduler and during
// scheduling.
NOT_SCHEDULED = -1 // the schedule () method has not been called yet
, FAILED = -1
, SUCCEEDED
, ST_UNKNOWN_TASK
, ST_UNKNOWN_PRIORITY
, ST_TASK_ALREADY_REGISTERED
, ST_VIRTUAL_MEMORY_EXHAUSTED
, ST_BAD_INTERNAL_POINTER
// The following are only used by the runtime Scheduler.
, INVALID_MODE
, MODE_COUNT_MISMATCH // only used by schedule ()
, TASK_COUNT_MISMATCH // only used by schedule ()
, THREAD_COUNT_MISMATCH // only used by schedule ()
, INVALID_PRIORITY // only used by schedule (): mismatch of
// (off-line, maybe) Scheduler output to
// the runtime Scheduler component.
// The following are only used during scheduling (in the case of
// off-line scheduling, they are only used prior to runtime).
, ST_UTILIZATION_BOUND_EXCEEDED
, ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS
, ST_CYCLE_IN_DEPENDENCIES
, ST_UNRESOLVED_REMOTE_DEPENDENCIES
, UNABLE_TO_OPEN_SCHEDULE_FILE
, UNABLE_TO_WRITE_SCHEDULE_FILE
};
virtual ~ACE_Scheduler ();
// = Utility function for outputting the textual representation of a
// status_t value to a FILE.
static void output (FILE *, const status_t);
// = Initialize the scheduler.
/**
* The minimum and maximum priority are the OS-specific priorities that
* are used when creating the schedule (assigning priorities). The
* minimum_priority is the priority value of the lowest priority.
* It may be numerically higher than the maximum_priority, on OS's such
* as VxWorks that use lower values to indicate higher priorities.
*
* When Scheduler::schedule is called, the schedule is output to the
* file named by "runtime_filename" if it is non-zero.
* This file is compilable; it is linked into the runtime executable
* to provide priorities to the runtime scheduling component.
* If the "rt_info_filename" is non-zero, the RT_Info for
* every task is exported to it. It is not used at runtime.
* If the "timeline_filename" is non-zero, the timeline output
* file is created. It is not used at runtime.
*
* The runtime scheduling component ignores these filenames. It just
* uses the priorities that were linked in to the executable, after
* converting them to platform-specific values.
*/
virtual void init (const int minimum_priority,
const int maximum_priority,
const char *runtime_filename = 0,
const char *rt_info_filename = 0,
const char *timeline_filename = 0) = 0;
// = Registers a task.
/**
* If the Task registration succeeds, this function returns SUCCEEDED
* and sets "handle" to a unique identifier for the task.
* Otherwise, it returns either VIRTUAL_MEMORY_EXHAUSTED or
* TASK_ALREADY_REGISTERED sets the handle to 0. (A task may
* only be registered once.)
* The RT_Info * array is indexed by mode; there must be one element for
* each mode, as specified by number_of_modes. If a task does not
* run in a mode, then its entry in the array for that mode must
* be 0.
*/
virtual status_t register_task (RT_Info *[],
const u_int number_of_modes,
handle_t &handle) = 0;
/**
* Tries to find the RT_Info corresponding to <name> in the RT_Info
* database. Returns SUCCEEDED if <name> was found and <rtinfo> was
* set. Returns UNKNOWN_TASK if <name> was not found, but <rtinfo>
* was set to a newly allocated RT_Info. In this UNKNOWN_TASK case,
* the task must call RT_Info::set to fill in execution properties.
* In the SUCCEEDED and UNKNOWN_TASK cases, this->register_task
* (rtinfo, 0, handle) is called. Returns FAILED if an error
* occurs.
*
* One motivation for allocating RT_Info's from within the Scheduler
* is to allow RT_Infos to persist after the tasks that use them.
* For instance, we may want to call this->schedule right before the
* application exits a configuration run. If the tasks have been
* deleted (deleting their RT_Infos with them), this->schedule will
* fail.
*/
virtual status_t get_rt_info (Object_Name name,
RT_Info* &rtinfo);
/// Obtains an RT_Info based on its "handle".
virtual status_t lookup_rt_info (handle_t handle,
RT_Info* &rtinfo) = 0;
/// Obtains a Config_Info based on its priority.
virtual status_t lookup_config_info (Preemption_Priority priority,
Config_Info* &config_info) = 0;
// = Computes the schedule.
/// This actually generates the files.
virtual status_t
schedule (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set) = 0;
// = Access a thread priority.
/**
* Defines "priority" as the priority that was assigned to the Task that
* was assigned "handle", for the specified mode. Defines "subpriority"
* as the relative ordering (due to dependencies) within the priority.
* Returns 0 on success, or -1 if an invalid mode or handle are supplied.
* Queue numbers are platform-independent priority values, ranging from
* a highest priority value of 0 to the lowest priority value, which is
* returned by "minimum_priority_queue ()". The current and deadline times
* are part of the scheduling service implementation interface, but may be
* ignored by some implementations and used by others.
*/
virtual int priority (const handle_t handle,
OS_Thread_Priority &priority,
Sub_Priority &subpriority,
Preemption_Priority &preemption_prio,
const mode_t = CURRENT_MODE) const = 0;
// = Access the platform-independent priority value of the lowest-priority
// thread.
/// This is intended for use by the Event Channel, so it can determine the
/// number of priority dispatch queues to create.
u_int minimum_priority_queue () const { return minimum_priority_queue_; }
// = Access the number of modes.
u_int modes () const { return modes_; }
// = Access the number of tasks.
u_int tasks () const { return tasks_; }
// = Access the number of threads.
u_int threads () const { return threads_; }
// = Access the current mode.
mode_t mode () const { return mode_; }
// = Set the current mode.
void mode (const mode_t mode) { mode_ = mode; }
// = Access the current scheduler status.
status_t status () const { return status_; }
// = Access the current output (debugging) level.
/// Default is 0; set to 1 to print out schedule, by task. Set
/// to higher than one for debugging info.
u_int output_level () const { return output_level_; }
// = Set the scheduler output (debugging) level.
/// the only supported levels are 0 (quiet), 1 (verbose) and 2
/// (debug)
void output_level (const u_int level) { output_level_ = level; }
static int add_dependency(RT_Info* rt_info,
const Dependency_Info& d);
static int number_of_dependencies(RT_Info* rt_info);
static int number_of_dependencies(RT_Info& rt_info);
static void export_to_file (RT_Info*, FILE* file);
static void export_to_file (RT_Info&, FILE* file);
/// provide the thread priority and queue type for the given priority level
virtual int dispatch_configuration (const Preemption_Priority &p_priority,
OS_Thread_Priority& priority,
Dispatching_Type & d_type);
protected:
ACE_Scheduler ();
// = Set the minimum priority value.
void minimum_priority_queue (const u_int minimum_priority_queue_number)
{ minimum_priority_queue_ = minimum_priority_queue_number; }
// = Set the number of modes.
void modes (const u_int modes) { modes_ = modes; }
// = Set the number of tasks.
void tasks (const u_int tasks) { tasks_ = tasks; }
// = Set the number of threads.
void threads (const u_int threads) { threads_ = threads; }
// = Set the current scheduler status.
void status (const status_t new_status) { status_ = new_status; }
private:
typedef ACE_CString EXT;
typedef RT_Info **INT;
typedef ACE_Map_Manager<EXT, INT, TAO_SYNCH_MUTEX> Info_Collection;
typedef ACE_Map_Iterator<EXT, INT, TAO_SYNCH_MUTEX> Info_Collection_Iterator;
typedef ACE_Map_Entry<EXT, INT> Info_Collection_Entry;
/// A binding of name to rt_info. This is the mapping for every
/// rt_info in the process.
Info_Collection info_collection_;
static ACE_Scheduler *instance_;
/**
* The platform-independent priority value of the Event Channel's
* minimum priority dispatch queue. The value of the maximum priority
* dispatch queue is always 0.
*/
u_int minimum_priority_queue_;
u_int modes_;
u_int tasks_;
u_int threads_;
mode_t mode_;
status_t status_;
u_int output_level_;
// the following functions are not implememented
ACE_Scheduler (const ACE_Scheduler &);
ACE_Scheduler &operator= (const ACE_Scheduler &);
};
typedef ACE_Scheduler Scheduler;
#include /**/ "ace/post.h"
#endif /* SCHEDULER_H */
// EOF
|