1 //------------------------------------------------------------------------------ 2 // emEngine.cpp 3 // 4 // Copyright (C) 2005-2008 Oliver Hamann. 5 // 6 // Homepage: http://eaglemode.sourceforge.net/ 7 // 8 // This program is free software: you can redistribute it and/or modify it under 9 // the terms of the GNU General Public License version 3 as published by the 10 // Free Software Foundation. 11 // 12 // This program is distributed in the hope that it will be useful, but WITHOUT 13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for 15 // more details. 16 // 17 // You should have received a copy of the GNU General Public License version 3 18 // along with this program. If not, see <http://www.gnu.org/licenses/>. 19 //------------------------------------------------------------------------------ 20 21 #include <emCore/emEngine.h> 22 23 emEngine(emScheduler & scheduler)24emEngine::emEngine(emScheduler & scheduler) 25 : Scheduler(scheduler) 26 { 27 Scheduler.EngineCount++; 28 RNode.Prev=NULL; 29 RNode.Next=NULL; 30 SLFirst=NULL; 31 AwakeState=-1; 32 Priority=DEFAULT_PRIORITY; 33 Clock=Scheduler.Clock; 34 } 35 36 ~emEngine()37emEngine::~emEngine() 38 { 39 while (SLFirst) RemoveLink(SLFirst); 40 if (Scheduler.CurrentEngine==this) Scheduler.CurrentEngine=NULL; 41 if (AwakeState>=0) { 42 RNode.Next->Prev=RNode.Prev; 43 RNode.Prev->Next=RNode.Next; 44 } 45 Scheduler.EngineCount--; 46 } 47 48 AddWakeUpSignal(const emSignal & signal)49void emEngine::AddWakeUpSignal(const emSignal & signal) 50 { 51 emSignal * sig; 52 emSignal::Link * sl, * el; 53 54 sig=(emSignal*)&signal; 55 sl=SLFirst; 56 el=sig->ELFirst; 57 if (sl && el) { 58 do { 59 if (sl->Signal==sig) { 60 sl->RefCount++; 61 return; 62 } 63 sl=sl->SLNext; 64 if (!sl) break; 65 if (el->Engine==this) { 66 el->RefCount++; 67 return; 68 } 69 el=el->ELNext; 70 } while (el); 71 } 72 sl=(emSignal::Link*)malloc(sizeof(emSignal::Link)); 73 sl->Engine=this; 74 sl->ELThisPtr=&sig->ELFirst; 75 sl->ELNext=sig->ELFirst; 76 if (sl->ELNext) sl->ELNext->ELThisPtr=&sl->ELNext; 77 sig->ELFirst=sl; 78 sl->Signal=sig; 79 sl->SLThisPtr=&SLFirst; 80 sl->SLNext=SLFirst; 81 if (sl->SLNext) sl->SLNext->SLThisPtr=&sl->SLNext; 82 SLFirst=sl; 83 sl->RefCount=1; 84 } 85 86 RemoveWakeUpSignal(const emSignal & signal)87void emEngine::RemoveWakeUpSignal(const emSignal & signal) 88 { 89 emSignal * sig; 90 emSignal::Link * sl, * el; 91 92 sig=(emSignal*)&signal; 93 sl=SLFirst; 94 el=sig->ELFirst; 95 if (!sl || !el) return; 96 for (;;) { 97 if (sl->Signal==sig) { 98 break; 99 } 100 sl=sl->SLNext; 101 if (!sl) return; 102 if (el->Engine==this) { 103 sl=el; 104 break; 105 } 106 el=el->ELNext; 107 if (!el) return; 108 } 109 if (--sl->RefCount>0) return; 110 RemoveLink(sl); 111 } 112 113 GetWakeUpSignalRefs(const emSignal & signal) const114int emEngine::GetWakeUpSignalRefs(const emSignal & signal) const 115 { 116 const emSignal::Link * sl, * el; 117 118 sl=SLFirst; 119 el=signal.ELFirst; 120 if (sl && el) { 121 do { 122 if (sl->Signal==&signal) { 123 return sl->RefCount; 124 } 125 sl=sl->SLNext; 126 if (!sl) break; 127 if (el->Engine==this) { 128 return el->RefCount; 129 } 130 el=el->ELNext; 131 } while (el); 132 } 133 return 0; 134 } 135 136 SetEnginePriority(PriorityType priority)137void emEngine::SetEnginePriority(PriorityType priority) 138 { 139 emScheduler::EngineRingNode * l; 140 141 if (Priority==priority) return; 142 Priority=priority; 143 if (AwakeState<0) return; 144 RNode.Prev->Next=RNode.Next; 145 RNode.Next->Prev=RNode.Prev; 146 l=Scheduler.AwakeLists+(Priority*2+AwakeState); 147 if ( 148 Scheduler.CurrentAwakeList<l && 149 AwakeState==Scheduler.TimeSlice 150 ) Scheduler.CurrentAwakeList=l; 151 RNode.Next=l; 152 RNode.Prev=l->Prev; 153 l->Prev->Next=&RNode; 154 l->Prev=&RNode; 155 } 156 157 WakeUpImp()158void emEngine::WakeUpImp() 159 { 160 emScheduler::EngineRingNode * l; 161 162 if (AwakeState>=0) { 163 RNode.Prev->Next=RNode.Next; 164 RNode.Next->Prev=RNode.Prev; 165 } 166 AwakeState=Scheduler.TimeSlice; 167 l=Scheduler.AwakeLists+(Priority*2+AwakeState); 168 if (Scheduler.CurrentAwakeList<l) Scheduler.CurrentAwakeList=l; 169 RNode.Next=l; 170 RNode.Prev=l->Prev; 171 l->Prev->Next=&RNode; 172 l->Prev=&RNode; 173 } 174 175 RemoveLink(emSignal::Link * link)176void emEngine::RemoveLink(emSignal::Link * link) 177 { 178 *link->SLThisPtr=link->SLNext; 179 if (link->SLNext) link->SLNext->SLThisPtr=link->SLThisPtr; 180 *link->ELThisPtr=link->ELNext; 181 if (link->ELNext) link->ELNext->ELThisPtr=link->ELThisPtr; 182 free((void*)link); 183 } 184