Beispiel #1
0
void B_proc()
{
    printf("B: 1\n");
    swtch(&B, &A);
    printf("B: 2\n");
    swtch(&B, &A);
}
Beispiel #2
0
void A_proc()
{
    printf("A: 1\n");
    swtch(&A, &B);
    printf("A: 2\n");
    swtch(&A, &B);
    printf("A: 3\n");
    swtch(&A, &M);
}
Beispiel #3
0
void taskA()
{
  int i;
  for(i=1;i<=9;i++)
  {
     printf("A: %d\n",i);
      swtch(&A, &B);
  }
  printf("A: %d\n",i);
  swtch(&A,&M);
}
Beispiel #4
0
static void task2()
{
	while (1) {
		kprint("I AM TASK 2\r");
		swtch(&tsk2->context, tsk1->context);
	}
}
Beispiel #5
0
// Enter scheduler.  Must hold only ptable.lock
// and have changed proc->state.
void sched(void)
{
    int intena;

    //show_callstk ("sched");

    if(!holding(&ptable.lock)) {
        panic("sched ptable.lock");
    }

    if(cpu->ncli != 1) {
        panic("sched locks");
    }

    if(proc->state == RUNNING) {
        panic("sched running");
    }

    if(int_enabled ()) {
        panic("sched interruptible");
    }

    intena = cpu->intena;
    swtch(&proc->context, cpu->scheduler);
    cpu->intena = intena;
}
Beispiel #6
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;

  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;

      // Switch to chosen process.  It is the process's job
      // to release ptable.lock and then reacquire it
      // before jumping back to us.
      proc = p;
      switchuvm(p);
      p->state = RUNNING;
      swtch(&cpu->scheduler, proc->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      proc = 0;
    }
    release(&ptable.lock);

  }
}
Beispiel #7
0
void scheduler(){


	struct proc *p;
	
	while(1){
		/* set interrupts ??? */
		for(p=ptable.proc;p<&ptable.proc[NPROC];p++){
			if(p->state!=RUNNABLE){
				continue;
			}
			/* switch to this process. */
			proc=p;
			switchuvm(p);
			p->state=RUNNING;
			swtch(&cpu.scheduler,p->context);
			/* __asm__ volatile( */
			/* 		"movq %0,%%rsp;" */
			/* 		: */
			/* 		:"r"((char *)(proc->tf) - 8) */
			/* 		: */
			/* 				 ); */

			/* __asm__ volatile("retq;"); */
			
		}
	}

}
Beispiel #8
0
/*
 * Mark the current thread as sleeping on a shuttle object, and
 * switch to a new thread.
 * No locks other than 'l' should be held at this point.
 */
