Ejemplo n.º 1
0
/*===========================================================================*
 *              do_nice                      *
 *===========================================================================*/
PUBLIC int do_nice(message *m_ptr)
{
    struct schedproc *rmp;
    int rv;
    int proc_nr_n;
    unsigned tickets_to_add;

    /* check who can send you requests */
    if (!accept_message(m_ptr))
        return EPERM;

    if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
        printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
        "%ld\n", m_ptr->SCHEDULING_ENDPOINT);
        return EBADEPT;
    }

    rmp = &schedproc[proc_nr_n];
    tickets_to_add = (unsigned)m_ptr->SCHEDULING_MAXPRIO;

/* CHANGE START */
    change_tickets(rmp, tickets_to_add);
/* CHANGE END */

    return rv;
}
/*===========================================================================*
 *				do_stop_scheduling			     *
 *===========================================================================*/
int do_stop_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int proc_nr_n;
	int rv;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
#ifdef CONFIG_SMP
	cpu_proc[rmp->cpu]--;
#endif
	rmp->flags = 0; /*&= ~IN_USE;*/

	/*
        Lottey Scheduling
        After a process has finished its execution do_lottery is called to start another process
    */
	if ((rv = do_lottery()) != OK) {
		return rv;
	}

	return OK;
}
Ejemplo n.º 3
0
/*==========================================================================================*
 ######  ########  #######  ########           ######   ######  ##     ## ######## ########  
##    ##    ##    ##     ## ##     ##         ##    ## ##    ## ##     ## ##       ##     ## 
##          ##    ##     ## ##     ##         ##       ##       ##     ## ##       ##     ## 
 ######     ##    ##     ## ########           ######  ##       ######### ######   ##     ## 
      ##    ##    ##     ## ##                      ## ##       ##     ## ##       ##     ## 
##    ##    ##    ##     ## ##                ##    ## ##    ## ##     ## ##       ##     ##
 ######     ##     #######  ##        #######  ######   ######  ##     ## ######## ########  
 *==========================================================================================*/
PUBLIC int do_stop_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int err, proc_nr_n;

	do_print("CMPS111", "do_stop_scheduling");

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("do_stop_scheduling: WARNING: got an invalid endpoint in OOQ msg "
				"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
	do_print_process(rmp, "do_stop_scheduling", DEBUG);
	rmp->flags &= ~IN_USE;
	/*if ((err = schedule_process(rmp, "do_stop_scheduling")) != OK) {
		printf("ERROROROAROAROROR\n");
	}*/
	if (rmp->priority == MAX_USER_Q) {
		do_lottery();
	}
	return OK;
}
Ejemplo n.º 4
0
/* msg_client()
 *
 * inputs	- flag 0 if PRIVMSG 1 if NOTICE. RFC
 *		  say NOTICE must not auto reply
 * 		- pointer to source_p source (struct Client *)
 *		- pointer to target_p target (struct Client *)
 *		- pointer to text
 * output	- NONE
 * side effects	- message given channel either chanop or voice
 */
static void
msg_client(int p_or_n, struct Client *source_p, struct Client *target_p,
           const char *text)
{
  if (MyClient(source_p))
  {
    if (target_p->away[0] && p_or_n != NOTICE)
      sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name, target_p->away);

    if (HasUMode(target_p, UMODE_REGONLY) && target_p != source_p)
    {
      if (!HasUMode(source_p, UMODE_REGISTERED | UMODE_OPER))
      {
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, ERR_NONONREG, target_p->name);
        return;
      }
    }
  }

  if (MyClient(target_p) && IsClient(source_p))
  {
    if (HasUMode(target_p, UMODE_CALLERID | UMODE_SOFTCALLERID) &&
        !accept_message(source_p, target_p))
    {
      const int callerid = !!HasUMode(target_p, UMODE_CALLERID);

      /* check for accept, flag recipient incoming message */
      if (p_or_n != NOTICE)
        sendto_one_numeric(source_p, &me, RPL_TARGUMODEG,
                           target_p->name,
                           callerid ? "+g" : "+G",
                           callerid ? "server side ignore" :
                                      "server side ignore with the exception of common channels");

      if ((target_p->connection->last_caller_id_time +
           ConfigGeneral.caller_id_wait) < CurrentTime)
      {
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, RPL_TARGNOTIFY, target_p->name);

        sendto_one_numeric(target_p, &me, RPL_UMODEGMSG,
                           source_p->name, source_p->username, source_p->host,
                           callerid ? "+g" : "+G");
        target_p->connection->last_caller_id_time = CurrentTime;
      }

      /* Only so opers can watch for floods */
      flood_attack_client(NOTICE, source_p, target_p);
      return;
    }

    if (flood_attack_client(p_or_n, source_p, target_p))
      return;
  }

  sendto_anywhere(target_p, source_p, command[p_or_n], ":%s", text);
}
Ejemplo n.º 5
0
/*===========================================================================*
 *				do_nice					     *
 *===========================================================================*/
int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
	unsigned new_q, old_q, old_max_q;
	int old_ticketsNum;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
	new_q = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	if (new_q >= NR_SCHED_QUEUES) {
		return EINVAL;
	}

	/* Store old values, in case we need to roll back the changes */
	old_q     = rmp->priority;
	old_max_q = rmp->max_priority;
	old_ticketsNum = rmp->ticketsNum;

	/* Update the proc entry and reschedule the process */
	/*rmp->max_priority = rmp->priority = new_q;*/
	rmp->priority = USER_Q;
	
	
	/**new_q = MAX_USER_Q + (nice-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / (PRIO_MAX-PRIO_MIN+1);*/
	
	rmp->ticketsNum += ((new_q - MAX_USER_Q)*(PRIO_MAX-PRIO_MIN+1)/(MIN_USER_Q-MAX_USER_Q+1) )+ PRIO_MIN;

	printf(" *** %d ***\n", rmp->ticketsNum);
	if((int)rmp->ticketsNum < 5)
		rmp->ticketsNum = 5;
	if((int)rmp->ticketsNum > 100)
		rmp->ticketsNum = 100;	
	printf("**** %d ****\n", (int) rmp->ticketsNum);
	if ((rv = schedule_process_local(rmp)) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;
		rmp->ticketsNum = old_ticketsNum;
	}
	
	return do_lottery();
	//return rv;
}
Ejemplo n.º 6
0
/*
 Here, we keep track of a backup for processes. 
 
 We won't be needing this for Dynamic Lottery, so we kept it the same
 as in static lottery. 
 */
