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