comparison packages/kernel/current/src/sched/bitmap.cxx @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 //==========================================================================
2 //
3 // sched/bitmap.cxx
4 //
5 // Bitmap scheduler class implementation
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //==========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): nickg
33 // Contributors: nickg
34 // Date: 1997-09-16
35 // Purpose: Bitmap scheduler class implementation
36 // Description: This file contains the implementations of
37 // Cyg_Scheduler_Implementation and Cyg_SchedThread_Implementation.
38 //
39 //
40 //####DESCRIPTIONEND####
41 //
42 //==========================================================================
43
44 #include <pkgconf/kernel.h>
45
46 #include <cyg/kernel/ktypes.h> // base kernel types
47 #include <cyg/infra/cyg_trac.h> // tracing macros
48 #include <cyg/infra/cyg_ass.h> // assertion macros
49
50 #include <cyg/kernel/sched.hxx> // our header
51
52 #include <cyg/hal/hal_arch.h> // Architecture specific definitions
53
54 #include <cyg/kernel/thread.inl> // thread inlines
55 #include <cyg/kernel/sched.inl> // scheduler inlines
56
57 #ifdef CYGSEM_KERNEL_SCHED_BITMAP
58
59 //==========================================================================
60 // Cyg_Scheduler_Implementation class members
61
62 // -------------------------------------------------------------------------
63 // Constructor.
64
65 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation()
66 {
67 CYG_REPORT_FUNCTION();
68
69 // At present we cannot init run_queue here because the absence of
70 // ordering of static constructors means that we could do this
71 // after the static idle thread has been created. (Guess how I
72 // found this out!)
73 // run_queue = 0;
74
75 }
76
77 // -------------------------------------------------------------------------
78 // Choose the best thread to run next
79
80 Cyg_Thread *Cyg_Scheduler_Implementation::schedule()
81 {
82 CYG_REPORT_FUNCTION();
83
84 // The run queue may _never_ be empty, there is always
85 // an idle thread at the lowest priority.
86
87 CYG_ASSERT(run_queue != 0, "Run queue empty");
88
89 cyg_uint32 index;
90
91 HAL_LSBIT_INDEX(index, run_queue);
92
93 return thread_table[index];
94 }
95
96 // -------------------------------------------------------------------------
97
98 void Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread)
99 {
100 CYG_REPORT_FUNCTION();
101
102 CYG_ASSERT( thread_table[thread->priority] == NULL ||
103 thread_table[thread->priority] == thread,
104 "Duplicate thread priorities" );
105
106 CYG_ASSERT( (run_queue & (1<<thread->priority)) == 0,
107 "Run queue bit already set" );
108
109 // If the thread is on some other queue, remove it
110 // here.
111 if( thread->queue != NULL )
112 {
113 thread->queue->remove(thread);
114 thread->queue = NULL;
115 }
116
117 run_queue |= 1<<thread->priority;
118
119 // If the new thread is higher priority than the
120 // current thread, request a reschedule.
121
122 if( thread->priority < Cyg_Scheduler::get_current_thread()->priority )
123 need_reschedule = true;
124 }
125
126 // -------------------------------------------------------------------------
127
128 void Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread)
129 {
130 CYG_REPORT_FUNCTION();
131
132 CYG_ASSERT( thread_table[thread->priority] == thread,
133 "Invalid thread priority" );
134
135 CYG_ASSERT( (run_queue & (1<<thread->priority)) != 0,
136 "Run queue bit not set" );
137
138 run_queue &= ~(1<<thread->priority);
139
140 if( thread == Cyg_Scheduler::get_current_thread() )
141 need_reschedule = true;
142 }
143
144 // -------------------------------------------------------------------------
145 // register thread with scheduler
146
147 void Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread)
148 {
149 CYG_REPORT_FUNCTION();
150
151 thread_table[thread->priority] = thread;
152 }
153
154 // -------------------------------------------------------------------------
155
156 // deregister thread
157 void Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread)
158 {
159 CYG_REPORT_FUNCTION();
160
161 thread_table[thread->priority] = NULL;
162 }
163
164 // -------------------------------------------------------------------------
165 // Test the given priority for uniqueness
166
167 cyg_bool Cyg_Scheduler_Implementation::unique( cyg_priority priority)
168 {
169 CYG_REPORT_FUNCTION();
170
171 return thread_table[priority] == NULL;
172 }
173
174
175 //==========================================================================
176 // Cyg_Cyg_SchedThread_Implementation class members
177
178 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation
179 (
180 CYG_ADDRWORD sched_info
181 )
182 {
183 CYG_REPORT_FUNCTION();
184
185 #if 1
186 // Assign this thread's priority to the supplied sched_info
187 // or the next highest priority available.
188
189 priority = cyg_priority(sched_info);
190
191 while( !Cyg_Scheduler::scheduler.unique(priority) )
192 priority++;
193
194 #else
195 // Assign initial priorities to threads in descending order of
196 // creation.
197
198 static cyg_priority init_priority = 0;
199
200 priority = init_priority++;
201 #endif
202
203 }
204
205 // -------------------------------------------------------------------------
206
207 void Cyg_SchedThread_Implementation::yield()
208 {
209 CYG_REPORT_FUNCTION();
210
211 // We cannot yield in this scheduler
212 }
213
214 //==========================================================================
215 // Cyg_ThreadQueue_Implementation class members
216
217 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation()
218 {
219 CYG_REPORT_FUNCTION();
220
221 wait_queue = 0; // empty queue
222 }
223
224
225 void Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread)
226 {
227 CYG_REPORT_FUNCTION();
228
229 wait_queue |= 1<<thread->priority;
230 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue,
231 Cyg_ThreadQueue_Implementation,
232 this);
233 }
234
235 // -------------------------------------------------------------------------
236
237 Cyg_Thread *Cyg_ThreadQueue_Implementation::dequeue()
238 {
239 CYG_REPORT_FUNCTION();
240
241 // Isolate ls bit in run_queue.
242 cyg_sched_bitmap next_thread = wait_queue & -wait_queue;
243
244 if( next_thread == 0 ) return NULL;
245
246 wait_queue &= ~next_thread;
247
248 cyg_uint32 index;
249
250 HAL_LSBIT_INDEX(index, next_thread);
251
252 Cyg_Thread *thread = Cyg_Scheduler::scheduler.thread_table[index];
253
254 thread->queue = NULL;
255
256 return thread;
257 }
258
259 // -------------------------------------------------------------------------
260
261 Cyg_Thread *Cyg_ThreadQueue_Implementation::highpri()
262 {
263 CYG_REPORT_FUNCTION();
264
265 // Isolate ls bit in run_queue.
266 cyg_sched_bitmap next_thread = wait_queue & -wait_queue;
267
268 if( next_thread == 0 ) return NULL;
269
270 cyg_uint32 index;
271
272 HAL_LSBIT_INDEX(index, next_thread);
273
274 return Cyg_Scheduler::scheduler.thread_table[index];
275 }
276
277 // -------------------------------------------------------------------------
278
279 void Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread)
280 {
281 CYG_REPORT_FUNCTION();
282
283 wait_queue &= ~(1<<thread->priority);
284 thread->queue = NULL;
285 }
286
287 #endif
288
289 // -------------------------------------------------------------------------
290 // EOF sched/bitmap.cxx