PUBLIC int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
    /* CHANGE START */
	unsigned old_q, old_max_q, old_tickets;
    /* CHANGE END */
    
	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;
    
	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
               "%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}
    rmp = &schedproc[proc_nr_n];
    
    /* CHANGE START */
    if (((unsigned) m_ptr->SCHEDULING_MAXPRIO + 20) > 100){
        rmp->tickets = 100;
    }else {
        rmp->tickets += (unsigned) m_ptr->SCHEDULING_MAXPRIO;
    } 
    /*if (new_q >= NR_SCHED_QUEUES) {
     return EINVAL;
     }*/
    /* CHANGE END */
    
	/* store old parameters, if there are problems so we can revert*/
	old_q       = rmp->priority;
	old_max_q   = rmp->max_priority;
    /* CHANGE START */
    old_tickets = rmp->tickets;
    /* CHANGE END*/
    rmp->max_priority = rmp->priority;
    
	if ((rv = schedule_process(rmp)) != OK) {
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;
        /* CHANGE START */
        rmp->tickets      = old_tickets;
        /* CHANGE END */
	}
    
	return rv;
}
Ejemplo n.º 7
0
/*===========================================================================*
 *				do_stop_scheduling			     *
 *===========================================================================*/
PUBLIC int do_stop_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int rv, proc_nr_n;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}
	rmp = &schedproc[proc_nr_n];
	rmp->flags = 0; /*&= ~IN_USE;*/
	tic_num -= rmp->tickets;
	return OK;
}
Ejemplo n.º 8
0
/*===========================================================================*
 *				do_nice					     *
 *===========================================================================*/
PUBLIC int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
	unsigned old_q, old_max_q, old_tickets;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];

	if (((unsigned) m_ptr->SCHEDULING_MAXPRIO + 20) > 100){
        rmp->tickets = 100;
    }else {
        rmp->tickets += (unsigned) m_ptr->SCHEDULING_MAXPRIO;
  }

	/* Store old values, in case we need to roll back the changes */
	old_q       = rmp->priority;
	old_max_q   = rmp->max_priority;
	/* Update the proc entry and reschedule the process */
	rmp->max_priority = rmp->priority;
    
    
    
	if ((rv = schedule_process(rmp)) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;
	}

	return rv;
}
Ejemplo n.º 9
0
/*===========================================================================*
 *				do_nice					     *
 *===========================================================================*/
PUBLIC int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
	unsigned new_q, old_q, old_max_q;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
	new_q = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	/*if (new_q >= NR_SCHED_QUEUES) {
		return EINVAL;
	} */

	/* Store old values, in case we need to roll back the changes */
	old_q     = rmp->priority;
	old_max_q = rmp->max_priority;

	/* Update the proc entry and reschedule the process */
	rmp->max_priority = rmp->priority = new_q;

	if ((rv = schedule_process(rmp)) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;
	}

  /*  printf("\tPRIORITY in servers/schedule.c: %d\n", rmp->max_priority); */ 

	return rv;
}
/*===========================================================================*
 *				do_nice					     *
 *===========================================================================*/
int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
	unsigned new_q, old_q, old_max_q;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->m_pm_sched_scheduling_set_nice.endpoint, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OoQ msg "
		"%d\n", m_ptr->m_pm_sched_scheduling_set_nice.endpoint);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
	new_q = m_ptr->m_pm_sched_scheduling_set_nice.maxprio;
	if (new_q >= NR_SCHED_QUEUES) {
		return EINVAL;
	}

	/* Store old values, in case we need to roll back the changes */
	old_q     = rmp->priority;
	old_max_q = rmp->max_priority;

	/* Update the proc entry and reschedule the process */
	rmp->max_priority = rmp->priority = new_q;

	if ((rv = schedule_process_local(rmp)) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;
	}

	return rv;
}
Ejemplo n.º 11
0
/*=========================================================*
########   #######          ##    ## ####  ######  ######## 
##     ## ##     ##         ###   ##  ##  ##    ## ##       
##     ## ##     ##         ####  ##  ##  ##       ##       
##     ## ##     ##         ## ## ##  ##  ##       ######   
##     ## ##     ##         ##  ####  ##  ##       ##       
##     ## ##     ##         ##   ###  ##  ##    ## ##       
########   #######  ####### ##    ## ####  ######  ######## 
 *=========================================================*/
PUBLIC int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int err; int nice;
	int proc_nr_n, proc_nr;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("do_nice: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
	nice = m_ptr->SCHEDULING_MAXPRIO;

	if (nice == 0) {
		DEBUG = !DEBUG;/*for debugging*/
		printf("DEBUG:%d\n", DEBUG);
	} else if (nice == 1) {
		do_print_user_queues("do_nice", DEBUG);
	} else if (nice == 2) {
		do_print_queue_info("do_nice", DEBUG);
	}

	/* Update the proc entry and reschedule the process */
	rmp->num_tix += m_ptr->SCHEDULING_MAXPRIO;
	if ((err = schedule_process(rmp, "do_nice")) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->num_tix -= m_ptr->SCHEDULING_MAXPRIO;
		return err;
	}

	return OK;
}
Ejemplo n.º 12
0
/*===========================================================================*
 *              do_stop_scheduling               *
 *===========================================================================*/
