Example #1
0
void TimerISR()
{
	outportb(0x20, 0x60); // dismiss timer interrupt

	// deal with sleep items
	sys_tick++;


	while(!EmptyQ(&sleep_q) && (pcbs[sleep_q.q[sleep_q.head]].wake_tick <= sys_tick)) {
		int tmpPID = DeQ(&sleep_q);
		pcbs[tmpPID].state=READY;
		EnQ(tmpPID, &ready_q);
	}

	if(cur_pid == 0) return; // if Idle process, no need to do this on it

	pcbs[cur_pid].tick_count++;


	if(pcbs[cur_pid].tick_count == TIME_SLICE) // running up time, preempt it?
	{
		pcbs[cur_pid].tick_count = 0; // reset (roll over) usage time
		pcbs[cur_pid].total_tick_count += TIME_SLICE; // sum to total

		pcbs[cur_pid].state = READY;  // change its state
		EnQ(cur_pid, &ready_q);       // move it to ready_q
		cur_pid = -1;                 // no longer running
	}
}
void MsgSndISR() 
{	
   int mid, pid;
   msg_t *src, *dest;

   mid = pcbs[cur_pid].tf_p->eax;
   src = (msg_t *)pcbs[cur_pid].tf_p->ebx;

   src->sender = cur_pid;      // authenticate sender
   src->time_stamp = sys_tick; // authenticate time_stamp

   if(EmptyQ(&mboxes[mid].wait_q))
   {
      MsgEnQ( src, &( mboxes[mid].msg_q ) );
   }
   else
   {	
      pid = DeQ(&mboxes[mid].wait_q);
      pcbs[pid].state = READY;
      EnQ(pid, &ready_q);

      dest = (msg_t *)pcbs[pid].tf_p->eax; // eax since MsgRcv changed
      *dest = *src;
   }
}
Example #3
0
void MsgSndISR()
{
	int mid,pid,head;
	msg_t *source, *destination;

	mid = pcbs[cur_pid].tf_p ->eax;
	source = (msg_t*)pcbs[cur_pid].tf_p -> ebx;

	if(!EmptyQ(&mboxes[mid].wait_q))
	{
		pid = DeQ(&mboxes[mid].wait_q);
		EnQ(pid,&ready_q);
		pcbs[pid].state = READY;

		destination = (msg_t *)pcbs[pid].tf_p -> ebx;
		MyMemCpy((char*)destination,(char*)source,sizeof(msg_t));
	}
	else
	{
		EnQMsg(source, &mboxes[mid].msg_q);
		head = mboxes[mid].msg_q.head;
		destination = &mboxes[mid].msg_q.msgs[head];
	}
	destination->sender = cur_pid;
	destination->send_tick = sys_tick;
}
Example #4
0
void SemPostISR(int sid){
	if (!EmptyQ(&(sems[sid].wait_q))) {
		int free_pid = DeQ(&(sems[sid].wait_q));
		pcbs[free_pid].state = READY;
		EnQ(free_pid, &ready_q);
	}
	else {
		sems[sid].sem_count += 1;
	}
}
Example #5
0
void SleepISR(int sleep_secs){
	q_t tmp_q;
	InitQ(&tmp_q);
	pcbs[cur_pid].wake_tick = (sys_tick + sleep_secs * 100);
	while( !(EmptyQ(&sleep_q)) &&
			(pcbs[sleep_q.q[sleep_q.head]].wake_tick <= pcbs[cur_pid].wake_tick)         ){
		int tmpPID= DeQ(&sleep_q);
		EnQ(tmpPID, &tmp_q);
	}
	EnQ(cur_pid, &tmp_q);
	while (!EmptyQ(&sleep_q)){
		EnQ(DeQ(&sleep_q), &tmp_q);
	}
	while(!EmptyQ(&tmp_q)){
		EnQ(DeQ(&tmp_q), &sleep_q);
	}
	pcbs[cur_pid].state = SLEEP;
	cur_pid = -1;
}
Example #6
0
void Scheduler() // this is kernel's process scheduler, simple round robin
{
   if(cur_pid > 0) return; // when cur_pid is not 0 (IdleProc) or -1 (none)

   if(cur_pid == 0) pcbs[0].state = READY; // skip when cur_pid is -1

   if(EmptyQ(&ready_q)) cur_pid = 0; // ready q empty, use IdleProc
   else cur_pid = DeQ(&ready_q);     // or get 1st process from ready_q

   pcbs[cur_pid].state = RUN;   // RUN state for newly selected process
}
Example #7
0
int SemInitISR(int sem_count){
	int sid;
	if (!EmptyQ(&avail_sem_q)) {
		sid = DeQ(&avail_sem_q);
		sems[sid].sem_count = sem_count;
		InitQ(&(sems[sid].wait_q));
	}
	else {
		sid = -1;
	}
	return sid;
}
//void SemPostISR(int sid) {
void SemPostISR() {
   int pid, sid = pcbs[cur_pid].tf_p->eax;
   
   if(!EmptyQ(&sems[sid].wait_q)) {
      pid = DeQ(&sems[sid].wait_q);
      EnQ(pid, &ready_q);
      pcbs[pid].state = READY;
   }
   else {
      sems[sid].sem_count++;
   }
}
void SemPostISR( int sid ) // passing arg as device driver phase uses this
{
   if( EmptyQ( &sems[ sid ].wait_q ) )
   {
      sems[ sid ].sem_count++;
   }
   else
   {
      int pid = DeQ( &sems[ sid ].wait_q );
      pcbs[ pid ].state = READY;
      EnQ( pid, &ready_q );
   }
}
Example #10
0
datatype *DeQueueQ(struct sequeue *sq){
	datatype 	*ret;
	if(EmptyQ(sq)){
		printf("queue is empty\n");
		return NULL;
	}else{
		ret = (datatype *)malloc(sizeof(datatype));
		*ret = sq->data[(sq->rear-sq->length+1)%MAXSIZE];
		sq->rear--;
		sq->quelen--;
		return ret;
	}
}
Example #11
0
void Kernel(tf_t *tf_p) // kernel directly enters here when interrupt occurs
{
	// Save "tf_p" to pcbs[cur_pid].tf_p for future resume of process runtime
	pcbs[cur_pid].tf_p = tf_p;

	// tf_p->intr_id tells what intr made CPU get here, pushed in entry.S
	switch(tf_p->intr_id)
	{
		case TIMER_INTR:
			TimerISR(); // this must include dismissal of timer interrupt
			break;
		case IRQ7_INTR:
			IRQ7ISR();
			break;
		case SLEEP_INTR:
			SleepISR(tf_p->eax);
			break;
		case GETPID_INTR:
			tf_p->eax = cur_pid;
			break;
		case SPAWN_INTR:
			if (EmptyQ(&avail_q)) {
				cons_printf("No more available PIDs!\n");
				tf_p->ebx = -1;
			}
			else {
				tf_p->ebx = DeQ(&avail_q);
				SpawnISR((int) tf_p->ebx, (func_ptr_t) tf_p->eax);
			}
			break;
		case SEMINIT_INTR:
			tf_p->ebx = SemInitISR(tf_p->eax);
			break;
		case SEMWAIT_INTR:
			SemWaitISR(tf_p->eax);
			break;
		case SEMPOST_INTR:
			SemPostISR(tf_p->eax);
			break;
		case MSGSND_INTR:
			MsgSndISR();
			break;
		case MSGRCV_INTR:
			MsgRcvISR();
			break;
	}

	Scheduler();                // select a process to run
	Loader(pcbs[cur_pid].tf_p); // run the process selected
}
void SleepISR()
{
   q_t tmp_q;

   InitQ( &tmp_q ); // empty temp q

// calc the future wake_tick of cur_pid
   pcbs[cur_pid].wake_tick = sys_tick + 100 * pcbs[cur_pid].tf_p->eax;

// WHILE sleep_q not empty AND the 1st one in it has a wake_tick <=
// wake_tick of cur_pid: move that 1st one from sleep_q to tmp_q
   while(!EmptyQ(&sleep_q)
         &&
         pcbs[ sleep_q.q[ sleep_q.head ] ].wake_tick
         <= pcbs[ cur_pid ].wake_tick
        )
   {
      EnQ(DeQ(&sleep_q), &tmp_q); // append it to tmp_q
   }

// insertion point is reached as either sleep_q is now empty or the
// wake_tick of cur_pid is smaller than the 1st one in the sleep_q
   EnQ( cur_pid, &tmp_q ); // append cur_pid to tmp_q

// append the rest of sleep_q to tmp_q
   while( ! EmptyQ( &sleep_q ) )
   {
      EnQ( DeQ( &sleep_q ), &tmp_q );
   }

// update sleep_q with the now ordered tmp_q
   sleep_q = tmp_q; // assignment allowed for struct type

   pcbs[cur_pid].state = SLEEP;
   cur_pid = -1; // need to get a different proc to run now
}
void SemPostISR(int sid)
{
	int pid;
	
	if( EmptyQ( &(sems[sid].wait)) )
	{
		sems[sid].count++;
		return;
	}
	
	pid = DeQ(&(sems[sid].wait));
	pcbs[pid].state = READY;
	EnQ(pid, &ready_q);
	return;
}
int DeQ(q_t *p) // return -1 if queue is empty
{
   int id;

   if(EmptyQ(p))
   {
      cons_printf("Queue is empty, can't dequeue!\n");
      return -1;
   }
   id = p->q[p->head];
   p->head++;
   if(p->head == Q_SIZE) p->head = 0;   // wrap around
   p->count--;

   return id;
}
Example #15
0
int DeQ(q_t *p)// return -1 if q is empty
{
   	int pid;
	if(!EmptyQ(p))//if Queue is not empty
	{
		pid = p->q[p->head];
		p->head = p->head + 1;
		if(p->head == Q_SIZE)//if head is at index 20 of queue then reset head to 0
			p->head = 0;
		p->count = p->count - 1;
		return pid;
	}
	else return -1;	//return -1 if q is empty


}
void WakieWakie() // wake if (multiple) processes to wake
{
   int pid;

   sys_tick++; // system time/ticks

   // repeat until false:
   //    check if sleep_q is not empty and wake_tick of the 1st
   //    process indicated in sleep_q == sys_tick to wake it up
   while(!EmptyQ(&sleep_q) &&
         pcbs[sleep_q.q[sleep_q.head]].wake_tick==sys_tick)
   {
      pid = DeQ(&sleep_q);
      EnQ(pid, &ready_q);
      pcbs[pid].state = READY;
   }
}
void MsgSndISR(int mid, msg_t *p)
{
	int pid;
	
	p->sender = cur_pid;
	p->send_tick = sys_tick;
	
	if(EmptyQ(&(mboxes[mid].wait_q))) // If wait Queue of message is empty.
		MsgEnQ(p, &(mboxes[mid].msg_q)); // Queue the message.
	else
	{
		pid = DeQ(&(mboxes[mid].wait_q)); // Dequeue the waiting process
		pcbs[pid].state = READY;
		EnQ(pid, &ready_q);
		*((msg_t *) pcbs[pid].tf_p->eax) = *p;
	}
}
void Kernel(tf_t *tf_p) // kernel begins its control upon/after interrupt
{
   int pid, sid;

   pcbs[cur_pid].tf_p = tf_p; // save for cur_pid which may change

   switch(tf_p->intr_id)
   {
      case TIMER_INTR:
         TimerISR(); // service the simulated timer interrupt
         break;
      case GETPID_INTR:
         tf_p->eax = cur_pid;
         break;
      case SLEEP_INTR:
         SleepISR();
         break;
      case SPAWN_INTR:
         if(EmptyQ(&avail_q)) {
            cons_printf("No more processes\n");
            tf_p->eax = -1;
         }
         else {
            pid = DeQ(&avail_q);
            pcbs[pid].state = READY;
            SpawnISR(pid, (func_ptr_t) tf_p->eax);
            tf_p->eax = pid;
         }
         break;
      case SEMINIT_INTR:
         sid = SemInitISR(tf_p->eax);
         tf_p->eax = sid;
         break;   
      case SEMWAIT_INTR:
         SemWaitISR();
         break;
      case SEMPOST_INTR:
         SemPostISR();
         break;      
   }

   
   Scheduler();                // find same/new process to run
   Loader(pcbs[cur_pid].tf_p); // load it to run
} // Kernel()
Example #19
0
void Kernel(tf_t *tf_p) // kernel directly enters here when interrupt occurs
{
   // Save "tf_p" to pcbs[cur_pid].tf_p for future resume of process runtime
   pcbs[cur_pid].tf_p = tf_p;
   
   // tf_p->intr_id tells what intr made CPU get here, pushed in entry.S
   switch(tf_p->intr_id)
   {
      case TIMER_INTR:
         TimerISR(); // this must include dismissal of timer interrupt
         break;
      case SLEEP_INTR:
            SleepISR(tf_p->eax);
            break;
       case GETPID_INTR:
            tf_p->eax = cur_pid;
            break;
   }

   // still handles other keyboard-generated simulated events
   if(cons_kbhit()) // check if a key was pressed (returns non zero)
   {
      char key = cons_getchar(); // get the pressed key

      switch(key) // see if it's one of the following for service
      {
         case 'n':
            if(EmptyQ(&avail_q))
               cons_printf("No more available PIDs!\n");
            else
            {
               SpawnISR(DeQ(&avail_q), SimpleProc);
            }
            break;
         case 'k': KillISR(); break; // non-functional in phase 2
         case 's': ShowStatusISR(); break;
         case 'b': breakpoint(); break; // this stops when run in GDB mode
         case 'q': exit(0);
      } // switch(key)
   } // if(cons_kbhit())

   Scheduler();                // select a process to run
   Loader(pcbs[cur_pid].tf_p); // run the process selected
}
Example #20
0
int DeQ(q_t *p) // return -1 if q is empty
{
	int pid;

	if (EmptyQ(p)) {
		cons_printf("Queue is empty, can't dequeue!\n");
		return -1;
	}

	pid = p->q[p->head];

	p->head += 1;

	if (p->head >= Q_SIZE) {
		p->head = 0;
	}

	p->count -= 1;

	return pid;
}