void
shuttle_swtch(kmutex_t *l)
{
	klwp_t	*lwp = ttolwp(curthread);

	thread_lock(curthread);
	disp_lock_enter_high(&shuttle_lock);
	lwp->lwp_asleep = 1;			/* /proc */
	lwp->lwp_sysabort = 0;			/* /proc */
	lwp->lwp_ru.nvcsw++;
	curthread->t_flag |= T_WAKEABLE;
	curthread->t_sobj_ops = &shuttle_sobj_ops;
	curthread->t_wchan0 = (caddr_t)1;
	CL_INACTIVE(curthread);
	DTRACE_SCHED(sleep);
	THREAD_SLEEP(curthread, &shuttle_lock);
	(void) new_mstate(curthread, LMS_SLEEP);
	disp_lock_exit_high(&shuttle_lock);
	mutex_exit(l);
	if (ISSIG(curthread, JUSTLOOKING) || MUSTRETURN(curproc, curthread))
		setrun(curthread);
	swtch();
	/*
	 * Caller must check for ISSIG/lwp_sysabort conditions
	 * and clear lwp->lwp_asleep/lwp->lwp_sysabort
	 */
}
Beispiel #9
0
void testLock(void)
{
        gslLockMode_t mode1 = PERPROC(curProc)->testMode1;
        bool mode1DontWait  = PERPROC(curProc)->testMode1DontWait;
        gslLockMode_t mode2 = PERPROC(curProc)->testMode2;
        bool mode2DontWait  = PERPROC(curProc)->testMode2DontWait;
        bool got1 = false, got2 = false;

        got1 = gslAcquire(&theLock, mode1, mode1DontWait, NULL);
        if (got1)
                holderCounts = lcAdd(holderCounts, lcActive(mode1));
        swtch();
        if (mode2 != -1) {
                got2 = gslAcquire(&theLock, mode2, mode2DontWait, NULL);
                if (got2)
                        holderCounts = lcAdd(holderCounts, lcActive(mode2));
                swtch();
        }

        // Check for conflicting held locks
        lockCounts_t otherCounts = lcSubtract(holderCounts, PERPROC(curProc)->perLock.holding);
        for (int i = 0; i < LC_MAX_MODES; ++i) {
                if (lcGetActive(otherCounts, i)) {
                        if ((got1 && CONFLICTS(i, mode1)) || (got2 && CONFLICTS(i, mode2))) {
                                fail("Conflicting lock held");
                        } else if ((got1 && i == mode1) || (got2 && i == mode2)) {
                                observedSharing[i] = true;
                        }
                }
        }

        // I release mode1 first so that my tests for observed sharing
        // remain simple.  Otherwise, if mode1 overshadows mode2, then
        // it could prevent sharing of mode2, even if mode2 would
        // otherwise be sharable.  (This isn't entirely reliable, but
        // takes care of most cases)
        if (got1) {
                holderCounts = lcSubtract(holderCounts, lcActive(mode1));
                // XXX Check lastlocalhold and lasthold
                gslRelease(&theLock, mode1, NULL, NULL);
        }
        if (got2) {
                holderCounts = lcSubtract(holderCounts, lcActive(mode2));
                gslRelease(&theLock, mode2, NULL, NULL);
        }
}
Beispiel #10
0
void taskB()
{
   int i;
  for(i=1;i<=9;i++)
  {
     printf("B: %d\n",i);
     swtch(&B, &M);
  }
}
Beispiel #11
0
/*
 * Like cv_wait_sig_swap but allows the caller to indicate (with a
 * non-NULL sigret) that they will take care of signalling the cv
 * after wakeup, if necessary.  This is a vile hack that should only
 * be used when no other option is available; almost all callers
 * should just use cv_wait_sig_swap (which takes care of the cv_signal
 * stuff automatically) instead.
 */