PUBLIC int do_stop_scheduling(message *m_ptr)
{
    register struct schedproc *rmp;
    int rv, proc_nr_n;

    /* check who can send you requests */
    if (!accept_message(m_ptr))
        return EPERM;

    if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
        printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
        "%ld\n", m_ptr->SCHEDULING_ENDPOINT);
        return EBADEPT;
    }

    rmp = &schedproc[proc_nr_n];
/* CHANGE START */
    rmp->flags = 0; /* clear IN_USE and USER_PROCESS flags */
/* CHANGE START */

    return OK;
}
Ejemplo n.º 13
0
/*===========================================================================*
 *				do_stop_scheduling			     *
 *===========================================================================*/
int do_stop_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int proc_nr_n;

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];
#ifdef CONFIG_SMP
	cpu_proc[rmp->cpu]--;
#endif
	rmp->flags = 0; /*&= ~IN_USE;*/

	return OK;
}
Ejemplo n.º 14
0
/*===========================================================================*
 *				do_start_scheduling			     *
 *===========================================================================*/
int do_start_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int rv, proc_nr_n, parent_nr_n;
	
	/* we can handle two kinds of messages here */
	assert(m_ptr->m_type == SCHEDULING_START || 
		m_ptr->m_type == SCHEDULING_INHERIT);

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	/* Resolve endpoint to proc slot. */
	if ((rv = sched_isemtyendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n))
			!= OK) {
		return rv;
	}
	rmp = &schedproc[proc_nr_n];

	/* Populate process slot */
	rmp->endpoint     = m_ptr->SCHEDULING_ENDPOINT;
	rmp->parent       = m_ptr->SCHEDULING_PARENT;
	rmp->max_priority = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	if (rmp->max_priority >= NR_SCHED_QUEUES) {
		return EINVAL;
	}

	/* Inherit current priority and time slice from parent. Since there
	 * is currently only one scheduler scheduling the whole system, this
	 * value is local and we assert that the parent endpoint is valid */
	if (rmp->endpoint == rmp->parent) {
		/* We have a special case here for init, which is the first
		   process scheduled, and the parent of itself. */
		rmp->priority   = USER_Q;
		rmp->time_slice = DEFAULT_USER_TIME_SLICE;

		/*
		 * Since kernel never changes the cpu of a process, all are
		 * started on the BSP and the userspace scheduling hasn't
		 * changed that yet either, we can be sure that BSP is the
		 * processor where the processes run now.
		 */
#ifdef CONFIG_SMP
		rmp->cpu = machine.bsp_id;
		/* FIXME set the cpu mask */
#endif
	}
	
	switch (m_ptr->m_type) {

	case SCHEDULING_START:
		/* We have a special case here for system processes, for which
		 * quanum and priority are set explicitly rather than inherited 
		 * from the parent */
		rmp->priority   = rmp->max_priority;
		rmp->time_slice = (unsigned) m_ptr->SCHEDULING_QUANTUM;
		break;
		
	case SCHEDULING_INHERIT:
		/* Inherit current priority and time slice from parent. Since there
		 * is currently only one scheduler scheduling the whole system, this
		 * value is local and we assert that the parent endpoint is valid */
		if ((rv = sched_isokendpt(m_ptr->SCHEDULING_PARENT,
				&parent_nr_n)) != OK)
			return rv;

		rmp->priority = schedproc[parent_nr_n].priority;
		rmp->time_slice = schedproc[parent_nr_n].time_slice;
		
		// sys_getproctab((struct proc *) &tempProc);
		
		// const char* currentName = tempProc[_ENDPOINT_P(rmp->endpoint) + 5].p_name;
		// unsigned realRuntime = tempProc[_ENDPOINT_P(rmp->endpoint) + 5].p_cycles;

		// int fake_proc_flag = 0;
		// for (int i = 0; i < PROCNUM; i++) {
		// 	if (!strcmp(sjf[i].p_name, currentName)) {
		// 		sjf[i].p_endpoint = rmp->endpoint;
		// 		sjf[i].predBurst = ALPHA * realRuntime + (1 - ALPHA) * sjf[i].predBurst;
		// 		fake_proc_flag = 1;
		// 	}
		// }
		// printf("Before flag \n");
		// if (fake_proc_flag == 1) {
		// 	printf("In flag statement \n");
		// 	int c, d, i;
		// 	struct sjf swap;
		
		// 	for (c = 0; c < (PROCNUM - 1); c++) {
		// 		for (d = 0; d < (PROCNUM - c - 1); d++) {
		// 			if (sjf[d].predBurst > sjf[d+1].predBurst) {
		// 				swap = sjf[d];
		// 				sjf[d] = sjf[d+1];
		// 				sjf[d+1] = swap;
		// 			}
		// 		}
		// 	}
			
		// 	for (i = 0; i < PROCNUM; i++) {
		// 		printf("Process name: %s - Predicted Runtime: %ld", sjf[i].p_name, sjf[i].predBurst);
		// 	}
		
		// 	for (i = PROCNUM - 1; i >= 0; i--) {
		// 		sys_qptab(sjf[i].p_endpoint);
		// 	}
		// } else {
		// 	rmp->priority = schedproc[parent_nr_n].priority;
		// 	rmp->time_slice = schedproc[parent_nr_n].time_slice;
		// }
		// printf("After flag, before break \n");
		break;
		
	default: 
		/* not reachable */
		assert(0);
	}

	/* Take over scheduling the process. The kernel reply message populates
	 * the processes current priority and its time slice */
	if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0, 0)) != OK) {
		printf("Sched: Error taking over scheduling for %d, kernel said %d\n",
			rmp->endpoint, rv);
		return rv;
	}
	rmp->flags = IN_USE;

	/* Schedule the process, giving it some quantum */
	pick_cpu(rmp);
	while ((rv = schedule_process(rmp, SCHEDULE_CHANGE_ALL)) == EBADCPU) {
		/* don't try this CPU ever again */
		cpu_proc[rmp->cpu] = CPU_DEAD;
		pick_cpu(rmp);
	}

	if (rv != OK) {
		printf("Sched: Error while scheduling process, kernel replied %d\n",
			rv);
		return rv;
	}

	/* Mark ourselves as the new scheduler.
	 * By default, processes are scheduled by the parents scheduler. In case
	 * this scheduler would want to delegate scheduling to another
	 * scheduler, it could do so and then write the endpoint of that
	 * scheduler into SCHEDULING_SCHEDULER
	 */

	m_ptr->SCHEDULING_SCHEDULER = SCHED_PROC_NR;

	return OK;
}
Ejemplo n.º 15
0
static int
m_cmessage(int p_or_n, const char *command,
		struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *target_p;
	struct Channel *chptr;
	struct membership *msptr;

	if(!IsFloodDone(source_p))
		flood_endgrace(source_p);

	if((target_p = find_named_person(parv[1])) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOSUCHNICK,
					form_str(ERR_NOSUCHNICK), parv[1]);
		return 0;
	}

	if((chptr = find_channel(parv[2])) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
					form_str(ERR_NOSUCHCHANNEL), parv[2]);
		return 0;
	}

	if((msptr = find_channel_membership(chptr, source_p)) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL),
					chptr->chname);
		return 0;
	}

	if(!is_chanop_voiced(msptr))
	{
		if(p_or_n != NOTICE)
			sendto_one(source_p, form_str(ERR_VOICENEEDED),
				me.name, source_p->name, chptr->chname);
		return 0;
	}

	if(!IsMember(target_p, chptr))
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
					form_str(ERR_USERNOTINCHANNEL),
					target_p->name, chptr->chname);
		return 0;
	}

	if(MyClient(target_p) && (IsSetCallerId(target_p) || (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])) &&
	   !accept_message(source_p, target_p) && !IsOper(source_p))
	{
		if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])
		{
			if (p_or_n != NOTICE)
				sendto_one_numeric(source_p, ERR_NONONREG,
						form_str(ERR_NONONREG),
						target_p->name);
			return 0;
		}
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_TARGUMODEG,
					form_str(ERR_TARGUMODEG), target_p->name);

		if((target_p->localClient->last_caller_id_time +
		    ConfigFileEntry.caller_id_wait) < rb_current_time())
		{
			if(p_or_n != NOTICE)
				sendto_one_numeric(source_p, RPL_TARGNOTIFY,
						form_str(RPL_TARGNOTIFY),
						target_p->name);

			sendto_one(target_p, form_str(RPL_UMODEGMSG),
				me.name, target_p->name, source_p->name,
				source_p->username, source_p->host);

			target_p->localClient->last_caller_id_time = rb_current_time();
		}

		return 0;
	}

	if(p_or_n != NOTICE)
		source_p->localClient->last = rb_current_time();

	sendto_anywhere(target_p, source_p, command, ":%s", parv[3]);
	return 0;
}
Ejemplo n.º 16
0
/*
 * msg_client
 *
 * inputs	- flag 0 if PRIVMSG 1 if NOTICE. RFC 
 *		  say NOTICE must not auto reply
 *		- pointer to command, "PRIVMSG" or "NOTICE"
 * 		- pointer to source_p source (struct Client *)
 *		- pointer to target_p target (struct Client *)
 *		- pointer to text
 * output	- NONE
 * side effects	- message given channel either chanop or voice
 */
