/*===========================================================================* * do_nice * *===========================================================================*/ PUBLIC int do_nice(message *m_ptr) { /* Change process priority or stop the process. */ int proc_nr, pri, new_q ; register struct proc *rp; /* Extract the message parameters and do sanity checking. */ if(!isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return EINVAL; if (iskerneln(proc_nr)) return(EPERM); pri = m_ptr->PR_PRIORITY; rp = proc_addr(proc_nr); if (is_rtp(rp)) return (EPERM); /* don't allow nice for RT processes */ if (pri == PRIO_STOP) { /* Take process off the scheduling queues. */ lock_dequeue(rp); rp->p_rts_flags |= NO_PRIORITY; return(OK); } else if (pri >= PRIO_MIN && pri <= PRIO_MAX) { /* The value passed in is currently between PRIO_MIN and PRIO_MAX. * We have to scale this between MIN_USER_Q and MAX_USER_Q to match * the kernel's scheduling queues. */ new_q = MAX_USER_Q + (pri-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / (PRIO_MAX-PRIO_MIN+1); if (new_q < MAX_USER_Q) new_q = MAX_USER_Q; /* shouldn't happen */ if (new_q > MIN_USER_Q) new_q = MIN_USER_Q; /* shouldn't happen */ if (new_q == RT_Q && !is_rtp(rp)) return (EINVAL); /* don't allow other processes in the RT queue */ /* Make sure the process is not running while changing its priority. * Put the process back in its new queue if it is runnable. */ lock_dequeue(rp); rp->p_max_priority = rp->p_priority = new_q; if (! rp->p_rts_flags) lock_enqueue(rp); return(OK); } return(EINVAL); }
/*===========================================================================* * do_rt_set_rm * *===========================================================================*/ PRIVATE int do_rt_set_rm(message *m_ptr, struct proc *rp) { struct proc *xp; /* if rm_prio_policy equals PRIO_UNIQUE the priority of a * process scheduled with RM should be unique. We will have to * loop through the process table to check if there is no other process * with this priority. */ if (rm_prio_policy == PRIO_UNIQUE) { for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) { if (xp->p_rts_flags != SLOT_FREE && is_rtp(xp) && xp->p_rt_priority == m_ptr->RM_PRIO) { return (EINVAL); } } } if ( rp->p_rts_flags == 0) { /* Should not happen normally. * A process is runnable if p_rts_flags is zero. * The process requesting to be real-time should be * blocked waiting for a reply from PM * and thus p_rts_flags should not be zero. * Still we remove the process from the scheduling queue. */ lock_dequeue(rp); } /* Now we can change the process structure. * First make sure this process will be recognized * as a real-time process. */ rp->p_rt = 1; /* Set the current and maximum priority to the * real-time queue. */ rp->p_max_priority = rp->p_priority = RT_Q; /* set the static priority */ rp->p_rt_priority = m_ptr->RM_PRIO; if ( rp->p_rts_flags == 0) { /* Should not happen normally. * See above. Add process to the scheduling queue. */ lock_enqueue(rp); } return (OK); }
/*===========================================================================* * do_quantum * *===========================================================================*/ PUBLIC int do_quantum(message *m_ptr) { int proc_nr, quantum; register struct proc *rp; /* Individuo il numero del processo da modificare */ proc_nr = m_ptr->PR_PROC_NR ; /* Il numero del processo non e` valido */ if (! isokprocn(proc_nr)) return(EINVAL); /* Consento di modificare la dimensione del quanto solo nei processi utente */ if (iskerneln(proc_nr)) return(EPERM); /* Nuova dimensione del quanto */ quantum = m_ptr->PR_QUANTUM; /* Controllo che la sua dimensione rispetti i limiti consentiti */ if (quantum < MIN_QUANTUM_SIZE) { kprintf("WARNING: quantum size exceeds MIN_QUANTUM_SIZE, it will be raised to %d ticks\n",MIN_QUANTUM_SIZE); quantum = MIN_QUANTUM_SIZE; } else if (quantum > MAX_QUANTUM_SIZE) { kprintf("WARNING: quantum size exceeds MAX_QUANTUM_SIZE, it will be lowered to %d ticks\n",MAX_QUANTUM_SIZE); quantum = MAX_QUANTUM_SIZE; } /* Seleziono il processo da aggiornare */ rp = proc_addr(proc_nr); /* Lo rimuovo dalla coda */ lock_dequeue(rp); /* Aggiorno la dimensione del quanto */ rp->p_quantum_size = quantum; /* Reinserisco il processo in coda */ if (! rp->p_rts_flags) lock_enqueue(rp); return(OK); }