int
cv_wait_sig_swap_core(kcondvar_t *cvp, kmutex_t *mp, int *sigret)
{
	kthread_t *t = curthread;
	proc_t *p = ttoproc(t);
	klwp_t *lwp = ttolwp(t);
	int rval = 1;
	int signalled = 0;

	if (panicstr)
		return (rval);

	/*
	 * The check for t_intr is to catch an interrupt thread
	 * that has not yet unpinned the thread underneath.
	 */
	if (lwp == NULL || t->t_intr) {
		cv_wait(cvp, mp);
		return (rval);
	}

	lwp->lwp_asleep = 1;
	lwp->lwp_sysabort = 0;
	thread_lock(t);
	t->t_kpri_req = 0;	/* don't need kernel priority */
	cv_block_sig(t, (condvar_impl_t *)cvp);
	/* I can be swapped now */
	curthread->t_schedflag &= ~TS_DONT_SWAP;
	thread_unlock_nopreempt(t);
	mutex_exit(mp);
	if (ISSIG(t, JUSTLOOKING) || MUSTRETURN(p, t))
		setrun(t);
	/* ASSERT(no locks are held) */
	swtch();
	signalled = (t->t_schedflag & TS_SIGNALLED);
	t->t_flag &= ~T_WAKEABLE;
	/* TS_DONT_SWAP set by disp() */
	ASSERT(curthread->t_schedflag & TS_DONT_SWAP);
	mutex_enter(mp);
	if (ISSIG_PENDING(t, lwp, p)) {
		mutex_exit(mp);
		if (issig(FORREAL))
			rval = 0;
		mutex_enter(mp);
	}
	if (lwp->lwp_sysabort || MUSTRETURN(p, t))
		rval = 0;
	lwp->lwp_asleep = 0;
	lwp->lwp_sysabort = 0;
	if (rval == 0) {
		if (sigret != NULL)
			*sigret = signalled;	/* just tell the caller */
		else if (signalled)
			cv_signal(cvp);	/* avoid consuming the cv_signal() */
	}
	return (rval);
}
Beispiel #12
0
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;
  initlock(&tlock, "time");


  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;

      if(count_high_pri() != 0 && p->priority == 1)
		continue;

      // Switch to chosen process.  It is the process's job
      // to release ptable.lock and then reacquire it
      // before jumping back to us.
      proc = p;
      switchuvm(p);
      p->state = RUNNING;
	  //swtch(&cpu->scheduler, proc->context);
	  //switchkvm();
	  uint ticks0 = 0, ticks1 = 0;
	  
	  acquire(&tlock);//Acquire the timer lock
      ticks0 = ticks;//Start timer
	  release(&tlock);

	  swtch(&cpu->scheduler, proc->context);

      acquire(&tlock);//Acquire the timer lock
      ticks1 = ticks;//Stop timer and add the ticks to htick or ltick depending upon the priority of the process.
      release(&tlock);

	  if (p->priority == 1) {
		p->ltick = p->ltick + (ticks1 - ticks0);
      } else {
		p->htick = p->htick + (ticks1 - ticks0);
	  }
	  
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      proc = 0;
    }
    release(&ptable.lock);

  }
}
Beispiel #13
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;
  int makeShiftTimer = 0;

  for(;;){
    // Enable interrupts on this processor.
    sti();
        makeShiftTimer++;

	if (makeShiftTimer >= 10000){
		for (p = ptable.proc; p < &ptable.proc[NPROC]; p++){
			if (p->pri != 1){
				continue;
			}	
			p->pri = 0;
			//cprintf("Bumping up: %s", p->name);
		}
		makeShiftTimer = 0;
	} 

	int zeroCount = 0;
	for (p = ptable.proc; p < &ptable.proc[NPROC]; p++){
		zeroCount++;
	}
	
//	cprintf("Number of process on queue 0: %d\n", zeroCount);
	//don't uncomment this if you want to be able to use the terminal. At all.

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if((p->state != RUNNABLE) || (zeroCount != 0 && p->pri == 1))
	//im pretty sure the case for there being nothing on the 0 queue and stuff on the 1 queue is implicit here
	//we'll wait and see I guess
        continue;

      // Switch to chosen process.  It is the process's job
      // to release ptable.lock and then reacquire it
      // before jumping back to us.
      proc = p;
      switchuvm(p);
      p->state = RUNNING;
      swtch(&cpu->scheduler, proc->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      proc = 0;
    }
    release(&ptable.lock);

  }
}
Beispiel #14
0
/*
 * Give up the processor till a wakeup occurs
 * on chan, at which time the process
 * enters the scheduling queue at priority pri.
 * The most important effect of pri is that when
 * pri<0 a signal cannot disturb the sleep;
 * if pri>=0 signals will be processed.
 * Callers of this routine must be prepared for
 * premature return, and check that the reason for
 * sleeping has gone away.
 */
sleep(chan, pri)
{
    register *rp, s;

    s = PS->integ;
    rp = u.u_procp;
    if(pri >= 0) {
        if(issig())
            goto psig;
        spl6();
        rp->p_wchan = chan;
        rp->p_stat = SWAIT;
        rp->p_pri = pri;
        spl0();
        if(runin != 0) {
            runin = 0;
            wakeup(&runin);
        }
        swtch();
        if(issig())
            goto psig;
    } else {
        spl6();
        rp->p_wchan = chan;
        rp->p_stat = SSLEEP;
        rp->p_pri = pri;
        spl0();
        swtch();
    }
    PS->integ = s;
    return;

    /*
     * If priority was low (>=0) and
     * there has been a signal,
     * execute non-local goto to
     * the qsav location.
     * (see trap1/trap.c)
     */
psig:
    aretu(u.u_qsav);
}
Beispiel #15
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;
  int i;
