Mercurial > ecos
annotate packages/kernel/current/src/sched/bitmap.cxx @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | 4c750ce71ae3 |
| children | d2c90368aeef |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // sched/bitmap.cxx |
| 0 | 4 // |
| 2 | 5 // Bitmap scheduler class implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
177
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 40 //========================================================================== |
| 41 //#####DESCRIPTIONBEGIN#### | |
| 42 // | |
| 2 | 43 // Author(s): nickg |
| 44 // Contributors: nickg | |
| 45 // Date: 1997-09-16 | |
| 46 // Purpose: Bitmap scheduler class implementation | |
| 47 // Description: This file contains the implementations of | |
| 0 | 48 // Cyg_Scheduler_Implementation and Cyg_SchedThread_Implementation. |
| 49 // | |
| 50 // | |
| 51 //####DESCRIPTIONEND#### | |
| 52 // | |
| 53 //========================================================================== | |
| 54 | |
| 55 #include <pkgconf/kernel.h> | |
| 56 | |
| 57 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 58 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 59 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 60 | |
| 61 #include <cyg/kernel/sched.hxx> // our header | |
| 62 | |
| 63 #include <cyg/hal/hal_arch.h> // Architecture specific definitions | |
| 64 | |
| 65 #include <cyg/kernel/thread.inl> // thread inlines | |
| 66 #include <cyg/kernel/sched.inl> // scheduler inlines | |
| 67 | |
| 68 #ifdef CYGSEM_KERNEL_SCHED_BITMAP | |
| 69 | |
| 70 //========================================================================== | |
| 71 // Cyg_Scheduler_Implementation class members | |
| 72 | |
| 73 // ------------------------------------------------------------------------- | |
| 74 // Constructor. | |
| 75 | |
| 76 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation() | |
| 77 { | |
| 78 CYG_REPORT_FUNCTION(); | |
| 79 | |
| 80 // At present we cannot init run_queue here because the absence of | |
| 81 // ordering of static constructors means that we could do this | |
| 82 // after the static idle thread has been created. (Guess how I | |
| 83 // found this out!) | |
| 84 // run_queue = 0; | |
| 85 | |
| 86 } | |
| 87 | |
| 88 // ------------------------------------------------------------------------- | |
| 89 // Choose the best thread to run next | |
| 90 | |
| 91 Cyg_Thread *Cyg_Scheduler_Implementation::schedule() | |
| 92 { | |
| 93 CYG_REPORT_FUNCTION(); | |
| 94 | |
| 95 // The run queue may _never_ be empty, there is always | |
| 96 // an idle thread at the lowest priority. | |
| 97 | |
| 98 CYG_ASSERT(run_queue != 0, "Run queue empty"); | |
| 99 | |
| 100 cyg_uint32 index; | |
| 101 | |
| 102 HAL_LSBIT_INDEX(index, run_queue); | |
| 103 | |
| 104 return thread_table[index]; | |
| 105 } | |
| 106 | |
| 107 // ------------------------------------------------------------------------- | |
| 108 | |
| 109 void Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread) | |
| 110 { | |
| 111 CYG_REPORT_FUNCTION(); | |
| 112 | |
|
56
755351606154
Merge from eCos master repository on 1999-12-01-18:03:05-GMT
jlarmour
parents:
46
diff
changeset
|
113 CYG_ASSERT((CYG_THREAD_MIN_PRIORITY >= thread->priority) |
|
755351606154
Merge from eCos master repository on 1999-12-01-18:03:05-GMT
jlarmour
parents:
46
diff
changeset
|
114 && (CYG_THREAD_MAX_PRIORITY <= thread->priority), |
|
755351606154
Merge from eCos master repository on 1999-12-01-18:03:05-GMT
jlarmour
parents:
46
diff
changeset
|
115 "Priority out of range!"); |
|
755351606154
Merge from eCos master repository on 1999-12-01-18:03:05-GMT
jlarmour
parents:
46
diff
changeset
|
116 |
| 0 | 117 CYG_ASSERT( thread_table[thread->priority] == NULL || |
| 118 thread_table[thread->priority] == thread, | |
| 119 "Duplicate thread priorities" ); | |
| 120 | |
| 121 CYG_ASSERT( (run_queue & (1<<thread->priority)) == 0, | |
| 122 "Run queue bit already set" ); | |
| 123 | |
| 124 // If the thread is on some other queue, remove it | |
| 125 // here. | |
| 126 if( thread->queue != NULL ) | |
| 127 { | |
| 128 thread->queue->remove(thread); | |
| 129 thread->queue = NULL; | |
| 130 } | |
| 131 | |
| 132 run_queue |= 1<<thread->priority; | |
| 133 | |
| 134 // If the new thread is higher priority than the | |
| 135 // current thread, request a reschedule. | |
| 136 | |
| 137 if( thread->priority < Cyg_Scheduler::get_current_thread()->priority ) | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
138 set_need_reschedule(); |
| 0 | 139 } |
| 140 | |
| 141 // ------------------------------------------------------------------------- | |
| 142 | |
| 143 void Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread) | |
| 144 { | |
| 145 CYG_REPORT_FUNCTION(); | |
| 146 | |
| 147 CYG_ASSERT( thread_table[thread->priority] == thread, | |
| 148 "Invalid thread priority" ); | |
| 149 | |
| 150 CYG_ASSERT( (run_queue & (1<<thread->priority)) != 0, | |
| 151 "Run queue bit not set" ); | |
| 152 | |
| 153 run_queue &= ~(1<<thread->priority); | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
154 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
155 if( thread == Cyg_Scheduler::get_current_thread() ) |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
156 set_need_reschedule(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
157 } |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
158 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
159 // ------------------------------------------------------------------------- |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
160 // Set up initial idle thread |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
161 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
162 void Cyg_Scheduler_Implementation::set_idle_thread( Cyg_Thread *thread, HAL_SMP_CPU_TYPE cpu ) |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
163 { |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
164 CYG_REPORT_FUNCTION(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
165 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
166 // Make the thread the current thread for this CPU. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
167 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
168 current_thread[cpu] = thread; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
169 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
170 // This will insert the thread in the run queues and make it |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
171 // available to execute. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
160
diff
changeset
|
172 thread->resume(); |
| 0 | 173 } |
| 174 | |
| 175 // ------------------------------------------------------------------------- | |
| 176 // register thread with scheduler | |
| 177 | |
| 178 void Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread) | |
| 179 { | |
| 180 CYG_REPORT_FUNCTION(); | |
| 181 | |
| 182 thread_table[thread->priority] = thread; | |
| 183 } | |
| 184 | |
| 185 // ------------------------------------------------------------------------- | |
| 186 | |
| 187 // deregister thread | |
| 188 void Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread) | |
| 189 { | |
| 190 CYG_REPORT_FUNCTION(); | |
| 191 | |
| 192 thread_table[thread->priority] = NULL; | |
| 193 } | |
| 194 | |
| 195 // ------------------------------------------------------------------------- | |
| 196 // Test the given priority for uniqueness | |
| 197 | |
| 198 cyg_bool Cyg_Scheduler_Implementation::unique( cyg_priority priority) | |
| 199 { | |
| 200 CYG_REPORT_FUNCTION(); | |
| 201 | |
| 202 return thread_table[priority] == NULL; | |
| 203 } | |
| 204 | |
| 205 | |
| 206 //========================================================================== | |
| 207 // Cyg_Cyg_SchedThread_Implementation class members | |
| 208 | |
| 209 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation | |
| 210 ( | |
| 211 CYG_ADDRWORD sched_info | |
| 212 ) | |
| 213 { | |
| 214 CYG_REPORT_FUNCTION(); | |
| 215 | |
| 216 #if 1 | |
| 217 // Assign this thread's priority to the supplied sched_info | |
| 218 // or the next highest priority available. | |
| 219 | |
| 220 priority = cyg_priority(sched_info); | |
| 221 | |
| 222 while( !Cyg_Scheduler::scheduler.unique(priority) ) | |
| 223 priority++; | |
| 224 | |
| 225 #else | |
| 226 // Assign initial priorities to threads in descending order of | |
| 227 // creation. | |
| 228 | |
| 229 static cyg_priority init_priority = 0; | |
| 230 | |
| 231 priority = init_priority++; | |
| 232 #endif | |
| 233 | |
| 234 } | |
| 235 | |
| 236 // ------------------------------------------------------------------------- | |
| 237 | |
| 238 void Cyg_SchedThread_Implementation::yield() | |
| 239 { | |
| 240 CYG_REPORT_FUNCTION(); | |
| 241 | |
| 242 // We cannot yield in this scheduler | |
| 243 } | |
| 244 | |
| 245 //========================================================================== | |
| 246 // Cyg_ThreadQueue_Implementation class members | |
| 247 | |
| 248 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation() | |
| 249 { | |
| 250 CYG_REPORT_FUNCTION(); | |
| 251 | |
| 252 wait_queue = 0; // empty queue | |
| 2 | 253 |
| 254 CYG_REPORT_RETURN(); | |
| 0 | 255 } |
| 256 | |
| 257 | |
| 258 void Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread) | |
| 259 { | |
| 260 CYG_REPORT_FUNCTION(); | |
| 261 | |
| 262 wait_queue |= 1<<thread->priority; | |
| 263 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, | |
| 264 Cyg_ThreadQueue_Implementation, | |
| 265 this); | |
| 266 } | |
| 267 | |
| 268 // ------------------------------------------------------------------------- | |
| 269 | |
| 270 Cyg_Thread *Cyg_ThreadQueue_Implementation::dequeue() | |
| 271 { | |
| 272 CYG_REPORT_FUNCTION(); | |
| 273 | |
| 274 // Isolate ls bit in run_queue. | |
| 275 cyg_sched_bitmap next_thread = wait_queue & -wait_queue; | |
| 276 | |
| 277 if( next_thread == 0 ) return NULL; | |
| 278 | |
| 279 wait_queue &= ~next_thread; | |
| 280 | |
| 281 cyg_uint32 index; | |
| 282 | |
| 283 HAL_LSBIT_INDEX(index, next_thread); | |
| 284 | |
| 285 Cyg_Thread *thread = Cyg_Scheduler::scheduler.thread_table[index]; | |
| 286 | |
| 287 thread->queue = NULL; | |
| 288 | |
| 289 return thread; | |
| 290 } | |
| 291 | |
| 292 // ------------------------------------------------------------------------- | |
| 293 | |
| 294 Cyg_Thread *Cyg_ThreadQueue_Implementation::highpri() | |
| 295 { | |
| 296 CYG_REPORT_FUNCTION(); | |
| 297 | |
| 298 // Isolate ls bit in run_queue. | |
| 299 cyg_sched_bitmap next_thread = wait_queue & -wait_queue; | |
| 300 | |
| 301 if( next_thread == 0 ) return NULL; | |
| 302 | |
| 303 cyg_uint32 index; | |
| 304 | |
| 305 HAL_LSBIT_INDEX(index, next_thread); | |
| 306 | |
| 307 return Cyg_Scheduler::scheduler.thread_table[index]; | |
| 308 } | |
| 309 | |
| 310 // ------------------------------------------------------------------------- | |
| 311 | |
| 312 void Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread) | |
| 313 { | |
| 314 CYG_REPORT_FUNCTION(); | |
| 315 | |
| 316 wait_queue &= ~(1<<thread->priority); | |
| 317 thread->queue = NULL; | |
| 318 } | |
| 319 | |
| 320 #endif | |
| 321 | |
| 322 // ------------------------------------------------------------------------- | |
| 323 // EOF sched/bitmap.cxx |
