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), 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(); |
93 while ((p = readyListMethods.getNext())) |
94 p->popListNode(); |
95 while ((p = readyListThreads.getNext())) 96 p->popListNode(); |
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{ |
167 // Pull a process from the active list. 168 _current = readyList->getNext(); |
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 |
198 if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 199 readyListMethods.pushLast(p); |
200 else |
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 |
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 |
226Scheduler::suspend(Process *p) 227{ |
228 bool was_ready; |
229 if (initDone) { 230 // After initialization, the only list we can be on is the ready list. |
231 was_ready = (p->nextListNode != nullptr); |
232 p->popListNode(); |
233 } else { |
234 // Check the ready lists to see if we find this process. 235 was_ready = listContains(&readyListMethods, p) || 236 listContains(&readyListThreads, p); |
237 if (was_ready) 238 toFinalize.pushLast(p); |
239 } |
240 return was_ready; |
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{ |
274 bool empty = readyListMethods.empty() && readyListThreads.empty(); |
275 lastReadyTick = getCurTick(); 276 277 // The evaluation phase. 278 do { |
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(); |
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 |
293 if (!empty) { 294 _numCycles++; 295 _changeStamp++; 296 } 297 298 if (_stopNow) 299 return; 300 --- 117 unchanged lines hidden --- |