Mercurial > ecos
annotate packages/kernel/current/src/sched/mlqueue.cxx @ 128:0c2b7be0d798 ecos-sw-2000-10-12
Merge from eCos master repository on 2000-10-12-08:46:24-BST
| author | jlarmour |
|---|---|
| date | Thu, 12 Oct 2000 20:31:43 +0000 |
| parents | 0ec04793409a |
| children | 8f2f7615e727 |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // sched/mlqueue.cxx |
| 0 | 4 // |
| 2 | 5 // Multi-level queue scheduler class implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
9 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
10 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
11 // The contents of this file are subject to the Red Hat eCos Public License |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
12 // Version 1.1 (the "License"); you may not use this file except in |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
13 // compliance with the License. You may obtain a copy of the License at |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
14 // http://www.redhat.com/ |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
15 // |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
18 // License for the specific language governing rights and limitations under |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
19 // the License. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
20 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
21 // The Original Code is eCos - Embedded Configurable Operating System, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
22 // released September 30, 1998. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
23 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
24 // The Initial Developer of the Original Code is Red Hat. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
25 // Portions created by Red Hat are |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
27 // All Rights Reserved. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
28 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
29 // |
| 0 | 30 //####COPYRIGHTEND#### |
| 31 //========================================================================== | |
| 32 //#####DESCRIPTIONBEGIN#### | |
| 33 // | |
| 2 | 34 // Author(s): nickg |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
35 // Contributors: jlarmour |
| 2 | 36 // Date: 1999-02-17 |
| 37 // Purpose: Multilevel queue scheduler class implementation | |
| 38 // Description: This file contains the implementations of | |
| 39 // Cyg_Scheduler_Implementation and | |
| 40 // Cyg_SchedThread_Implementation. | |
| 0 | 41 // |
| 42 // | |
| 43 //####DESCRIPTIONEND#### | |
| 44 // | |
| 45 //========================================================================== | |
| 46 | |
| 47 #include <pkgconf/kernel.h> | |
| 48 | |
| 49 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 50 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 51 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 52 | |
| 53 #include <cyg/kernel/sched.hxx> // our header | |
| 54 | |
| 55 #include <cyg/hal/hal_arch.h> // Architecture specific definitions | |
| 56 | |
| 57 #include <cyg/kernel/thread.inl> // thread inlines | |
| 58 #include <cyg/kernel/sched.inl> // scheduler inlines | |
| 59 | |
| 60 #ifdef CYGSEM_KERNEL_SCHED_MLQUEUE | |
| 61 | |
| 62 //------------------------------------------------------------------------- | |
| 63 // Some local tracing control - a default. | |
| 64 #ifdef CYGDBG_USE_TRACING | |
| 65 # if !defined( CYGDBG_INFRA_DEBUG_TRACE_ASSERT_SIMPLE ) && \ | |
| 66 !defined( CYGDBG_INFRA_DEBUG_TRACE_ASSERT_FANCY ) | |
| 67 // ie. not a tracing implementation that takes a long time to output | |
| 68 | |
| 69 # ifndef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 70 # define CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 71 # endif // control not already defined | |
| 72 | |
| 73 # endif // trace implementation not ..._SIMPLE && not ..._FANCY | |
| 74 #endif // CYGDBG_USE_TRACING | |
| 75 | |
| 76 //========================================================================== | |
| 77 // Cyg_Scheduler_Implementation class static members | |
| 78 | |
| 79 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 80 | |
| 81 cyg_ucount32 Cyg_Scheduler_Implementation::timeslice_count = | |
| 82 CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS; | |
| 83 | |
| 84 #endif | |
| 85 | |
| 86 | |
| 87 //========================================================================== | |
| 88 // Cyg_Scheduler_Implementation class members | |
| 89 | |
| 90 // ------------------------------------------------------------------------- | |
| 91 // Constructor. | |
| 92 | |
| 93 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation() | |
| 94 { | |
| 95 CYG_REPORT_FUNCTION(); | |
| 96 | |
| 97 queue_map = 0; | |
| 2 | 98 |
| 99 CYG_REPORT_RETURN(); | |
| 0 | 100 } |
| 101 | |
| 102 // ------------------------------------------------------------------------- | |
| 103 // Choose the best thread to run next | |
| 104 | |
| 2 | 105 Cyg_Thread * |
| 106 Cyg_Scheduler_Implementation::schedule(void) | |
| 0 | 107 { |
| 2 | 108 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 0 | 109 |
| 110 // The run queue may _never_ be empty, there is always | |
| 111 // an idle thread at the lowest priority. | |
| 112 | |
| 113 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 114 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 115 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 116 | |
| 117 register cyg_uint32 index; | |
| 118 | |
| 119 HAL_LSBIT_INDEX(index, queue_map); | |
| 120 | |
| 121 Cyg_Thread *thread = run_queue[index].highpri(); | |
| 122 | |
| 123 CYG_ASSERT( thread != NULL , "No threads in run queue"); | |
| 124 | |
| 2 | 125 CYG_REPORT_RETVAL(thread); |
| 126 | |
| 0 | 127 return thread; |
| 128 } | |
| 129 | |
| 130 // ------------------------------------------------------------------------- | |
| 131 | |
| 2 | 132 void |
| 133 Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread) | |
| 0 | 134 { |
| 135 CYG_REPORT_FUNCTION(); | |
| 2 | 136 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 137 |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
138 cyg_priority pri = thread->priority; |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
139 Cyg_SchedulerThreadQueue_Implementation *queue = &run_queue[pri]; |
| 0 | 140 |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
141 CYG_ASSERT((CYG_THREAD_MIN_PRIORITY >= pri) |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
142 && (CYG_THREAD_MAX_PRIORITY <= pri), |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
143 "Priority out of range!"); |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
144 |
| 0 | 145 // If the thread is on some other queue, remove it |
| 146 // here. | |
| 147 if( thread->queue != NULL ) | |
| 148 { | |
| 149 thread->queue->remove(thread); | |
| 150 thread->queue = NULL; | |
| 151 } | |
| 152 | |
| 153 if( queue->empty() ) | |
| 154 { | |
| 155 // set the map bit and ask for a reschedule if this is a | |
| 156 // new highest priority thread. | |
| 157 | |
| 158 queue_map |= (1<<pri); | |
| 159 | |
| 160 // If the new thread is higher priority than the | |
| 161 // current thread, request a reschedule. | |
| 162 | |
| 163 if( pri < Cyg_Scheduler::get_current_thread()->priority ) | |
| 164 need_reschedule = true; | |
| 165 | |
| 166 } | |
| 167 // else the queue already has an occupant, queue behind him | |
| 168 | |
| 169 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 170 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri"); | |
| 171 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 172 // CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 173 | |
| 2 | 174 queue->enqueue(thread); |
| 175 | |
| 176 CYG_REPORT_RETURN(); | |
| 0 | 177 } |
| 178 | |
| 179 // ------------------------------------------------------------------------- | |
| 180 | |
| 2 | 181 void |
| 182 Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread) | |
| 0 | 183 { |
| 184 CYG_REPORT_FUNCTION(); | |
| 2 | 185 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 186 |
| 187 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 188 | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
189 cyg_priority pri = thread->priority; |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
190 Cyg_SchedulerThreadQueue_Implementation *queue = &run_queue[pri]; |
| 0 | 191 |
| 192 CYG_ASSERT( pri != CYG_THREAD_MIN_PRIORITY, "Idle thread trying to sleep!"); | |
| 193 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri"); | |
| 194 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 195 | |
| 196 // remove thread from queue | |
| 197 queue->remove(thread); | |
| 198 | |
| 199 if( queue->empty() ) | |
| 200 { | |
| 201 // If this was only thread in | |
| 202 // queue, clear map. | |
| 203 | |
| 204 queue_map &= ~(1<<pri); | |
| 205 } | |
| 206 | |
| 207 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 208 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 209 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 2 | 210 |
| 211 CYG_REPORT_RETURN(); | |
| 0 | 212 } |
| 213 | |
| 214 // ------------------------------------------------------------------------- | |
| 215 // register thread with scheduler | |
| 216 | |
| 2 | 217 void |
| 218 Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread) | |
| 0 | 219 { |
| 220 CYG_REPORT_FUNCTION(); | |
| 2 | 221 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 222 // No registration necessary in this scheduler |
| 2 | 223 CYG_REPORT_RETURN(); |
| 0 | 224 } |
| 225 | |
| 226 // ------------------------------------------------------------------------- | |
| 227 | |
| 228 // deregister thread | |
| 2 | 229 void |
| 230 Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread) | |
| 0 | 231 { |
| 232 CYG_REPORT_FUNCTION(); | |
| 2 | 233 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 234 // No registration necessary in this scheduler |
| 2 | 235 CYG_REPORT_RETURN(); |
| 0 | 236 } |
| 237 | |
| 238 // ------------------------------------------------------------------------- | |
| 239 // Test the given priority for uniqueness | |
| 240 | |
| 2 | 241 cyg_bool |
| 242 Cyg_Scheduler_Implementation::unique( cyg_priority priority) | |
| 0 | 243 { |
| 2 | 244 CYG_REPORT_FUNCTYPE("returning %d"); |
| 245 CYG_REPORT_FUNCARG1("priority=%d", priority); | |
| 0 | 246 // Priorities are not unique |
| 2 | 247 CYG_REPORT_RETVAL(true); |
| 0 | 248 return true; |
| 249 } | |
| 250 | |
| 251 //========================================================================== | |
| 252 // Support for timeslicing option | |
| 253 | |
| 254 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 255 | |
| 2 | 256 void |
| 257 Cyg_Scheduler_Implementation::timeslice(void) | |
| 0 | 258 { |
| 259 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 260 CYG_REPORT_FUNCTION(); | |
| 261 #endif | |
| 262 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 263 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
264 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
265 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
266 if( current_thread->timeslice_enabled && --timeslice_count == 0 ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
267 #else |
| 0 | 268 if( --timeslice_count == 0 ) |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
269 #endif |
| 0 | 270 { |
| 271 CYG_INSTRUMENT_SCHED(TIMESLICE,0,0); | |
| 272 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 273 CYG_TRACE0( true, "quantum consumed, time to reschedule" ); | |
| 274 #endif | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
275 |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
276 CYG_ASSERT( sched_lock > 0 , "Timeslice called with zero sched_lock"); |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
277 |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
278 Cyg_Thread *thread = current_thread; |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
279 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
280 // Only try to rotate the run queue if the current thread is running. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
281 // Otherwise we are going to reschedule anyway. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
282 if( thread->get_state() == Cyg_Thread::RUNNING ) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
283 { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
284 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
285 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
286 CYG_ASSERTCLASS( thread, "Bad current thread"); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
287 CYG_ASSERTCLASS( sched, "Bad scheduler"); |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
288 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
289 cyg_priority pri = thread->priority; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
290 Cyg_SchedulerThreadQueue_Implementation *queue = &sched->run_queue[pri]; |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
291 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
292 queue->rotate(); |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
293 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
294 if( queue->highpri() != thread ) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
295 sched->need_reschedule = true; |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
296 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
297 timeslice_count = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
298 } |
| 0 | 299 } |
| 300 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
301 |
| 0 | 302 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); |
| 303 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 304 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 305 CYG_REPORT_RETURN(); | |
| 306 #endif | |
| 307 } | |
| 308 | |
| 309 #endif | |
| 310 | |
| 311 //========================================================================== | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
312 // Cyg_SchedThread_Implementation class members |
| 0 | 313 |
| 314 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation | |
| 315 ( | |
| 316 CYG_ADDRWORD sched_info | |
| 317 ) | |
| 318 { | |
| 319 CYG_REPORT_FUNCTION(); | |
| 2 | 320 CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info); |
| 0 | 321 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
322 // Set priority to the supplied value. |
| 0 | 323 priority = (cyg_priority)sched_info; |
| 324 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
325 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
326 // If timeslice_enabled exists, set it true by default |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
327 timeslice_enabled = true; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
328 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
329 |
| 0 | 330 // point the next and prev field at this thread. |
| 331 | |
| 332 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 333 Cyg_SchedThread_Implementation, | |
| 334 this); | |
| 2 | 335 CYG_REPORT_RETURN(); |
| 0 | 336 } |
| 337 | |
| 338 // ------------------------------------------------------------------------- | |
| 339 // Insert thread in front of this | |
| 340 | |
| 2 | 341 void |
| 342 Cyg_SchedThread_Implementation::insert( Cyg_Thread *thread) | |
| 0 | 343 { |
| 344 CYG_REPORT_FUNCTION(); | |
| 2 | 345 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 346 |
| 347 thread->next = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 348 Cyg_SchedThread_Implementation, | |
| 349 this); | |
| 350 thread->prev = prev; | |
| 351 prev->next = thread; | |
| 352 prev = thread; | |
| 2 | 353 |
| 354 CYG_REPORT_RETURN(); | |
| 0 | 355 } |
| 356 | |
| 357 // ------------------------------------------------------------------------- | |
| 358 // remove this from queue | |
| 359 | |
| 2 | 360 void |
| 361 Cyg_SchedThread_Implementation::remove(void) | |
| 0 | 362 { |
| 363 CYG_REPORT_FUNCTION(); | |
| 364 | |
| 365 next->prev = prev; | |
| 366 prev->next = next; | |
| 367 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 368 Cyg_SchedThread_Implementation, | |
| 369 this); | |
| 2 | 370 CYG_REPORT_RETURN(); |
| 0 | 371 } |
| 372 | |
| 373 // ------------------------------------------------------------------------- | |
| 374 // Yield the processor to another thread | |
| 375 | |
| 2 | 376 void |
| 377 Cyg_SchedThread_Implementation::yield(void) | |
| 0 | 378 { |
| 379 CYG_REPORT_FUNCTION(); | |
| 380 | |
| 381 // Prevent preemption | |
| 382 Cyg_Scheduler::lock(); | |
| 383 | |
| 384 Cyg_Thread *thread = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 385 Cyg_SchedThread_Implementation, | |
| 386 this); | |
| 387 | |
| 388 // Only do this if this thread is running. If it is not, there | |
| 389 // is no point. | |
| 390 | |
| 391 if( thread->get_state() == Cyg_Thread::RUNNING ) | |
| 392 { | |
| 393 // To yield we simply rotate the appropriate | |
| 394 // run queue to the next thread and reschedule. | |
| 395 | |
| 396 CYG_ASSERTCLASS( thread, "Bad current thread"); | |
| 397 | |
| 398 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; | |
| 399 | |
| 400 CYG_ASSERTCLASS( sched, "Bad scheduler"); | |
| 401 | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
402 cyg_priority pri = thread->priority; |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
403 Cyg_SchedulerThreadQueue_Implementation *queue = &sched->run_queue[pri]; |
| 0 | 404 |
| 405 queue->rotate(); | |
| 406 | |
| 407 if( queue->highpri() != thread ) | |
| 408 sched->need_reschedule = true; | |
| 409 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 410 // Reset the timeslice counter so that this thread gets a full | |
| 411 // quantum. | |
| 412 else Cyg_Scheduler::reset_timeslice_count(); | |
| 413 #endif | |
| 414 } | |
| 415 | |
| 416 // Unlock the scheduler and switch threads | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
417 #ifdef CYGDBG_USE_ASSERTS |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
418 // This test keeps the assertions in unlock_inner() happy if |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
419 // need_reschedule was not set above. |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
420 if( !Cyg_Scheduler::need_reschedule ) |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
421 Cyg_Scheduler::unlock(); |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
422 else |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
423 #endif |
|
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
424 Cyg_Scheduler::unlock_reschedule(); |
| 0 | 425 |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
426 |
| 2 | 427 CYG_REPORT_RETURN(); |
| 0 | 428 } |
| 429 | |
| 430 // ------------------------------------------------------------------------- | |
| 431 // Rotate the run queue at a specified priority. | |
| 432 // (pri is the decider, no this, so the routine is static) | |
| 433 | |
| 434 void | |
| 435 Cyg_SchedThread_Implementation::rotate_queue( cyg_priority pri ) | |
| 436 { | |
| 437 CYG_REPORT_FUNCTION(); | |
| 2 | 438 CYG_REPORT_FUNCARG1("priority=%d", pri); |
| 0 | 439 |
| 440 // Prevent preemption | |
| 441 Cyg_Scheduler::lock(); | |
| 442 | |
| 443 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; | |
| 444 | |
| 445 CYG_ASSERTCLASS( sched, "Bad scheduler"); | |
| 446 | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
447 Cyg_SchedulerThreadQueue_Implementation *queue = &sched->run_queue[pri]; |
| 0 | 448 |
| 449 if ( !queue->empty() ) { | |
| 450 queue->rotate(); | |
| 451 sched->need_reschedule = true; | |
| 452 } | |
| 453 | |
| 454 // Unlock the scheduler and switch threads | |
| 455 Cyg_Scheduler::unlock(); | |
| 456 | |
| 2 | 457 CYG_REPORT_RETURN(); |
| 458 } | |
| 459 | |
| 460 // ------------------------------------------------------------------------- | |
| 461 // Move this thread to the head of its queue | |
| 462 // (not necessarily a scheduler queue) | |
| 463 | |
| 464 void | |
| 465 Cyg_SchedThread_Implementation::to_queue_head( void ) | |
| 466 { | |
| 467 CYG_REPORT_FUNCTION(); | |
| 468 | |
| 469 // Prevent preemption | |
| 470 Cyg_Scheduler::lock(); | |
| 471 | |
| 472 Cyg_Thread *thread = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 473 Cyg_SchedThread_Implementation, | |
| 474 this); | |
| 475 | |
| 476 CYG_ASSERTCLASS( thread, "Bad current thread"); | |
| 477 | |
| 478 Cyg_ThreadQueue *q = thread->get_current_queue(); | |
| 479 q->to_head( thread ); | |
| 480 | |
| 481 // Unlock the scheduler and switch threads | |
| 482 Cyg_Scheduler::unlock(); | |
| 483 | |
| 484 CYG_REPORT_RETURN(); | |
| 0 | 485 } |
| 486 | |
| 487 //========================================================================== | |
| 488 // Cyg_ThreadQueue_Implementation class members | |
| 489 | |
| 490 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation() | |
| 491 { | |
| 492 CYG_REPORT_FUNCTION(); | |
| 493 | |
| 494 queue = NULL; // empty queue | |
| 2 | 495 |
| 496 CYG_REPORT_RETURN(); | |
| 0 | 497 } |
| 498 | |
| 499 | |
| 500 | |
| 2 | 501 void |
| 502 Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread) | |
| 0 | 503 { |
| 504 CYG_REPORT_FUNCTION(); | |
| 2 | 505 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 506 |
| 507 if( queue == NULL ) queue = thread; | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
508 else { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
509 #ifdef CYGIMP_KERNEL_SCHED_SORTED_QUEUES |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
510 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
511 // Insert the thread into the queue in priority order. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
512 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
513 if( queue == queue->next ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
514 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
515 // There is only one other thread in the queue, join it |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
516 // and adjust the queue pointer to point to the highest |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
517 // priority of the two. If they are the same priority, |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
518 // leave the pointer pointing to the oldest. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
519 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
520 queue->insert( thread ); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
521 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
522 if( thread->priority < queue->priority ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
523 queue = thread; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
524 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
525 else |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
526 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
527 // There is more than one thread in the queue. First check |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
528 // whether we are of higher priority than the head and if |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
529 // so just jump in at the front. Also check whether we are |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
530 // lower priority than the tail and jump onto the end. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
531 // Otherwise we really have to search the queue to find |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
532 // our place. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
533 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
534 if( thread->priority < queue->priority ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
535 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
536 queue->insert( thread ); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
537 queue = thread; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
538 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
539 else if( thread->priority > queue->prev->priority ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
540 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
541 // We are lower priority than any thread in the queue, |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
542 // go in at the end. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
543 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
544 queue->prev->insert( thread ); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
545 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
546 else |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
547 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
548 // Search the queue. We do this backwards so that we |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
549 // always add new threads after any that have the same |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
550 // priority. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
551 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
552 // Because of the previous tests we know that this |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
553 // search will terminate before we hit the head of the |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
554 // queue, hence we do not need to check for that |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
555 // condition. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
556 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
557 Cyg_Thread *qtmp = queue->prev; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
558 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
559 // Scan the queue until we find a higher or equal |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
560 // priority thread. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
561 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
562 while( thread->priority > qtmp->priority ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
563 qtmp = qtmp->prev; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
564 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
565 // Insert ourself after the node pointed to by qtmp. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
566 // We do this by inserting before the next node since |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
567 // that is the operation we have. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
568 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
569 qtmp->next->insert( thread ); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
570 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
571 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
572 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
573 #else |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
574 queue->prev->insert(thread); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
575 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
576 } |
| 0 | 577 |
| 578 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, | |
| 579 Cyg_ThreadQueue_Implementation, | |
| 580 this); | |
| 2 | 581 CYG_REPORT_RETURN(); |
| 0 | 582 } |
| 583 | |
| 584 // ------------------------------------------------------------------------- | |
| 585 | |
| 2 | 586 Cyg_Thread * |
| 587 Cyg_ThreadQueue_Implementation::dequeue(void) | |
| 0 | 588 { |
| 2 | 589 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 0 | 590 |
| 2 | 591 if( queue == NULL ) { |
| 592 CYG_REPORT_RETVAL(NULL); | |
| 593 return NULL; | |
| 594 } | |
| 0 | 595 |
| 596 Cyg_Thread *thread = queue; | |
| 597 | |
| 598 if( thread->next == thread ) | |
| 599 { | |
| 600 // sole thread on list, NULL out ptr | |
| 601 queue = NULL; | |
| 602 } | |
| 603 else | |
| 604 { | |
| 605 // advance to next and remove thread | |
| 606 queue = thread->next; | |
| 607 thread->remove(); | |
| 608 } | |
| 609 | |
| 610 thread->queue = NULL; | |
| 611 | |
| 2 | 612 CYG_REPORT_RETVAL(thread); |
| 0 | 613 return thread; |
| 614 } | |
| 615 | |
| 616 // ------------------------------------------------------------------------- | |
| 617 | |
| 2 | 618 Cyg_Thread * |
| 619 Cyg_ThreadQueue_Implementation::highpri(void) | |
| 0 | 620 { |
| 2 | 621 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 622 CYG_REPORT_RETVAL(queue); | |
| 0 | 623 return queue; |
| 624 } | |
| 625 | |
| 626 // ------------------------------------------------------------------------- | |
| 627 | |
| 2 | 628 void |
| 629 Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread) | |
| 0 | 630 { |
| 631 CYG_REPORT_FUNCTION(); | |
| 2 | 632 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 633 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
634 // If the thread we want is the at the head |
| 0 | 635 // of the list, and is on its own, clear the |
| 636 // list and return. Otherwise advance to the | |
| 637 // next thread and remove ours. If the thread | |
| 638 // is not at the head of the list, just dequeue | |
| 639 // it. | |
| 640 | |
| 641 thread->queue = NULL; | |
| 642 | |
| 643 if( queue == thread ) | |
| 644 { | |
| 645 if( thread->next == thread ) | |
| 646 { | |
| 647 queue = NULL; | |
| 648 return; | |
| 649 } | |
| 650 else queue = thread->next; | |
| 651 } | |
| 652 | |
| 653 thread->Cyg_SchedThread_Implementation::remove(); | |
| 654 | |
| 2 | 655 CYG_REPORT_RETURN(); |
| 0 | 656 } |
| 657 | |
| 658 // ------------------------------------------------------------------------- | |
| 659 // Rotate the front thread on the queue to the back. | |
| 660 | |
| 2 | 661 void |
| 662 Cyg_ThreadQueue_Implementation::rotate(void) | |
| 0 | 663 { |
| 664 CYG_REPORT_FUNCTION(); | |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
665 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
666 CYG_ASSERT(queue != 0, "Rotating an empty queue"); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
124
diff
changeset
|
667 |
| 0 | 668 queue = queue->next; |
| 2 | 669 |
| 670 CYG_REPORT_RETURN(); | |
| 671 } | |
| 672 | |
| 673 // ------------------------------------------------------------------------- | |
| 674 // Rotate or move the thread quoted to the front. | |
| 675 | |
| 676 void | |
| 677 Cyg_ThreadQueue_Implementation::to_head(Cyg_Thread *thread) | |
| 678 { | |
| 679 CYG_REPORT_FUNCTION(); | |
| 680 | |
| 681 queue = thread; | |
| 682 | |
| 683 CYG_REPORT_RETURN(); | |
| 0 | 684 } |
| 685 | |
| 686 // ------------------------------------------------------------------------- | |
| 687 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
688 inline void |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
689 Cyg_ThreadQueue_Implementation::set_thread_queue(Cyg_Thread *thread, |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
690 Cyg_ThreadQueue *tq ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
691 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
692 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
693 thread->queue = tq; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
694 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
695 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
696 // ------------------------------------------------------------------------- |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
697 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
698 void |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
699 Cyg_SchedulerThreadQueue_Implementation::enqueue(Cyg_Thread *thread) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
700 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
701 CYG_REPORT_FUNCTION(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
702 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
703 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
704 if( queue == NULL ) queue = thread; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
705 else queue->prev->insert(thread); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
706 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
707 set_thread_queue( thread, CYG_CLASSFROMBASE(Cyg_ThreadQueue, |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
708 Cyg_SchedulerThreadQueue_Implementation, |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
709 this)); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
710 CYG_REPORT_RETURN(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
711 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
712 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
713 // ------------------------------------------------------------------------- |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
714 |
| 0 | 715 #endif |
| 716 | |
| 717 // ------------------------------------------------------------------------- | |
| 718 // EOF sched/mlqueue.cxx |
