3 * \brief Scheduler object functions.
6 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7 * Alexander Warg <warg@os.inf.tu-dresden.de>
8 * economic rights: Technische Universität Dresden (Germany)
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
14 * As a special exception, you may use this file as part of a free software
15 * library without restriction. Specifically, if other files instantiate
16 * templates or use macros or inline functions from this file, or you compile
17 * this file and link it with other files to produce an executable, this
18 * file does not by itself cause the resulting executable to be covered by
19 * the GNU General Public License. This exception does not however
20 * invalidate any other reasons why the executable file might be covered by
21 * the GNU General Public License.
25 #include <l4/sys/kernel_object.h>
26 #include <l4/sys/ipc.h>
29 * \defgroup l4_scheduler_api Scheduler
30 * \ingroup l4_kernel_object_api
31 * \brief Scheduler object.
33 * <c>\#include <l4/sys/scheduler.h></c>
38 * \ingroup l4_scheduler_api
40 typedef struct l4_sched_cpu_set_t
43 * First CPU of interest (must be aligned to 2^granularity).
48 * Bitmap of online CPUs.
53 * One bit in map represents 2^granularity CPUs.
55 unsigned char granularity;
61 * \ingroup l4_scheduler_api
63 * \param offset Offset.
64 * \param granularity Granularitry in log2 notation.
65 * \param map Bitmap of CPUs, defaults to 1 in C++.
69 L4_INLINE l4_sched_cpu_set_t
70 l4_sched_cpu_set(l4_umword_t offset, unsigned char granularity,
71 l4_umword_t map L4_DEFAULT_PARAM(1)) L4_NOTHROW;
74 * \brief Get scheduler information.
75 * \ingroup l4_scheduler_api
77 * \param scheduler Scheduler object.
78 * \retval cpu_max maximum number of CPUs ever available.
79 * \param cpus \a cpus.offset is first CPU of interest.
80 * \a cpus.granularity (see l4_sched_cpu_set_t).
81 * \retval cpus \a cpus.map Bitmap of online CPUs.
83 * \return 0 on success, <0 error code otherwise.
86 l4_scheduler_info(l4_cap_idx_t scheduler, l4_umword_t *cpu_max,
87 l4_sched_cpu_set_t *cpus) L4_NOTHROW;
93 l4_scheduler_info_u(l4_cap_idx_t scheduler, l4_umword_t *cpu_max,
94 l4_sched_cpu_set_t *cpus, l4_utcb_t *utcb) L4_NOTHROW;
99 * \ingroup l4_scheduler_api
101 typedef struct l4_sched_param_t
104 * Timeslice in micro seconds.
106 l4_cpu_time_t quantum;
109 * Priority for scheduling.
116 l4_sched_cpu_set_t affinity;
122 * \ingroup l4_scheduler_api
124 L4_INLINE l4_sched_param_t
125 l4_sched_param(unsigned prio,
126 l4_cpu_time_t quantum L4_DEFAULT_PARAM(0)) L4_NOTHROW;
129 * \brief Run a thread on a Scheduler.
130 * \ingroup l4_scheduler_api
132 * \param scheduler Scheduler object.
133 * \param thread Thread to run.
134 * \param sp Scheduling parameters.
136 * \return 0 on success, <0 error code otherwise.
138 L4_INLINE l4_msgtag_t
139 l4_scheduler_run_thread(l4_cap_idx_t scheduler,
140 l4_cap_idx_t thread, l4_sched_param_t const *sp) L4_NOTHROW;
145 L4_INLINE l4_msgtag_t
146 l4_scheduler_run_thread_u(l4_cap_idx_t scheduler, l4_cap_idx_t thread,
147 l4_sched_param_t const *sp, l4_utcb_t *utcb) L4_NOTHROW;
150 * \brief Query idle time of a CPU, in µs.
151 * \ingroup l4_scheduler_api
153 * \param scheduler Scheduler object.
154 * \param cpus Set of CPUs to query.
156 * The consumed time is returned as l4_kernel_clock_t at UTCB message
159 L4_INLINE l4_msgtag_t
160 l4_scheduler_idle_time(l4_cap_idx_t scheduler, l4_sched_cpu_set_t const *cpus) L4_NOTHROW;
165 L4_INLINE l4_msgtag_t
166 l4_scheduler_idle_time_u(l4_cap_idx_t scheduler, l4_sched_cpu_set_t const *cpus,
167 l4_utcb_t *utcb) L4_NOTHROW;
172 * \brief Query if a CPU is online.
173 * \ingroup l4_scheduler_api
175 * \param scheduler Scheduler object.
176 * \param cpu CPU number.
177 * \return true if online, false if not (or any other query error).
180 l4_scheduler_is_online(l4_cap_idx_t scheduler, l4_umword_t cpu) L4_NOTHROW;
186 l4_scheduler_is_online_u(l4_cap_idx_t scheduler, l4_umword_t cpu,
187 l4_utcb_t *utcb) L4_NOTHROW;
192 * \brief Operations on the Scheduler object.
193 * \ingroup l4_scheduler_api
197 enum L4_scheduler_ops
199 L4_SCHEDULER_INFO_OP = 0UL, /**< Query infos about the scheduler */
200 L4_SCHEDULER_RUN_THREAD_OP = 1UL, /**< Run a thread on this scheduler */
201 L4_SCHEDULER_IDLE_TIME_OP = 2UL, /**< Query idle time for the scheduler */
204 /*************** Implementations *******************/
206 L4_INLINE l4_sched_cpu_set_t
207 l4_sched_cpu_set(l4_umword_t offset, unsigned char granularity,
208 l4_umword_t map) L4_NOTHROW
210 l4_sched_cpu_set_t cs;
212 cs.granularity = granularity;
217 L4_INLINE l4_sched_param_t
218 l4_sched_param(unsigned prio, l4_cpu_time_t quantum) L4_NOTHROW
222 sp.quantum = quantum;
223 sp.affinity = l4_sched_cpu_set(0, ~0, 1);
228 L4_INLINE l4_msgtag_t
229 l4_scheduler_info_u(l4_cap_idx_t scheduler, l4_umword_t *cpu_max,
230 l4_sched_cpu_set_t *cpus, l4_utcb_t *utcb) L4_NOTHROW
232 l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
235 m->mr[0] = L4_SCHEDULER_INFO_OP;
236 m->mr[1] = (cpus->granularity << 24) | cpus->offset;
238 res = l4_ipc_call(scheduler, utcb, l4_msgtag(L4_PROTO_SCHEDULER, 2, 0, 0), L4_IPC_NEVER);
240 if (l4_msgtag_has_error(res))
243 cpus->map = m->mr[0];
251 L4_INLINE l4_msgtag_t
252 l4_scheduler_run_thread_u(l4_cap_idx_t scheduler, l4_cap_idx_t thread,
253 l4_sched_param_t const *sp, l4_utcb_t *utcb) L4_NOTHROW
255 l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
256 m->mr[0] = L4_SCHEDULER_RUN_THREAD_OP;
257 m->mr[1] = (sp->affinity.granularity << 24) | sp->affinity.offset;
258 m->mr[2] = sp->affinity.map;
260 m->mr[4] = sp->quantum;
261 m->mr[5] = l4_map_obj_control(0, 0);
262 m->mr[6] = l4_obj_fpage(thread, 0, L4_FPAGE_RWX).raw;
264 return l4_ipc_call(scheduler, utcb, l4_msgtag(L4_PROTO_SCHEDULER, 5, 1, 0), L4_IPC_NEVER);
267 L4_INLINE l4_msgtag_t
268 l4_scheduler_idle_time_u(l4_cap_idx_t scheduler, l4_sched_cpu_set_t const *cpus,
269 l4_utcb_t *utcb) L4_NOTHROW
271 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
272 v->mr[0] = L4_SCHEDULER_IDLE_TIME_OP;
273 v->mr[1] = (cpus->granularity << 24) | cpus->offset;
274 v->mr[2] = cpus->map;
275 return l4_ipc_call(scheduler, utcb, l4_msgtag(L4_PROTO_SCHEDULER, 3, 0, 0), L4_IPC_NEVER);
280 l4_scheduler_is_online_u(l4_cap_idx_t scheduler, l4_umword_t cpu,
281 l4_utcb_t *utcb) L4_NOTHROW
283 l4_sched_cpu_set_t s;
287 r = l4_scheduler_info_u(scheduler, NULL, &s, utcb);
288 if (l4_msgtag_has_error(r) || l4_msgtag_label(r) < 0)
295 L4_INLINE l4_msgtag_t
296 l4_scheduler_info(l4_cap_idx_t scheduler, l4_umword_t *cpu_max,
297 l4_sched_cpu_set_t *cpus) L4_NOTHROW
299 return l4_scheduler_info_u(scheduler, cpu_max, cpus, l4_utcb());
302 L4_INLINE l4_msgtag_t
303 l4_scheduler_run_thread(l4_cap_idx_t scheduler,
304 l4_cap_idx_t thread, l4_sched_param_t const *sp) L4_NOTHROW
306 return l4_scheduler_run_thread_u(scheduler, thread, sp, l4_utcb());
309 L4_INLINE l4_msgtag_t
310 l4_scheduler_idle_time(l4_cap_idx_t scheduler, l4_sched_cpu_set_t const *cpus) L4_NOTHROW
312 return l4_scheduler_idle_time_u(scheduler, cpus, l4_utcb());
316 l4_scheduler_is_online(l4_cap_idx_t scheduler, l4_umword_t cpu) L4_NOTHROW
318 return l4_scheduler_is_online_u(scheduler, cpu, l4_utcb());