| 492 | } |
| 493 | |
| 494 | void Schedule(void* data, regs64_t* r){ |
| 495 | CPU* cpu = GetCPULocal(); |
| 496 | |
| 497 | if(cpu->currentThread) { |
| 498 | cpu->currentThread->parent->activeTicks++; |
| 499 | if(cpu->currentThread->timeSlice > 0) { |
| 500 | cpu->currentThread->timeSlice--; |
| 501 | return; |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | while(__builtin_expect(acquireTestLock(&cpu->runQueueLock), 0)) { |
| 506 | return; |
| 507 | } |
| 508 | |
| 509 | if (__builtin_expect(cpu->runQueue->get_length() <= 0 || !cpu->runQueue->front, 0)){ |
| 510 | cpu->currentThread = cpu->idleProcess->threads[0]; |
| 511 | } else if(__builtin_expect(cpu->currentThread && cpu->currentThread->parent != cpu->idleProcess, 1)){ |
| 512 | cpu->currentThread->timeSlice = cpu->currentThread->timeSliceDefault; |
| 513 | |
| 514 | asm volatile ("fxsave64 (%0)" :: "r"((uintptr_t)cpu->currentThread->fxState) : "memory"); |
| 515 | |
| 516 | cpu->currentThread->registers = *r; |
| 517 | |
| 518 | cpu->currentThread = cpu->currentThread->next; |
| 519 | } else { |
| 520 | cpu->currentThread = cpu->runQueue->front; |
| 521 | } |
| 522 | |
| 523 | if(cpu->currentThread->state == ThreadStateBlocked){ |
| 524 | thread_t* first = cpu->currentThread; |
| 525 | |
| 526 | do { |
| 527 | cpu->currentThread = cpu->currentThread->next; |
| 528 | } while(cpu->currentThread->state == ThreadStateBlocked && cpu->currentThread != first); |
| 529 | |
| 530 | if(cpu->currentThread->state == ThreadStateBlocked){ |
| 531 | cpu->currentThread = cpu->idleProcess->threads[0]; |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | releaseLock(&cpu->runQueueLock); |
| 536 | asm volatile ("fxrstor64 (%0)" :: "r"((uintptr_t)cpu->currentThread->fxState) : "memory"); |
| 537 | |
| 538 | asm volatile ("wrmsr" :: "a"(cpu->currentThread->fsBase & 0xFFFFFFFF) /*Value low*/, "d"((cpu->currentThread->fsBase >> 32) & 0xFFFFFFFF) /*Value high*/, "c"(0xC0000100) /*Set FS Base*/); |
| 539 | |
| 540 | TSS::SetKernelStack(&cpu->tss, (uintptr_t)cpu->currentThread->kernelStack); |
| 541 | |
| 542 | TaskSwitch(&cpu->currentThread->registers, cpu->currentThread->parent->addressSpace->pml4Phys); |
| 543 | } |
| 544 | |
| 545 | process_t* CreateELFProcess(void* elf, int argc, char** argv, int envc, char** envp) { |
| 546 | if(!VerifyELF(elf)) return nullptr; |
no test coverage detected