static void
msg_client(int p_or_n, char *command,
           struct Client *source_p, struct Client *target_p, char *text)
{
  if (MyClient(source_p))
  {
    /* reset idle time for message only if its not to self 
     * and its not a notice */
    if ((p_or_n != NOTICE) && (source_p != target_p) && source_p->user)
      source_p->user->last = CurrentTime;
      
    if (IsSetSSLaccept(target_p)) {
#ifdef HAVE_LIBCRYPTO
  		int fd = source_p->localClient->fd;
  		fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
  	
  		if (F && !F->ssl) {
#endif
  			sendto_one(source_p, form_str(source_p,ERR_SSLACCEPTONLY),
  				me.name, source_p->name, target_p->name);
  			return;
  			
#ifdef HAVE_LIBCRYPTO
		}
#endif
	}
  }

  if (MyConnect(source_p) && (p_or_n != NOTICE) &&
      target_p->user && target_p->user->away)
    sendto_one(source_p, form_str(source_p,RPL_AWAY), me.name,
               source_p->name, target_p->name, target_p->user->away);

  if (MyClient(target_p))
  {
    if (IsSetRegAccept(target_p) && !(source_p->svsflags & FLAGS_SVS_IDENT))
	{
	  if (p_or_n != NOTICE)
	    sendto_one(source_p, form_str(source_p,ERR_REGACCEPTONLY),
		       me.name, source_p->name, target_p->name);
	    return;
	}

	if (ConfigFileEntry.spam_wait && (p_or_n != NOTICE) &&
	((target_p->localClient->last_join_time + ConfigFileEntry.spam_wait > CurrentTime) ||
	(target_p->localClient->last_leave_time + ConfigFileEntry.spam_wait > CurrentTime)))
	{
		sendto_anywhere(source_p, target_p, 
			"NOTICE %s :*** I'm joining/leaving a chan, please try again in a few seconds.",
			source_p->name);
		return;
	}

    if (!IsServer(source_p) && IsSetCallerId(target_p))
    {
      /* Here is the anti-flood bot/spambot code -db */
      if (accept_message(source_p, target_p) || (source_p == target_p) ||
          find_z_conf((char *)source_p->user->server))
      {
        sendto_one(target_p, ":%s!%s@%s %s %s :%s",
                   source_p->name,
                   source_p->username,
                   source_p->host, 
                   command, target_p->name, translate(target_p, text));
      }
      else
      {
        /* check for accept, flag recipient incoming message */
        if (p_or_n != NOTICE)
          sendto_anywhere(source_p, target_p,
                          "NOTICE %s :*** I'm in +g mode (server side ignore).",
                          source_p->name);

        if ((target_p->localClient->last_caller_id_time +
             ConfigFileEntry.caller_id_wait) < CurrentTime)
        {
          if (p_or_n != NOTICE)
            sendto_anywhere(source_p, target_p,
                            "NOTICE %s :*** I've been informed you messaged me.",
                            source_p->name);

          sendto_one(target_p,
                     ":%s NOTICE %s :*** Client %s [%s@%s] is messaging you and you are +g",
                     me.name, target_p->name,
                     source_p->name, source_p->username, source_p->host);

          target_p->localClient->last_caller_id_time = CurrentTime;

        }
        /* Only so opers can watch for floods */
        (void)flood_attack_client(p_or_n, source_p, target_p);
      }
    }
    else
    {
      /* If the client is remote, we dont perform a special check for
       * flooding.. as we wouldnt block their message anyway.. this means
       * we dont give warnings.. we then check if theyre opered 
       * (to avoid flood warnings), lastly if theyre our client
       * and flooding    -- fl */
      if (!MyClient(source_p) || IsOper(source_p) ||
          (MyClient(source_p) &&
           !flood_attack_client(p_or_n, source_p, target_p)))
        sendto_anywhere(target_p, source_p, "%s %s :%s",
                        command, target_p->name, translate(target_p, text));
    }
  }
  else
    /* The target is a remote user.. same things apply  -- fl */
  if (!MyClient(source_p) || IsOper(source_p) ||
        (MyClient(source_p)
           && !flood_attack_client(p_or_n, source_p, target_p)))
    sendto_anywhere(target_p, source_p, "%s %s :%s", command, target_p->name,
                    text);
  return;
}
Ejemplo n.º 17
0
/*
 * m_accept - ACCEPT command handler
 *      parv[0] = sender prefix
 *      parv[1] = servername
 */