#if 0
  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
    if(p->state != UNUSED)
      cprintf("proc %d has priority  %d\n", p->pid, p->priority);
  }
#endif

  for(;;){
    // Enable interrupts on this processor.
    sti();

    acquire(&ptable.lock);
    // Loop through priority queues looking for runnable processe
    for(i = 0; i < 32; i++) {
      if(priority_q[i] != NULL) {
        p = priority_q[i];

#if 0
      }
    }
    // Loop over process table looking for process to run.
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
#endif
        if(p->state != RUNNABLE)
          panic("Not runnable in ready queue");

        // Switch to chosen process.  It is the process's job
        // to release ptable.lock and then reacquire it
        // before jumping back to us.
        proc = p;
        switchuvm(p);
        p->state = RUNNING;

        //**** remove
        //cprintf("remove in scheduler\n");
        removefromq(p);
        //****

        swtch(&cpu->scheduler, proc->context);
        switchkvm();

        // Process is done running for now.
        // It should have changed its p->state before coming back.
        proc = 0;
      }
    }
  release(&ptable.lock);

  }
Beispiel #16
0
int main()
{
  int stackA[1024];
  int stackB[1024];
  A.eip = (int)taskA;
  B.eip = (int)taskB;
  A.esp = (int)(&stackA[1023]);
  B.esp = (int)(&stackB[1023]);
  
  
   int i;
  for(i=1;i<=8;i++)
  {
     swtch(&M, &A);
     printf("C: %d\n\n",i);
  }
  swtch(&M, &A);
  swtch(&M, &A);
  return 0;
}
Beispiel #17
0
int main()
{
  int Astack[1024];
  int Bstack[1024];
  A.eip = (int)A_proc;
  A.esp = (int)(&Astack[1023]);
  B.eip = (int)B_proc;
  B.esp = (int)(&Bstack[1023]);
  swtch(&M, &A);
  return 0;
}
Beispiel #18
0
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;
  struct cpu *c;
  int i;
  trace_frame *curr_trace_frm, *last_trace_frm;

  c = &cpus[cpu()];
  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&proc_table_lock);
    for(i = 0; i < NPROC; i++){
      p = &proc[i];
      if(p->state != RUNNABLE)
        continue;

      // Switch to chosen process.  It is the process's job
      // to release proc_table_lock and then reacquire it
      // before jumping back to us.

      //cprintf("current: %d\n", p->pid);
      c->curproc = p;
      setupsegs(p);
      p->state = RUNNING;
      swtch(&c->context, &p->context);

      if (trace_status == TRACE_ON) {
        last_trace_frm = &trace[(trace_index - 1) % TRACE_SIZE];
        if (last_trace_frm->pid != p->pid) {
          curr_trace_frm = &trace[trace_index % TRACE_SIZE];
          curr_trace_frm->pid = p->pid;
          curr_trace_frm->quantums = 1;
          trace_index++;
        }
        else if (last_trace_frm->pid == p->pid) {
          curr_trace_frm = &trace[(trace_index - 1) % TRACE_SIZE];
          curr_trace_frm->quantums++;
        }
      }

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      c->curproc = 0;
      setupsegs(0);
    }
    release(&proc_table_lock);

  }
}
Beispiel #19
0
void SwitchToProccess(struct proc* process)
{
	proc = process;
	switchuvm(process);
	process->state = RUNNING;
	swtch(&cpu->scheduler, proc->context);
	switchkvm();

	// Process is done running for now.
	// It should have changed its p->state before coming back.
	proc = 0;
}
Beispiel #20
0
static void
apix_do_softint_epilog(struct cpu *cpu, uint_t oldpil)
{
	struct machcpu *mcpu = &cpu->cpu_m;
	kthread_t *t, *it;
	uint_t pil, basespl;
	hrtime_t intrtime;
	hrtime_t now = tsc_read();

	it = cpu->cpu_thread;
	pil = it->t_pil;

	cpu->cpu_stats.sys.intr[pil - 1]++;

	ASSERT(cpu->cpu_intr_actv & (1 << pil));
	cpu->cpu_intr_actv &= ~(1 << pil);

	intrtime = now - it->t_intr_start;
	mcpu->intrstat[pil][0] += intrtime;
	cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;

	/*
	 * If there is still an interrupted thread underneath this one
	 * then the interrupt was never blocked and the return is
	 * fairly simple.  Otherwise it isn't.
	 */
	if ((t = it->t_intr) == NULL) {
		/*
		 * Put thread back on the interrupt thread list.
		 * This was an interrupt thread, so set CPU's base SPL.
		 */
		set_base_spl();
		/* mcpu->mcpu_pri = cpu->cpu_base_spl; */

		it->t_state = TS_FREE;
		it->t_link = cpu->cpu_intr_thread;
		cpu->cpu_intr_thread = it;
		(void) splhigh();
		sti();
		swtch();
		/*NOTREACHED*/
		panic("dosoftint_epilog: swtch returned");
	}
	it->t_link = cpu->cpu_intr_thread;
	cpu->cpu_intr_thread = it;
	it->t_state = TS_FREE;
	cpu->cpu_thread = t;
	if (t->t_flag & T_INTR_THREAD)
		t->t_intr_start = now;
	basespl = cpu->cpu_base_spl;
	pil = MAX(oldpil, basespl);
	mcpu->mcpu_pri = pil;
}
Beispiel #21
0
/*
 * Block on the indicated condition variable and release the
 * associated kmutex while blocked.
 */
