Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}