static void m_accept(struct Client *client_p, struct Client *source_p,
                    int parc, char *parv[])
{
  char *nick;
  char *p = NULL;
  static char addbuf[BUFSIZE];
  static char delbuf[BUFSIZE];
  struct Client *target_p;
  int accept_num;
  
  if(*parv[1] == '*')
  {
    list_accepts(source_p);
    return;
  }

  build_nicklist(source_p, addbuf, delbuf, parv[1]);

  /* parse the delete list */
  for(nick = strtoken(&p, delbuf, ","); nick != NULL;
      nick = strtoken(&p, NULL, ","))
  {
    /* shouldnt happen, but lets be paranoid */
    if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p))
    {
      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
                 me.name, source_p->name, nick);
      continue;
    }

    /* user isnt on clients accept list */
    if(!accept_message(target_p, source_p))
    {
      sendto_one(source_p, form_str(ERR_ACCEPTNOT),
                 me.name, source_p->name, target_p->name);
      continue;
    }

    del_from_accept(target_p, source_p);
  }

  /* get the number of accepts they have */ 
  accept_num = dlink_list_length(&source_p->allow_list);
  
  /* parse the add list */
  for(nick = strtoken(&p, addbuf, ","); nick;
      nick = strtoken(&p, NULL, ","), accept_num++)
  {
    /* shouldnt happen, but lets be paranoid */
    if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p)) 
    {
      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
                 me.name, source_p->name, nick);
      continue;
    }

    /* user is already on clients accept list */
    if(accept_message(target_p, source_p))
    {
      sendto_one(source_p, form_str(ERR_ACCEPTEXIST),
                 me.name, source_p->name, target_p->name);
      continue;
    }

    if(accept_num >= ConfigFileEntry.max_accept)
    {
      sendto_one(source_p, form_str(ERR_ACCEPTFULL),
                 me.name, source_p->name);
      return;
    }
      
    /* why is this here? */
    /* del_from accept(target_p, source_p); */
    add_accept(source_p, target_p);

  }


}
Ejemplo n.º 18
0
/*===========================================================================*
 *              do_start_scheduling              *
 *===========================================================================*/
PUBLIC int do_start_scheduling(message *m_ptr)
{
    register struct schedproc *rmp;
    int rv, proc_nr_n, parent_nr_n, nice;
    
    /* we can handle two kinds of messages here */
    assert(m_ptr->m_type == SCHEDULING_START || 
        m_ptr->m_type == SCHEDULING_INHERIT);

    /* check who can send you requests */
    if (!accept_message(m_ptr))
        return EPERM;

    /* Resolve endpoint to proc slot. */
    if ((rv = sched_isemtyendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n))
            != OK) {
        return rv;
    }
    rmp = &schedproc[proc_nr_n];

    /* Populate process slot */
    rmp->endpoint     = m_ptr->SCHEDULING_ENDPOINT;
    rmp->parent       = m_ptr->SCHEDULING_PARENT;
    rmp->max_priority = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
/* CHANGE START */
    rmp->tickets = STARTING_TICKETS;
    rmp->flags = 0; /* clear IN_USE and USER_PROCESS flags */
    rmp->blocking = 0;
/* CHANGE END */

    if (rmp->max_priority >= NR_SCHED_QUEUES)
        return EINVAL;
    
    switch (m_ptr->m_type) {
        case SCHEDULING_START:
            /* We have a special case here for system processes, for which
             * quanum and priority are set explicitly rather than inherited 
             * from the parent */
            rmp->priority   = rmp->max_priority;
            rmp->time_slice = (unsigned) m_ptr->SCHEDULING_QUANTUM;
            break;
        
        case SCHEDULING_INHERIT:
            /* Inherit current priority and time slice from parent. Since there
             * is currently only one scheduler scheduling the whole system, this
             * value is local and we assert that the parent endpoint is valid */
            if ((rv = sched_isokendpt(m_ptr->SCHEDULING_PARENT,
                    &parent_nr_n)) != OK)
                return rv;

/* CHANGE START */
            rmp->priority = HOLDING_Q;
            rmp->flags |= USER_PROCESS;
/* CHANGE END */
            rmp->time_slice = schedproc[parent_nr_n].time_slice;
            break;
        
        default: 
            /* not reachable */
            assert(0);
    }

    /* Take over scheduling the process. The kernel reply message populates
     * the processes current priority and its time slice */
    if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0)) != OK) {
        printf("Sched: Error taking over scheduling for %d, kernel said %d\n",
            rmp->endpoint, rv);
        return rv;
    }
