Ejemplo n.º 1
0
// do_sleep - set current process state to sleep and add timer with "time"
//          - then call scheduler. if process run again, delete timer first.
//      time is jiffies
int do_sleep(unsigned int time)
{
	assert(!ucore_in_interrupt());
	if (time == 0) {
		return 0;
	}
	bool intr_flag;
	local_intr_save(intr_flag);
	timer_t __timer, *timer = timer_init(&__timer, current, time);
	current->state = PROC_SLEEPING;
	current->wait_state = WT_TIMER;
	add_timer(timer);
	local_intr_restore(intr_flag);

	schedule();

	del_timer(timer);
	return 0;
}
Ejemplo n.º 2
0
void
schedule(void) {
  /* schedule in irq ctx is not allowed */
  assert(!ucore_in_interrupt());
  bool intr_flag;
  struct proc_struct *next;
#ifndef MT_SUPPORT
  list_entry_t head;
  int lapic_id = pls_read(lapic_id);
#endif

  local_intr_save(intr_flag);
  int lcpu_count = pls_read(lcpu_count);
  {
    current->need_resched = 0;
#ifndef MT_SUPPORT
    if (current->mm)
    {
      assert(current->mm->lapic == lapic_id);
      current->mm->lapic = -1;
    }
#endif
    if (current->state == PROC_RUNNABLE && current->pid >= lcpu_count) {
      sched_class_enqueue(current);
    }
#ifndef MT_SUPPORT
    list_init(&head);
    while (1)
    {
      next = sched_class_pick_next();
      if (next != NULL) sched_class_dequeue(next);

      if (next && next->mm && next->mm->lapic != -1)
      {
        list_add(&head, &(next->run_link));
      }
      else
      {
        list_entry_t *cur;
        while ((cur = list_next(&head)) != &head)
        {
          list_del_init(cur);
          sched_class_enqueue(le2proc(cur, run_link));
        }

        break;
      }
    }
#else
    next = sched_class_pick_next();
    if (next != NULL)
      sched_class_dequeue(next);
#endif  /* !MT_SUPPORT */
    if (next == NULL) {
      next = idleproc;
    }
    next->runs ++;
    /* Collect information here*/
    if (sched_collect_info) {
      int lcpu_count = pls_read(lcpu_count);
      int lcpu_idx = pls_read(lcpu_idx);
      int loc = sched_info_head[lcpu_idx];
      int prev = sched_info_pid[loc*lcpu_count + lcpu_idx];
      if (next->pid == prev)
        sched_info_times[loc*lcpu_count + lcpu_idx] ++;
      else {
        sched_info_head[lcpu_idx] ++;
        if (sched_info_head[lcpu_idx] >= PGSIZE / sizeof(uint16_t) / lcpu_count)
          sched_info_head[lcpu_idx] = 0;
        loc = sched_info_head[lcpu_idx];
        uint16_t prev_pid = sched_info_pid[loc*lcpu_count + lcpu_idx];
        uint16_t prev_times = sched_info_times[loc*lcpu_count + lcpu_idx];
        if (prev_times > 0 && prev_pid >= lcpu_count + 2)
          sched_slices[lcpu_idx][prev_pid % SLICEPOOL_SIZE] += prev_times;
        sched_info_pid[loc*lcpu_count + lcpu_idx] = next->pid;
        sched_info_times[loc*lcpu_count + lcpu_idx] = 1;
      }
    }
#ifndef MT_SUPPORT
    assert(!next->mm || next->mm->lapic == -1);
    if (next->mm)
      next->mm->lapic = lapic_id;
#endif
    if (next != current) {
#if 0
      kprintf("N %d to %d\n", current->pid, next->pid);
#endif
      proc_run(next);
    }
  }
  local_intr_restore(intr_flag);
}