void
cv_wait(kcondvar_t *cvp, kmutex_t *mp)
{
	if (panicstr)
		return;

	ASSERT(curthread->t_schedflag & TS_DONT_SWAP);
	thread_lock(curthread);			/* lock the thread */
	cv_block((condvar_impl_t *)cvp);
	thread_unlock_nopreempt(curthread);	/* unlock the waiters field */
	mutex_exit(mp);
	swtch();
	mutex_enter(mp);
}
void
scheduler(void)
{
  struct proc *p;
  ptable.timeToReset = MAX_TIME_TO_RESET;

  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Check for procs in ready list
    int pri = 0;
    for (;;) {
      acquire(&ptable.lock);

      if(ptable.pPriQ[pri] != 0) { 
        // Switch to chosen process.  It is the process's job
        // to release ptable.lock and then reacquire it
        // before jumping back to us.
        p = ptable.pPriQ[pri];
	if (p->state != RUNNABLE)
	  panic("scheduled unready process");
        proc = p;
        switchuvm(p);
        p->state = RUNNING;
        ptable.pPriQ[pri] = ptable.pPriQ[pri]->next;
	p->next = 0;
	ptable.timeToReset--;
        if (ptable.timeToReset == 0)
          resetPri();   // Run priority-reset function
        swtch(&cpu->scheduler, proc->context);
        switchkvm();

        // Process is done running for now.
        // It should have changed its p->state before coming back.
        proc = 0;
        release(&ptable.lock);
	pri = 0;
        break;
      }
      else {
        release(&ptable.lock);
        if (pri == N_PRI-1)
          pri = 0;
        else
	  pri++;
      }
    }
  }
}
Beispiel #23
0
// Enter scheduler.  Must already hold proc_table_lock
// and have changed curproc[cpu()]->state.
void
sched(void)
{
  if(read_eflags()&FL_IF)
    panic("sched interruptible");
  if(cp->state == RUNNING)
    panic("sched running");
  if(!holding(&proc_table_lock))
    panic("sched proc_table_lock");
  if(cpus[cpu()].ncli != 1)
    panic("sched locks");

  swtch(&cp->context, &cpus[cpu()].context);
}
Beispiel #24
0
void first()
{
  bwprintf (COM2, "I AM FIRST USER.\n\tMODE IS ");
  print_mode ();
  bwputstr (COM2, ".\n\tCREATE???\n");
  //int z = Create (0xABCDEF01, (void*)0x10FEDCBA);
  int z = Create (3, second);
  int i=0,j=0,k=0;
  while (1) {
    bwprintf (COM2, "I AM FIRST USER.\n\tKERNEL SAID %d\n\tMODE IS ",z);
    print_mode ();
    bwputstr (COM2, ".\n\tPASS??\n");
    i++;
    if (i>10) j++;
    if (j>10) k++;
    i %= 11; j %= 11;
//    bwprintf (COM2, "(i,j,k) = (%d,%d,%d)\n",i,j,k);
    Pass();
    bwprintf (COM2, "I AM FIRST USER.\n\tMODE IS ");
    print_mode ();
    bwputstr (COM2, ".\n\tEXIT????\n");
    Exit();
  }

//  int i = 0xFFFFF;
  int r;
  while (i--) {
    bwprintf(COM2, "Hey, I'm a user(%d)!\n", i);
    r = swtch(i);
    bwprintf(COM2, "And the kernel gave me %d!\n", r);
    for (r = 0; r < 500000; ++r);
  }
  bwputstr (COM2, "CPU Mode: ");
  print_mode();
  bwputstr (COM2, "\n\n");
  int x = 42;
  int b[5];
  b[0] = 0xDEADBEEF;
  b[1] = 0xDEADBEEF;
  b[2] = 0xDEADBEEF;
  b[3] = 0xDEADBEEF;
  b[4] = 0xDEADBEEF;
  bwprintf (COM2, "x is %d\n", x);
  i = 5; while (i--) { bwprintf (COM2, "b[%d] = ", i); bwputr(COM2, b[i]); bwputstr (COM2, "\n");}
  b[2] -= x;
  b[3]--;
  bwputstr (COM2, "now b[2] = b[2] - x  and b[3] = b[3] - 1...\n");
  i = 5; while (i--) { bwprintf (COM2, "b[%d] = ", i); bwputr(COM2, b[i]); bwputstr (COM2, "\n");}
}
Beispiel #25
0
int
cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
{
	kthread_t *t = curthread;
	proc_t *p = ttoproc(t);
	klwp_t *lwp = ttolwp(t);
	int rval = 1;
	int signalled = 0;

	if (panicstr)
		return (rval);

	/*
	 * The check for t_intr is to catch an interrupt thread
	 * that has not yet unpinned the thread underneath.
	 */
	if (lwp == NULL || t->t_intr) {
		cv_wait(cvp, mp);
		return (rval);
	}

	ASSERT(curthread->t_schedflag & TS_DONT_SWAP);
	lwp->lwp_asleep = 1;
	lwp->lwp_sysabort = 0;
	thread_lock(t);
	cv_block_sig(t, (condvar_impl_t *)cvp);
	thread_unlock_nopreempt(t);
	mutex_exit(mp);
	if (ISSIG(t, JUSTLOOKING) || MUSTRETURN(p, t))
		setrun(t);
	/* ASSERT(no locks are held) */
	swtch();
	signalled = (t->t_schedflag & TS_SIGNALLED);
	t->t_flag &= ~T_WAKEABLE;
	mutex_enter(mp);
	if (ISSIG_PENDING(t, lwp, p)) {
		mutex_exit(mp);
		if (issig(FORREAL))
			rval = 0;
		mutex_enter(mp);
	}
	if (lwp->lwp_sysabort || MUSTRETURN(p, t))
		rval = 0;
	lwp->lwp_asleep = 0;
	lwp->lwp_sysabort = 0;
	if (rval == 0 && signalled)	/* avoid consuming the cv_signal() */
		cv_signal(cvp);
	return (rval);
}
Beispiel #26
0
// Enter scheduler.  Must hold only ptable.lock
// and have changed proc->state.
void sched(void) {
	int intena;

	if (!holding(&ptable.lock))
		panic("sched ptable.lock");
	if (cpu->ncli != 1)
		panic("sched locks");
	if (proc->state == RUNNING)
		panic("sched running");
	if (readeflags() & FL_IF)
		panic("sched interruptible");
	intena = cpu->intena;
	swtch(&proc->context, cpu->scheduler);
	cpu->intena = intena;
}
Beispiel #27
0
Datei: proc.c Projekt: Alesom/xv6
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void scheduler(void) {
	struct proc *p, *q;
	unsigned long long min  ;
	
	for(;;){
		// Enable interrupts on this processor.
		sti();
		
		// Loop over process table looking for process to run.
		acquire(&ptable.lock);
		p = 0;
		min = INFINITO ;
		for(q = ptable.proc; q < &ptable.proc[NPROC]; q++){
			if (q->state == RUNNABLE){
				if (min > q->curr_pass){ 
					p = q;
					min = q->curr_pass;
				}
			}
		}
		if (p!=0){
			/*Testes
			if (p->pid > 3){
				for(q = ptable.proc; q < &ptable.proc[NPROC]; q++){
					cprintf("%d %d %d\n", q->pid, q->Ntickts, q->slices);
				}
				cprintf("\n\n\n\n");
			}
			End */
			
			p->slices++; 
			proc = p;
			switchuvm(p);
			p->state = RUNNING;
			
			swtch(&cpu->scheduler, proc->context);
			switchkvm();

			// Process is done running for now.
			p->curr_pass+=p->pass;
			
			// It should have changed its p->state before coming back.
			proc = 0;
		}
		
		release(&ptable.lock);
	}
}
Beispiel #28
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
    struct proc *p;

    for(;;) {
        // Enable interrupts on this processor.
        sti();

        // Loop over process table looking for process to run.
        acquire(&ptable.lock);
        uint min_order = 1<<30;
        uint idx = -1;
        for (p = ptable.proc; p < &ptable.proc[NPROC]; p++)
            if (p->state == RUNNABLE && p->order < min_order) {
                min_order = p->order;
                idx = p - ptable.proc;
            }
        if (idx == -1)
        {
            release(&ptable.lock);
            continue;
        }
        //for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
        //  if(p->state != RUNNABLE)
        //    continue;

        // Switch to chosen process.  It is the process's job
        // to release ptable.lock and then reacquire it
        // before jumping back to us.
        p = ptable.proc + idx;
        proc = p;
        switchuvm(p);
        p->state = RUNNING;
        swtch(&cpu->scheduler, proc->context);
        switchkvm();

        // Process is done running for now.
        // It should have changed its p->state before coming back.
        proc = 0;
        //break;
        //}
        release(&ptable.lock);

    }
}
Beispiel #29
0
void
scheduler(void)
{
  struct proc *p;

  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;

      // Switch to chosen process.  It is the process's job
      // to release ptable.lock and then reacquire it
      // before jumping back to us.
      if (p->allowed_cpu > -1 && p->allowed_cpu == cpu->id) {
        //cprintf("\n Processing prod %d, at cpu %d", p->pid, cpu->id);
      } else if (p->allowed_cpu > -1) {
        //cprintf("\nSkipping proc %d at cpu %d, proc->allowed_cpu %d", p->pid, cpu->id, p->allowed_cpu);
          continue;
      }

rerun:
      proc = p;
      switchuvm(p);
      p->state = RUNNING;
      swtch(&cpu->scheduler, proc->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      if (cpu->preempt_disable_count > 0) {
          // Go back and reschedule the same process
          goto rerun;
      }
      proc = 0;

    }
    release(&ptable.lock);

  }
}
Beispiel #30
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
  struct proc *p;

  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    /*
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;
    */
    int i;
    for(i = 0; i < PRIORITIES; i ++)
      {
	p = ready[i];
	if(p == 0)
	  continue;
      // Switch to chosen process.  It is the process's job
      // to release ptable.lock and then reacquire it
      // before jumping back to us.
      proc = p;
      switchuvm(p);
      p->state = RUNNING;
      remove_from_ready(p);
      swtch(&cpu->scheduler, proc->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      proc = p = 0;
      /*
      if(current_priority == 31)
	current_priority = 0;
      else
      current_priority = i + 1; */
    }
    release(&ptable.lock);

  }
}