/* CHANGE START */
    rmp->flags |= IN_USE; /* process is valid */
/* CHANGE END */

    /* Schedule the process, giving it some quantum */
    if ((rv = schedule_process(rmp)) != OK) {
        printf("Sched: Error while scheduling process, kernel replied %d\n",
            rv);
        return rv;
    }
    
    /* Mark ourselves as the new scheduler.
     * By default, processes are scheduled by the parents scheduler. In case
     * this scheduler would want to delegate scheduling to another
     * scheduler, it could do so and then write the endpoint of that
     * scheduler into SCHEDULING_SCHEDULER
     */

    m_ptr->SCHEDULING_SCHEDULER = SCHED_PROC_NR;

    return OK;
}
/*===========================================================================*
 *				do_nice					     *
 *===========================================================================*/
int do_nice(message *m_ptr)
{
	struct schedproc *rmp;
	int rv;
	int proc_nr_n;
	unsigned new_q, old_q, old_max_q;

	/*Lottery Scheduling*/
	int old_ticketsNum; //old ticketsNum value

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	if (sched_isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n) != OK) {
		printf("SCHED: WARNING: got an invalid endpoint in OOQ msg "
		"%ld\n", m_ptr->SCHEDULING_ENDPOINT);
		return EBADEPT;
	}

	rmp = &schedproc[proc_nr_n];

    /*
        m_ptr->SCHEDULING_MAX_PRIO is set to the value of nice in servers/pm/schedule.c
    */
	new_q = (unsigned) m_ptr->SCHEDULING_MAXPRIO;

	rmp->ticketsNum += new_q;
	if(rmp->ticketsNum < 5)
		rmp->ticketsNum = 5;

    /*
        new_q is set the same value as the old_priority i.e. 13
    */
	new_q = rmp->priority;

	if (new_q >= NR_SCHED_QUEUES) {
		return EINVAL;
	}

	/* Store old values, in case we need to roll back the changes */
	old_q     = rmp->priority;
	old_max_q = rmp->max_priority;

	/*Lottery Scheduling*/
	old_ticketsNum = rmp->ticketsNum; //saving ticketsNum value to old_ticketsNum

	/* Update the proc entry and reschedule the process */

	/*Lottery Scheduling*/
	//rmp->max_priority = rmp->priority = new_q;
	rmp->priority = USER_Q; // default priority for user processes


	if ((rv = schedule_process_local(rmp)) != OK) {
		/* Something went wrong when rescheduling the process, roll
		 * back the changes to proc struct */
		rmp->priority     = old_q;
		rmp->max_priority = old_max_q;

		/*Lottery Scheduling*/
		rmp->ticketsNum = old_ticketsNum;//reverting ticketsNum value

	}

	/*Lottery Scheduling*/
	return do_lottery();//do_lottery is called to assign cpu to another process
}
Ejemplo n.º 20
0
/* msg_client()
 *
 * inputs	- flag 0 if PRIVMSG 1 if NOTICE. RFC
 *		  say NOTICE must not auto reply
 *		- pointer to command, "PRIVMSG" or "NOTICE"
 * 		- pointer to source_p source (struct Client *)
 *		- pointer to target_p target (struct Client *)
 *		- pointer to text
 * output	- NONE
 * side effects	- message given channel either chanop or voice
 */
static void
msg_client(int p_or_n, const char *command, struct Client *source_p,
           struct Client *target_p, const char *text)
{
  if (MyClient(source_p))
  {
    if (target_p->away[0] && p_or_n != NOTICE)
      sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name, target_p->away);

    if (HasUMode(target_p, UMODE_REGONLY) && target_p != source_p)
    {
      if (!HasUMode(source_p, UMODE_REGISTERED|UMODE_OPER))
      {
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, ERR_NONONREG, target_p->name);
        return;
      }
    }
  }

  if (MyClient(target_p))
  {
    if (!IsServer(source_p) && HasUMode(target_p, UMODE_CALLERID|UMODE_SOFTCALLERID))
    {
      /* Here is the anti-flood bot/spambot code -db */
      if (HasFlag(source_p, FLAGS_SERVICE) || accept_message(source_p, target_p) ||
         (HasUMode(source_p, UMODE_OPER) && ConfigGeneral.opers_bypass_callerid))
      {
        sendto_one(target_p, ":%s!%s@%s %s %s :%s",
                   source_p->name, source_p->username,
                   source_p->host, command, target_p->name, text);
      }
      else
      {
        int callerid = !!HasUMode(target_p, UMODE_CALLERID);

        /* check for accept, flag recipient incoming message */
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, RPL_TARGUMODEG,
                             target_p->name,
                             callerid ? "+g" : "+G",
                             callerid ? "server side ignore" :
                                        "server side ignore with the exception of common channels");

        if ((target_p->connection->last_caller_id_time +
             ConfigGeneral.caller_id_wait) < CurrentTime)
        {
          if (p_or_n != NOTICE)
            sendto_one_numeric(source_p, &me, RPL_TARGNOTIFY, target_p->name);

          sendto_one_numeric(target_p, &me, RPL_UMODEGMSG,
                             get_client_name(source_p, HIDE_IP),
                             callerid ? "+g" : "+G");

          target_p->connection->last_caller_id_time = CurrentTime;

        }

        /* Only so opers can watch for floods */
        flood_attack_client(p_or_n, source_p, target_p);
      }
    }
    else
    {
      /*
       * If the client is remote, we dont perform a special check for
       * flooding.. as we wouldn't block their message anyway.. this means
       * we dont give warnings.. we then check if theyre opered
       * (to avoid flood warnings), lastly if theyre our client
       * and flooding    -- fl
       */
      if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) ||
          !flood_attack_client(p_or_n, source_p, target_p))
        sendto_anywhere(target_p, source_p, command, ":%s", text);
    }
  }
  else if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) ||
           !flood_attack_client(p_or_n, source_p, target_p))
    sendto_anywhere(target_p, source_p, command, ":%s", text);
}
Ejemplo n.º 21
0
/*===================================================================================================*
 ######  ########    ###    ########  ########          ######   ######  ##     ## ######## ######## 
##    ##    ##      ## ##   ##     ##    ##            ##    ## ##    ## ##     ## ##       ##     ##
##          ##     ##   ##  ##     ##    ##            ##       ##       ##     ## ##       ##     ##
 ######     ##    ##     ## ########     ##             ######  ##       ######### ######   ##     ##
      ##    ##    ######### ##   ##      ##                  ## ##       ##     ## ##       ##     ##
##    ##    ##    ##     ## ##    ##     ##            ##    ## ##    ## ##     ## ##       ##     ##
 ######     ##    ##     ## ##     ##    ##    #######  ######   ######  ##     ## ######## ######## 
 *===================================================================================================*/
