| 164 | U64 elapsedInstructionsMIPS; |
| 165 | |
| 166 | bool runSlice() { |
| 167 | runTimers(); |
| 168 | |
| 169 | if (scheduledThreads.isEmpty()) |
| 170 | return false; |
| 171 | |
| 172 | XServer* server = XServer::getServer(true); |
| 173 | if (server) { |
| 174 | server->isDisplayDirty = true; // a bit of a hack, sometimes popups in Basstour get missed and don't draw |
| 175 | server->draw(); |
| 176 | } |
| 177 | |
| 178 | U64 elapsedTime = 0; |
| 179 | |
| 180 | contextTimeRemaining = contextTime; |
| 181 | while (!scheduledThreads.isEmpty() && elapsedTime<9000) { |
| 182 | U64 threadStartTime = KSystem::getMicroCounter(); |
| 183 | KListNode<KThread*>* node = scheduledThreads.front(); |
| 184 | KThread* currentThread = (KThread*)node->data; |
| 185 | KNativeSystem::scheduledNewThread(currentThread); |
| 186 | sysCallTime = 0; |
| 187 | |
| 188 | ChangeThread c(currentThread); |
| 189 | static U64 rdtsc; |
| 190 | currentThread->cpu->instructionCount = rdtsc; |
| 191 | runThreadSlice(currentThread); |
| 192 | rdtsc = currentThread->cpu->instructionCount; |
| 193 | |
| 194 | U64 threadEndTime = KSystem::getMicroCounter(); |
| 195 | U64 diff = threadEndTime - threadStartTime; |
| 196 | |
| 197 | elapsedTime+=diff; |
| 198 | |
| 199 | elapsedTimeMIPS+=diff; |
| 200 | elapsedInstructionsMIPS+=currentThread->cpu->blockInstructionCount; |
| 201 | |
| 202 | currentThread->userTime+=diff-sysCallTime; |
| 203 | currentThread->kernelTime+=sysCallTime; |
| 204 | |
| 205 | if (currentThread->cpu->blockInstructionCount) { |
| 206 | contextTimeRemaining = (U32)(contextTime * (10000-elapsedTime) / 10000); |
| 207 | } |
| 208 | // this is how we signal to delete the current thread, since we can't delete it in the syscall, maybe we should use smart_ptr for threads |
| 209 | if (currentThread->terminating) { |
| 210 | delete currentThread; |
| 211 | } else if (!currentThread->waitingCond) { |
| 212 | // make sure we are behind any threads that were recently scheduled |
| 213 | node->remove(); |
| 214 | scheduledThreads.addToBack(node); |
| 215 | } |
| 216 | } |
| 217 | if (!scheduledThreads.isEmpty()) { |
| 218 | if (elapsedTime>11000) { |
| 219 | if (contextTime>100000) |
| 220 | contextTime-=20000; |
| 221 | } else if (elapsedTime<9500) { |
| 222 | contextTime+=20000; |
| 223 | } |