uint32_t sd_schedule_kernel(uint32_t esp) { process_t *process = _process_currentProcess; thread_t *thread = process->scheduledThread; thread->wasNice = true; thread->usedTicks = thread->wantedTicks; return sd_schedule(esp); }
uint32_t time_tick(uint32_t esp) { // Update the global time time_current ++; process_getCurrentProcess()->usedTime ++; // Call the scheduler esp = sd_schedule(esp); return esp; }
uint32_t sd_schedule(uint32_t esp) { process_t *process = _process_currentProcess; thread_t *thread = process->scheduledThread; if(esp) { // Try to obtain the lock, if we can't, we simply return to the current process // The reason behind this is that its possible that the currently scheduled thread holds the lock in which case we would deadlock ourself bool result = spinlock_tryLock(&_sd_lock); if(!result) return esp; thread->esp = esp; thread->hasBeenRunning = true; } // Check if the process or thread died if(process->died || thread->died) { if(process->died || thread == process->mainThread) { process_t *previous = _sd_processPreviousProcess(process); previous->next = process->next; process->next = _sd_deadProcess; _sd_deadProcess = process; process = previous->next ? previous->next : _process_firstProcess; thread = process->scheduledThread; } else if(thread->died) { thread_t *previous = _sd_threadPreviousThread(thread); previous->next = thread->next; thread->next = _sd_deadThread; _sd_deadThread = thread; thread = previous->next ? previous->next : process->mainThread; process->scheduledThread = thread; } } // Update the thread thread->usedTicks ++; while(thread->usedTicks >= thread->wantedTicks || thread->blocked > 0 || thread->died) { thread->usedTicks = 0; if(thread->sleeping) { timestamp_t timestamp = time_getTimestamp(); if(timestamp >= thread->wakeupCall) { thread->sleeping = false; thread->blocked --; if(thread->blocked == 0 && thread->died != false) break; } } // Update the scheduled thread thread = thread->next ? thread->next : process->mainThread; process->scheduledThread = thread; // Find a new process process = process->next ? process->next : _process_firstProcess; thread = process->scheduledThread; if(process->died) // Remotely killed process { _process_currentProcess = process; return sd_schedule(0x0); } } _process_currentProcess = process; ir_trampoline_map->pagedir = process->pdirectory; ir_trampoline_map->tss.esp0 = thread->esp + sizeof(cpu_state_t); thread->wasNice = false; spinlock_unlock(&_sd_lock); return thread->esp; }