PUBLIC int do_start_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int err, proc_nr_n, parent_nr_n, nice;
	char *tag;
	
	/* we can handle two kinds of messages here */
	assert(m_ptr->m_type == SCHEDULING_START || 
		m_ptr->m_type == SCHEDULING_INHERIT);

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	/* Resolve endpoint to proc slot. */
	if ((err = sched_isemtyendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n))
			!= OK) {
		return err;
	}
	rmp = &schedproc[proc_nr_n];

	/* Populate process slot */
	rmp->endpoint 			= m_ptr->SCHEDULING_ENDPOINT;
	rmp->parent 			= m_ptr->SCHEDULING_PARENT;
	rmp->max_priority 		= (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	if (rmp->max_priority >= NR_SCHED_QUEUES) {
		return EINVAL;
	}
	
	switch (m_ptr->m_type) {

		case SCHEDULING_START:
			/* We have a special case here for system processes, for which
			 * quantum and priority are set explicitly rather than inherited 
			 * from the parent */
			rmp->priority   = rmp->max_priority;/*TODO? try MAX_USER_Q*/
			rmp->time_slice = (unsigned) m_ptr->SCHEDULING_QUANTUM;
			rmp->num_tix    = (unsigned) 0;
			rmp->IS_SYS     = 1;

			tag = "SCHEDULING_START";
			break;
			
		case SCHEDULING_INHERIT:
			/* Inherit current priority and time slice from parent. Since there
			 * is currently only one scheduler scheduling the whole system, this
			 * value is local and we assert that the parent endpoint is valid */
			if ((err = sched_isokendpt(m_ptr->SCHEDULING_PARENT,
					&parent_nr_n)) != OK)
				return err;

			rmp->priority   = MIN_USER_Q;
			rmp->time_slice = -1;
			rmp->num_tix    = (unsigned) NR_TIX_DEFAULT;
			rmp->IS_SYS     = 0;

			tag = "SCHEDULING_INHERIT";
			break;
			
		default: 
			/* not reachable */
			assert(0);
	}

	do_print_process(rmp, tag, DEBUG);

	/* Take over scheduling the process. The kernel reply message populates
	 * the processes current priority and its time slice */
	if ((err = sys_schedctl(0, rmp->endpoint, 0, 0)) != OK) {
		printf("do_start_scheduling: Error taking over scheduling for %d, kernel said %d\n",
			rmp->endpoint, err);
		return err;
	}
	rmp->flags = IN_USE;

	/* Schedule the process, giving it some quantum */
	if ((err = schedule_process(rmp, tag)) != OK) {
		/*printf("do_start_scheduling: Error while scheduling process, kernel replied %d\n",
			err);*/
		return err;
	}

	/* Mark ourselves as the new scheduler.
	 * By default, processes are scheduled by the parents scheduler. In case
	 * this scheduler would want to delegate scheduling to another
	 * scheduler, it could do so and then write the endpoint of that
	 * scheduler into SCHEDULING_SCHEDULER
	 */
	m_ptr->SCHEDULING_SCHEDULER = SCHED_PROC_NR;

	/*do_lottery if not sys*/
	if (!rmp->IS_SYS) {
		do_lottery();
	}

	return OK;
}
Ejemplo n.º 22
0
/*===========================================================================*
 *				do_start_scheduling			     *
 *===========================================================================*/
