FreeBSD/Linux Kernel Cross Reference
sys/sched_policy/dm.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: dm.c,v $
29 * Revision 2.2 93/11/17 18:36:45 dbg
30 * Add per-policy scheduling parameters to thread and run queue.
31 * [93/05/10 dbg]
32 *
33 * Moved common operations to kern/run_queues.c.
34 * [93/04/10 dbg]
35 *
36 * Converted to per-policy run queue structure.
37 * [93/04/09 dbg]
38 *
39 * Merged into microkernel mainline.
40 *
41 * Changed deadline to time_spec_t.
42 * [92/09/06 savage]
43 * Added policy_init()
44 * [92/06/01 savage]
45 * Created
46 * [92/05/04 takuro]
47 *
48 */
49
50 /*
51 * Deadline-monotonic scheduling policy.
52 *
53 * Threads are scheduled in the order of shortest
54 * deadline interval first.
55 */
56 #include <mach_kdb.h>
57
58 #include <mach/boolean.h>
59 #include <mach/time_spec.h>
60 #include <mach/realtime_policy.h>
61
62 #include <kern/macro_help.h>
63 #include <kern/ast.h>
64 #include <kern/kalloc.h>
65 #include <kern/run_queues.h>
66 #include <kern/sched_policy.h>
67 #include <kern/processor.h>
68 #include <kern/thread.h>
69 #include <kern/rt_thread.h>
70 #include <sched_policy/real_time.h>
71
72 /*
73 * Uses a single run queue, ordered by deadline interval.
74 * No policy limits.
75 */
76 struct dm_run_queue {
77 struct run_queue rq; /* common structure */
78 queue_head_t dm_queue; /* queue */
79 };
80 typedef struct dm_run_queue * dm_run_queue_t;
81
82 #define dm_runq(rq) ((struct dm_run_queue *)(rq))
83 #define dm_count rq.rq_count
84
85 /*
86 * Choose thread.
87 */
88 thread_t
89 dm_thread_dequeue(
90 run_queue_t runq)
91 {
92 dm_run_queue_t rq = dm_runq(runq);
93 queue_entry_t elt;
94
95 assert(rq->dm_count > 0);
96 assert(!queue_empty(&rq->dm_queue));
97
98 dequeue_head_macro(&rq->dm_queue, elt);
99 rq->dm_count--;
100
101 current_processor()->first_quantum = TRUE; /* XXX */
102
103 return (thread_t) elt;
104 }
105
106 /*
107 * Put a thread onto a run queue in priority order.
108 * Return whether it can preempt the current thread.
109 */
110 boolean_t dm_thread_enqueue(
111 run_queue_t runq,
112 thread_t thread,
113 boolean_t may_preempt)
114 {
115 register dm_run_queue_t rq;
116 register thread_t next;
117 register queue_t q;
118
119 rq = dm_runq(runq);
120
121 q = &rq->dm_queue;
122 queue_iterate(q, next, thread_t, links) {
123 if (time_spec_leq(rt_sched(thread)->deadline,
124 rt_sched(next)->deadline))
125 break;
126 }
127 enqueue_tail_macro((queue_t) next, (queue_entry_t) thread);
128 rq->dm_count++;
129
130 if (!may_preempt)
131 return FALSE;
132
133 {
134 thread_t cth = current_thread();
135
136 return !time_spec_leq(rt_sched(cth)->deadline,
137 rt_sched(thread)->deadline);
138 }
139 }
140
141 /*
142 * Remove a thread from the run queue.
143 */
144 void dm_thread_remqueue(
145 run_queue_t runq,
146 thread_t thread)
147 {
148 dm_run_queue_t rq = dm_runq(runq);
149
150 remqueue(&rq->dm_queue, (queue_entry_t) thread);
151 rq->dm_count--;
152 }
153
154 boolean_t dm_csw_needed(
155 run_queue_t runq,
156 thread_t thread)
157 {
158 dm_run_queue_t rq = dm_runq(runq);
159 thread_t th;
160
161 th = (thread_t) queue_first(&rq->dm_queue);
162
163 return time_spec_leq(rt_sched(th)->deadline,
164 rt_sched(thread)->deadline);
165 }
166
167 extern struct sched_policy dm_sched_policy; /* forward */
168
169 run_queue_t
170 dm_run_queue_alloc(void)
171 {
172 dm_run_queue_t rq;
173
174 rq = (dm_run_queue_t) kalloc(sizeof(struct dm_run_queue));
175 run_queue_init(&rq->rq, &dm_sched_policy);
176
177 queue_init(&rq->dm_queue);
178
179 return &rq->rq;
180 }
181
182 void
183 dm_run_queue_free(
184 run_queue_t runq)
185 {
186 kfree((vm_offset_t) runq, sizeof(struct dm_run_queue));
187 }
188
189 #if MACH_KDB
190 #include <ddb/db_output.h>
191 void dm_thread_db_print(
192 thread_t thread)
193 {
194 db_printf("DM ");
195 }
196 #endif
197
198 /*
199 * Statically allocated policy structure.
200 */
201 struct sched_policy dm_sched_policy = {
202 {
203 /* sched_ops */
204 dm_thread_dequeue,
205 dm_thread_enqueue,
206 dm_thread_remqueue,
207
208 dm_csw_needed,
209 ast_check,
210 0, /* no update_priority */
211
212 dm_run_queue_alloc,
213 dm_run_queue_free,
214
215 rt_runq_set_limit,
216 rt_runq_get_limit,
217 rt_thread_set_limit,
218 rt_thread_set_param,
219 rt_thread_get_param,
220 rt_task_set_param,
221 rt_task_get_param,
222
223 #if MACH_KDB
224 dm_thread_db_print
225 #endif
226
227 },
228 POLICY_DEADLINE_MONOTONIC,
229 "deadline monotonic"
230 };
231
Cache object: b3397cbe919415430d0e22fdfbb5a275
|