//----------------------------------------------------------------------------------------------------// // @func - sys_pthread_setschedparam //! @desc //! Change the scheduling parameters of the thread identified by 'thread' //! @param //! - thread is the identifier of the target thread //! - policy is the target's new required scheduling policy //! - param is the target's new required scheduling parameters //! @return //! - Return 0 on success //! - Return ESRCH if target thread not found //! - Return EINVAL if scheduling parameters are invalid //! - Return -1 on unhandled errors //! @note //! - policy is ignored //----------------------------------------------------------------------------------------------------// int sys_pthread_setschedparam (pthread_t thread, int policy, struct sched_param *param) { pthread_info_t *thread_info; thread_info = pthread_get_info (thread); if (thread_info == NULL) return ESRCH; if ((param->sched_priority > PRIO_LOWEST) // Check requested priority change || (param->sched_priority < PRIO_HIGHEST)) return EINVAL; if (thread_info->parent->pid == current_pid || thread_info->parent->state == PROC_DELAY) { // Just need to change the priority thread_info->parent->priority = param->sched_priority; } else if (thread_info->parent->state == PROC_READY) { // cannot handle processes which are blocked if (pdelq (&ready_q[thread_info->parent->priority], thread_info->parent->pid) < 0) // Remove from corresponding priority queue return -1; thread_info->parent->priority = param->sched_priority; // Change priority and enqueue in new queue penq (&ready_q[thread_info->parent->priority], thread_info->parent->pid, 0); } else if (thread_info->parent->state == PROC_WAIT || thread_info->parent->state == PROC_TIMED_WAIT) { // Thread currently blocked if (prio_pdelq (thread_info->parent->blockq, // Remove from corresponding wait queue thread_info->parent->pid) < 0) return -1; thread_info->parent->priority = param->sched_priority; // Change priority and enqueue in new queue prio_penq (thread_info->parent->blockq, thread_info->parent->pid, 0); } resched = 1; return 0; }
static void handle_timeout (signed char pid) { if (ptable[pid].blockq) { #if SCHED_TYPE == SCHED_RR pdelq (ptable[pid].blockq, pid); #elif SCHED_TYPE == SCHED_PRIO prio_pdelq (ptable[pid].blockq, pid); #endif ptable[pid].timeout = 1; ptable[pid].blockq = NULL; } ptable[pid].state = PROC_READY; #if SCHED_TYPE == SCHED_RR penq (&ready_q[0], pid, 0); #else /* SCHED_TYPE == SCHED_PRIO */ penq (&ready_q[ptable[pid].priority], pid, 0); #endif resched = 1; }
//----------------------------------------------------------------------------------------------------// // @func - sched_prio //! @desc //! Pre-emptive strict priority scheduler //! @return //! - Nothing //! @note //! - None //----------------------------------------------------------------------------------------------------// void sched_prio () { int i; signed char ready = -1; // Enqueue only currently running processes. Else, // If PROC_DEAD, no need to enqueue // If PROC_WAIT or PROC_TIMED_WAIT, already enqueued in appropriate wait queue // If PROC_DELAY, is in one of the timer queues // If idle_task, then does not need to enter the queue if (current_process->state == PROC_RUN) { ptable[current_pid].state = PROC_READY; if (current_pid != idle_task_pid) penq (&ready_q[ptable[current_pid].priority], current_pid, 0); } SET_CURRENT_PROCESS (-1); for (i=0; i <= PRIO_LOWEST; i++) { while (ready_q[i].item_count != 0) { pdeq (&ready_q[i], &ready, 0); if (ptable[ready].state == PROC_DEAD) { // Flush out dead processes ready = -1; continue; } else break; } if (ready != -1) break; } if (ready == -1) ready = idle_task_pid; #if 0 DBG_PRINT ("XMK: Scheduler: scheduled pid: "); putnum (ready); DBG_PRINT ("\r\n"); #endif ptable[ready].state = PROC_RUN; SET_CURRENT_PROCESS (ready); }