scheduler.cc (13154:f86c71dac456) | scheduler.cc (13176:76f52e8d8c6a) |
---|---|
1/* 2 * Copyright 2018 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright --- 33 unchanged lines hidden (view full) --- 42 eq(nullptr), readyEvent(this, false, ReadyPriority), 43 pauseEvent(this, false, PausePriority), 44 stopEvent(this, false, StopPriority), 45 scMain(nullptr), 46 starvationEvent(this, false, StarvationPriority), 47 _started(false), _paused(false), _stopped(false), _stopNow(false), 48 maxTickEvent(this, false, MaxTickPriority), 49 _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false), | 1/* 2 * Copyright 2018 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright --- 33 unchanged lines hidden (view full) --- 42 eq(nullptr), readyEvent(this, false, ReadyPriority), 43 pauseEvent(this, false, PausePriority), 44 stopEvent(this, false, StopPriority), 45 scMain(nullptr), 46 starvationEvent(this, false, StarvationPriority), 47 _started(false), _paused(false), _stopped(false), _stopNow(false), 48 maxTickEvent(this, false, MaxTickPriority), 49 _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false), |
50 runOnce(false) | 50 runOnce(false), readyList(nullptr) |
51{} 52 53Scheduler::~Scheduler() 54{ 55 // Clear out everything that belongs to us to make sure nobody tries to 56 // clear themselves out after the scheduler goes away. 57 clear(); 58} --- 26 unchanged lines hidden (view full) --- 85 if (maxTickEvent.scheduled()) 86 deschedule(&maxTickEvent); 87 88 Process *p; 89 while ((p = toFinalize.getNext())) 90 p->popListNode(); 91 while ((p = initList.getNext())) 92 p->popListNode(); | 51{} 52 53Scheduler::~Scheduler() 54{ 55 // Clear out everything that belongs to us to make sure nobody tries to 56 // clear themselves out after the scheduler goes away. 57 clear(); 58} --- 26 unchanged lines hidden (view full) --- 85 if (maxTickEvent.scheduled()) 86 deschedule(&maxTickEvent); 87 88 Process *p; 89 while ((p = toFinalize.getNext())) 90 p->popListNode(); 91 while ((p = initList.getNext())) 92 p->popListNode(); |
93 while ((p = readyList.getNext())) | 93 while ((p = readyListMethods.getNext())) |
94 p->popListNode(); | 94 p->popListNode(); |
95 while ((p = readyListThreads.getNext())) 96 p->popListNode(); |
|
95 96 Channel *c; 97 while ((c = updateList.getNext())) 98 c->popListNode(); 99} 100 101void 102Scheduler::initPhase() --- 54 unchanged lines hidden (view full) --- 157 // off the list of processes to be initialized/marked ready. 158 toFinalize.pushLast(p); 159 } 160} 161 162void 163Scheduler::yield() 164{ | 97 98 Channel *c; 99 while ((c = updateList.getNext())) 100 c->popListNode(); 101} 102 103void 104Scheduler::initPhase() --- 54 unchanged lines hidden (view full) --- 159 // off the list of processes to be initialized/marked ready. 160 toFinalize.pushLast(p); 161 } 162} 163 164void 165Scheduler::yield() 166{ |
165 _current = readyList.getNext(); | 167 // Pull a process from the active list. 168 _current = readyList->getNext(); |
166 if (!_current) { 167 // There are no more processes, so return control to evaluate. 168 Fiber::primaryFiber()->run(); 169 } else { 170 _current->popListNode(); 171 // Switch to whatever Fiber is supposed to run this process. All 172 // Fibers which aren't running should be parked at this line. 173 _current->fiber()->run(); --- 13 unchanged lines hidden (view full) --- 187} 188 189void 190Scheduler::ready(Process *p) 191{ 192 if (_stopNow) 193 return; 194 | 169 if (!_current) { 170 // There are no more processes, so return control to evaluate. 171 Fiber::primaryFiber()->run(); 172 } else { 173 _current->popListNode(); 174 // Switch to whatever Fiber is supposed to run this process. All 175 // Fibers which aren't running should be parked at this line. 176 _current->fiber()->run(); --- 13 unchanged lines hidden (view full) --- 190} 191 192void 193Scheduler::ready(Process *p) 194{ 195 if (_stopNow) 196 return; 197 |
195 // Clump methods together to minimize context switching. 196 static bool cluster_methods = false; 197 198 if (cluster_methods && p->procKind() == ::sc_core::SC_METHOD_PROC_) 199 readyList.pushFirst(p); | 198 if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 199 readyListMethods.pushLast(p); |
200 else | 200 else |
201 readyList.pushLast(p); | 201 readyListThreads.pushLast(p); |
202 203 scheduleReadyEvent(); 204} 205 206void 207Scheduler::resume(Process *p) 208{ 209 if (initDone) 210 ready(p); 211 else 212 initList.pushLast(p); 213} 214 215bool | 202 203 scheduleReadyEvent(); 204} 205 206void 207Scheduler::resume(Process *p) 208{ 209 if (initDone) 210 ready(p); 211 else 212 initList.pushLast(p); 213} 214 215bool |
216listContains(ListNode *list, ListNode *target) 217{ 218 ListNode *n = list->nextListNode; 219 while (n != list) 220 if (n == target) 221 return true; 222 return false; 223} 224 225bool |
|
216Scheduler::suspend(Process *p) 217{ | 226Scheduler::suspend(Process *p) 227{ |
228 bool was_ready; |
|
218 if (initDone) { 219 // After initialization, the only list we can be on is the ready list. | 229 if (initDone) { 230 // After initialization, the only list we can be on is the ready list. |
220 bool was_ready = (p->nextListNode != nullptr); | 231 was_ready = (p->nextListNode != nullptr); |
221 p->popListNode(); | 232 p->popListNode(); |
222 return was_ready; | |
223 } else { | 233 } else { |
224 bool was_ready = false; 225 // Check the ready list to see if we find this process. 226 ListNode *n = readyList.nextListNode; 227 while (n != &readyList) { 228 if (n == p) { 229 was_ready = true; 230 break; 231 } 232 } | 234 // Check the ready lists to see if we find this process. 235 was_ready = listContains(&readyListMethods, p) || 236 listContains(&readyListThreads, p); |
233 if (was_ready) 234 toFinalize.pushLast(p); | 237 if (was_ready) 238 toFinalize.pushLast(p); |
235 return was_ready; | |
236 } | 239 } |
240 return was_ready; |
|
237} 238 239void 240Scheduler::requestUpdate(Channel *c) 241{ 242 updateList.pushLast(c); 243 scheduleReadyEvent(); 244} --- 17 unchanged lines hidden (view full) --- 262 if (readyEvent.scheduled()) 263 deschedule(&readyEvent); 264 } 265} 266 267void 268Scheduler::runReady() 269{ | 241} 242 243void 244Scheduler::requestUpdate(Channel *c) 245{ 246 updateList.pushLast(c); 247 scheduleReadyEvent(); 248} --- 17 unchanged lines hidden (view full) --- 266 if (readyEvent.scheduled()) 267 deschedule(&readyEvent); 268 } 269} 270 271void 272Scheduler::runReady() 273{ |
270 bool empty = readyList.empty(); | 274 bool empty = readyListMethods.empty() && readyListThreads.empty(); |
271 lastReadyTick = getCurTick(); 272 273 // The evaluation phase. 274 do { | 275 lastReadyTick = getCurTick(); 276 277 // The evaluation phase. 278 do { |
275 yield(); 276 } while (!readyList.empty()); | 279 // We run methods and threads in two seperate passes to emulate how 280 // Accellera orders things, but without having to scan through a 281 // unified list to find the next process of the correct type. 282 readyList = &readyListMethods; 283 while (!readyListMethods.empty()) 284 yield(); |
277 | 285 |
286 readyList = &readyListThreads; 287 while (!readyListThreads.empty()) 288 yield(); 289 290 // We already know that readyListThreads is empty at this point. 291 } while (!readyListMethods.empty()); 292 |
|
278 if (!empty) { 279 _numCycles++; 280 _changeStamp++; 281 } 282 283 if (_stopNow) 284 return; 285 --- 117 unchanged lines hidden --- | 293 if (!empty) { 294 _numCycles++; 295 _changeStamp++; 296 } 297 298 if (_stopNow) 299 return; 300 --- 117 unchanged lines hidden --- |