int do_start_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int rv, proc_nr_n, parent_nr_n;

	/* we can handle two kinds of messages here */
	assert(m_ptr->m_type == SCHEDULING_START ||
		m_ptr->m_type == SCHEDULING_INHERIT);

	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;

	/* Resolve endpoint to proc slot. */
	if ((rv = sched_isemtyendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n))
			!= OK) {
		return rv;
	}
	rmp = &schedproc[proc_nr_n];

	/* Populate process slot */
	rmp->endpoint     = m_ptr->SCHEDULING_ENDPOINT;
	rmp->parent       = m_ptr->SCHEDULING_PARENT;
	rmp->max_priority = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	rmp->YOLO = sys_times(rmp->endpoint, NULL, rmp->YOLO, NULL, NULL);
	if (rmp->max_priority >= NR_SCHED_QUEUES) {
		return EINVAL;
	}

	/* Inherit current priority and time slice from parent. Since there
	 * is currently only one scheduler scheduling the whole system, this
	 * value is local and we assert that the parent endpoint is valid */
	if (rmp->endpoint == rmp->parent) {
		/* We have a special case here for init, which is the first
		   process scheduled, and the parent of itself. */
		rmp->priority   = USER_Q;
		rmp->time_slice = DEFAULT_USER_TIME_SLICE;

		/*
		 * Since kernel never changes the cpu of a process, all are
		 * started on the BSP and the userspace scheduling hasn't
		 * changed that yet either, we can be sure that BSP is the
		 * processor where the processes run now.
		 */
#ifdef CONFIG_SMP
		rmp->cpu = machine.bsp_id;
		/* FIXME set the cpu mask */
#endif
	}

	switch (m_ptr->m_type) {

	case SCHEDULING_START:
		/* We have a special case here for system processes, for which
		 * quantum and priority are set explicitly rather than inherited
		 * from the parent */
		rmp->priority   = rmp->max_priority;
		rmp->time_slice = (unsigned) m_ptr->SCHEDULING_QUANTUM;
		break;

	case SCHEDULING_INHERIT:
		/* Inherit current priority and time slice from parent. Since there
		 * is currently only one scheduler scheduling the whole system, this
		 * value is local and we assert that the parent endpoint is valid */
		if ((rv = sched_isokendpt(m_ptr->SCHEDULING_PARENT,
				&parent_nr_n)) != OK)
			return rv;

		rmp->priority = schedproc[parent_nr_n].priority;
		rmp->time_slice = schedproc[parent_nr_n].time_slice;
		break;

	default:
		/* not reachable */
		assert(0);
	}

	/* Take over scheduling the process. The kernel reply message populates
	 * the processes current priority and its time slice */
	if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0, 0)) != OK) {
		printf("Sched: Error taking over scheduling for %d, kernel said %d\n",
			rmp->endpoint, rv);
		return rv;
	}
	rmp->flags = IN_USE;

	/* Schedule the process, giving it some quantum */
	pick_cpu(rmp);
	while ((rv = schedule_process(rmp, SCHEDULE_CHANGE_ALL)) == EBADCPU) {
		/* don't try this CPU ever again */
		cpu_proc[rmp->cpu] = CPU_DEAD;
		pick_cpu(rmp);
	}

	if (rv != OK) {
		printf("Sched: Error while scheduling process, kernel replied %d\n",
			rv);
		return rv;
	}

	/* Mark ourselves as the new scheduler.
	 * By default, processes are scheduled by the parents scheduler. In case
	 * this scheduler would want to delegate scheduling to another
	 * scheduler, it could do so and then write the endpoint of that
	 * scheduler into SCHEDULING_SCHEDULER
	 */

	m_ptr->SCHEDULING_SCHEDULER = SCHED_PROC_NR;

	return OK;
}
Ejemplo n.º 23
0
/*
 Called When a new user process wants to be scheduled.
 Here is where we want to initialize our tickets and priorities.
 Default tickets is 20, and we want all user processes to 
 start off inside of the LOSER_Queue. 
 */
PUBLIC int do_start_scheduling(message *m_ptr)
{
	register struct schedproc *rmp;
	int rv, proc_nr_n, parent_nr_n, nice;
	
	/* we can handle two kinds of messages here */
	assert(m_ptr->m_type == SCHEDULING_START || 
           m_ptr->m_type == SCHEDULING_INHERIT);
    
	/* check who can send you requests */
	if (!accept_message(m_ptr))
		return EPERM;
    
	/* Resolve endpoint to proc slot. */
	if ((rv = sched_isemtyendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr_n))
        != OK) {
		return rv;
	}
	rmp = &schedproc[proc_nr_n];
    
	/* Populate process slot */
	rmp->endpoint     = m_ptr->SCHEDULING_ENDPOINT;
	rmp->parent       = m_ptr->SCHEDULING_PARENT;
	rmp->max_priority = (unsigned) m_ptr->SCHEDULING_MAXPRIO;
	if (rmp->max_priority >= NR_SCHED_QUEUES) {
		return EINVAL;
	}
	
	switch (m_ptr->m_type) {
            
        case SCHEDULING_START:
            
            /* CHANGE START */
            rmp->priority   = LOSER_Queue;
            rmp->tickets = 20; /* default tickets */
            /* CHANGE END */
            
            rmp->time_slice = (unsigned) m_ptr->SCHEDULING_QUANTUM;
            break;
            
        case SCHEDULING_INHERIT:
            /* Inherits priority from parent, but we want it to be in
             LOSER_Queue */
            if ((rv = sched_isokendpt(m_ptr->SCHEDULING_PARENT,
                                      &parent_nr_n)) != OK)
                return rv;
            
            /* CHANGED START */
            rmp->priority = LOSER_Queue;
            rmp->tickets = 20; /* default tickets */
            /* CHANGE END */
            
            rmp->time_slice = schedproc[parent_nr_n].time_slice;
            break;
            
        default: 
            /* not reachable */
            assert(0);
	}
    
	/* Take over scheduling the process. The kernel reply message populates
	 * the processes current priority and its time slice */
	if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0)) != OK) {
		printf("Sched: Error taking over scheduling for %d, kernel said %d\n",
               rmp->endpoint, rv);
		return rv;
	}
	rmp->flags = IN_USE;
    
	/* Schedule the process, giving it some quantum */
    /*printf("Scheduling new process in do_start\n");*/
	if ((rv = schedule_process(rmp)) != OK) {
		printf("Sched: Error while scheduling process, kernel replied %d\n",
               rv);
		return rv;
	}
    
	/* Mark ourselves as the new scheduler.
	 * By default, processes are scheduled by the parents scheduler. In case
	 * this scheduler would want to delegate scheduling to another
	 * scheduler, it could do so and then write the endpoint of that
	 * scheduler into SCHEDULING_SCHEDULER
	 */
    
	m_ptr->SCHEDULING_SCHEDULER = SCHED_PROC_NR;
    
	return OK;
}