void Kernel(tf_t *tf_p) // kernel begins its control upon/after interrupt
{
   int pid;

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

   switch( tf_p->intr_id )
   {
      case TIMER_INTR:
         TimerISR();
         break;
      case IRQ7_INTR:
         IRQ7ISR(); // service parallel printer port event
         break;
      case GETPID_INTR:
         tf_p->eax = cur_pid;
         break;
      case SLEEP_INTR:
         SleepISR();
         break;
      case SPAWN_INTR:
         pid = DeQ( &avail_q ); // get pid and put in ebx can be in Kernel()
         pcbs[ cur_pid ].tf_p->ebx = pid; // child PID, could be -1
         if( pid == -1 ) break; // no more process
         SpawnISR(pid, (func_ptr_t) pcbs[ cur_pid ].tf_p->eax);
         break;
      case SEMINIT_INTR:
         SemInitISR();
         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;
      case IRQ3_INTR:	
      case IRQ4_INTR:
         IRQ34ISR();	
         break;
      case FORK_INTR:
         pid = DeQ( &avail_q );
         ForkISR(pid);
         pcbs[ cur_pid ].tf_p->ebx = pid;
         break;
      case WAIT_INTR: //cons_printf("Wait Intr\n");
         WaitISR(); 
         break;
      case EXIT_INTR: //cons_printf("Exit Intr\n");
         ExitISR();
         break;
   }
   Scheduler();                  // find same/new process to run
   Loader(pcbs[ cur_pid ].tf_p); // load it to run
} // Kernel()
예제 #2
0
// **********************************************************************
// **********************************************************************
// signal semaphore
//
//	if task blocked by semaphore, then clear semaphore and wakeup task
//	else signal semaphore
//
void semSignal(Semaphore* s)
{
	int i;
	// assert there is a semaphore and it is a legal type
	assert("semSignal Error" && s && ((s->type == 0) || (s->type == 1)));

	// check semaphore type
	if (s->type == 0)
	{
		// binary semaphore
		// look through tasks for one suspended on this semaphore

		for (i=0; i<MAX_TASKS; i++)	// look for suspended task
		{
			if (tcb[i].event == s)
			{
				s->state = 0;				// clear semaphore
				tcb[i].event = 0;			// clear event pointer
				tcb[i].state = S_READY;	// unblock task

				if(DeQ(s->q,i) >= 0)
        {
          enQ(rq,i,tcb[i].priority);
        }

				if (!superMode) swapTask();
				return;
			}
		}
		// nothing waiting on semaphore, go ahead and just signal
		s->state = 1;						// nothing waiting, signal
		if (!superMode) swapTask();
		return;
	}
	else
	{
		// counting semaphore
    if (++s->state > 0) 
    {
      return; 
    }
    
    else
    {
      int nextTask = DeQ(s->q,-1);
      enQ(rq, nextTask, tcb[nextTask].priority);
      tcb[nextTask].state = S_READY;
      tcb[nextTask].event = 0;
      return;
    }
	}
} // end semSignal
예제 #3
0
파일: main.c 프로젝트: suond/csc159
int main() {
   int pid;
   
   InitKernelData();
   InitKernelControl();
   pid = DeQ(&free_q);
   StartProcISR(pid,(unsigned int)IdleProc);
   pid = DeQ(&free_q);
   StartProcISR(pid,(unsigned int)InitProc);
   LoadRun(pcb[0].TF_ptr);
   
   return 0;   // not reached, but compiler needs it for syntax
}
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;
   }
}
예제 #5
0
파일: os345tasks.c 프로젝트: bpachev/CS_235
static void exitTask(int taskId)
{
  Semaphore* sem = semaphoreList;
  Semaphore** semLink = &semaphoreList;
	assert("exitTaskError" && tcb[taskId].name);

	// 1. find task in system queue
	// 2. if blocked, unblock (handle semaphore)
	// 3. set state to exit

	// ?? add code here
  while(sem = *semLink)
  {
      if (tcb[taskId].event == sem)
      {
//        printf("\nHello World");
          DeQ(sem->q,taskId);
          enQ(rq,taskId,tcb[taskId].priority);
   //     printQ(rq);
      }
    // move to next semaphore
    semLink = (Semaphore**)&sem->semLink;
  }

//  DeQ(rq,taskId);
	tcb[taskId].state = S_EXIT;			// EXIT task state
	return;
} // end exitTask
예제 #6
0
파일: isr.c 프로젝트: OnelungBL/CSC-159
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;
}
예제 #7
0
파일: isr.c 프로젝트: OnelungBL/CSC-159
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
	}
}
예제 #8
0
파일: isr.c 프로젝트: mios16/CPE159
////////////phase 4
void MsgSndISR(int msg_addr)
{
	int msg_q_id;
	int freed_pid;
	msg_t *incoming_msg_ptr, *dst_msg_ptr; 
	
	incoming_msg_ptr = (msg_t *) msg_addr; 
	msg_q_id = incoming_msg_ptr->recipient;
	incoming_msg_ptr->OS_clock = OS_clock;
	incoming_msg_ptr->sender = running_pid;

	if(msg_q[msg_q_id].wait_q.len == 0)
	{
		MsgEnQ(incoming_msg_ptr, &msg_q[msg_q_id]);
	}	
	else
	{
		freed_pid = DeQ(&(msg_q[msg_q_id].wait_q));
		EnQ(freed_pid, &ready_q);
		pcb[freed_pid].state = READY;
		dst_msg_ptr = (msg_t *) pcb[freed_pid].TF_ptr->eax;
		*dst_msg_ptr = *incoming_msg_ptr;
	}
			
}
예제 #9
0
int bfs(int source, int dest){

    int u, v;
    int d[300+10] , visited[300+10];
    for(int i=0;i<305;i++) {d[i] = 10000; visited[i] = 0;}


    d[source] = 0;
    parent[source] = -1;
    visited[source] = 1;
    EnQ(source);

    while(Q_Empty()==0){

        u = DeQ();

        for(v=1; v<=Total_Router; v++){

            if(routing_table[u][v]==1&&visited[v]==0){
                d[v] = d[u] + 1;
                visited[v] = 1;
                parent[v] = u;
                EnQ(v);
            }

        }
    }
    return d[dest];
}
예제 #10
0
파일: main.c 프로젝트: mios16/CPE159
int main() 
{
   	int pid;

	InitKernelData();	//call InitKernelData()  to set kernel data
	InitKernelControl();	//call InitKernelControl() (see below)	
	
	pid = DeQ(&free_q);	
	StartProcISR(pid, IdleProc);
	
	//phase 3
	pid = DeQ(&free_q);	
	StartProcISR(pid, InitProc);

	LoadRun(pcb[0].TF_ptr);	//call LoadRun() to load/run IdleProc	
	return 0;		//this will never be executed
}
int SemInitISR(int sem_count)
{
	int sid;
	sid = DeQ(&avail_sem_q);
	if(sid == -1) return sid;
	sems[sid].count = sem_count;
	InitQ(&(sems[sid].wait));
	
	return sid;
}
예제 #12
0
파일: isr.c 프로젝트: OnelungBL/CSC-159
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;
}
예제 #13
0
파일: isr.c 프로젝트: OnelungBL/CSC-159
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;
	}
}
int SemInitISR(int sem_count) {
   int sid;
   sid = DeQ(&avail_sem_q);
   
   if(sid < 0) {
      return -1;
   }
   sems[sid].sem_count = sem_count;
   InitQ(&sems[sid].wait_q);
   return sid;
}
예제 #15
0
파일: main.c 프로젝트: OnelungBL/CSC-159
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
}
//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++;
   }
}
예제 #17
0
파일: isr.c 프로젝트: suond/csc159
void SemGetISR(int limit){
	
	int sem_id;
	sem_id = DeQ(&sem_q);
	if(sem_id == -1){
		pcb[running_pid].TF_ptr->ebx= -1;
		return;
        }
	MyBzero((char*)&sem[sem_id].wait_q,sizeof(q_t));
	sem[sem_id].limit = limit;
	pcb[running_pid].TF_ptr->ebx= sem_id;
}
예제 #18
0
파일: isr.c 프로젝트: OnelungBL/CSC-159
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;
}
예제 #19
0
파일: main.c 프로젝트: mios16/CPE159
int main() 
{
   	int pid;

	InitKernelData();	//call InitKernelData()  to set kernel data
	InitKernelControl();	//call InitKernelControl() (see below)	
	
	pid = DeQ(&free_q);	
	StartProcISR((int) pid, (int) IdleProc);
	
	//phase 3
	pid = DeQ(&free_q);	
	StartProcISR((int) pid, (int) InitProc);

	//phase 7
	pid = DeQ(&free_q);	
	StartProcISR((int) pid, (int) FileService);

	//phase 6
	pid = DeQ(&free_q);	
	StartProcISR((int) pid, (int) ShellProc);

	pid = DeQ(&free_q);
	StartProcISR((int) pid, (int) StdinProc);

	pid = DeQ(&free_q);
	StartProcISR((int) pid, (int) StdoutProc);
	
	LoadRun(pcb[0].TF_ptr);	//call LoadRun() to load/run IdleProc	
	return 0;		//this will never be executed

}
예제 #20
0
// **********************************************************************
// **********************************************************************
// wait on semaphore
//
//	if semaphore is signaled, return immediately
//	else block task
//
int semWait(Semaphore* s)
{
	assert("semWait Error" && s);												// assert semaphore
	assert("semWait Error" && ((s->type == 0) || (s->type == 1)));	// assert legal type
	assert("semWait Error" && !superMode);								// assert user mode

	// check semaphore type
	if (s->type == 0)
	{
		// binary semaphore
		// if state is zero, then block task
    

		if (s->state == 0)
		{
			tcb[curTask].event = s;		// block task
			tcb[curTask].state = S_BLOCKED;
      DeQ(rq,curTask);
      enQ(s->q, curTask,tcb[curTask].priority);
      
			swapTask();						// reschedule the tasks
			return 1;
		}
		// state is non-zero (semaphore already signaled)
		s->state = 0;						// reset state, and don't block
		return 0;
	}
	else
	{
      s->state--;
      if (s->state >= 0) return;
      tcb[curTask].event = s;   // block task
      tcb[curTask].state = S_BLOCKED;
      DeQ(rq,curTask);
      enQ(s->q, curTask,tcb[curTask].priority);
      
      swapTask();           // reschedule the tasks
      return 1;
	}
} // end semWait
void SemInitISR()
{
   int sem_count = pcbs[ cur_pid ].tf_p->eax;
   int sid = DeQ( &avail_sem_q ); // get sid and put in ebx can be in Kernel()

   if(sid != -1)
   {
      MyBZero( (char *)&sems[ sid ], sizeof( sem_t ) );
      sems[ sid ].sem_count = sem_count;
   }
   pcbs[ cur_pid ].tf_p->ebx = sid;
   
}
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 );
   }
}
예제 #23
0
파일: isr.c 프로젝트: suond/csc159
void SemPostISR(int sem_id){
	
	if(sem[sem_id].wait_q.len > 0){
		int pid = DeQ(&sem[sem_id].wait_q);
		pcb[pid].state = READY;
		EnQ(pid, &ready_q);
	}
	else{
		sem[sem_id].limit++;
	}
	
		
}
예제 #24
0
파일: os345tasks.c 프로젝트: bpachev/CS_235
// **********************************************************************
// system kill task
//
int sysKillTask(int taskId)
{
	Semaphore* sem = semaphoreList;
	Semaphore** semLink = &semaphoreList;

	// assert that you are not pulling the rug out from under yourself!
	assert("sysKillTask Error" && tcb[taskId].name && superMode);
	printf("\nKill Task %s", tcb[taskId].name);

	// signal task terminated
	semSignal(taskSems[taskId]);

	// look for any semaphores created by this task
	while(sem = *semLink)
	{
    DeQ(sem->q,taskId);
		if(sem->taskNum == taskId)
		{
			// semaphore found, delete from list, release memory
			deleteSemaphore(semLink);
		}
		else
		{
			// move to next semaphore
			semLink = (Semaphore**)&sem->semLink;
		}
	}

	// ?? delete task from system queues
//	printQ(rq);
	DeQ(rq,taskId);
//	printQ(rq);
  free_argv(tcb[taskId].argv,tcb[taskId].argc);
  free(tcb[taskId].name);
  free(tcb[taskId].stack);
	tcb[taskId].name = 0;			// release tcb slot
	return 0;
} // end sysKillTask
예제 #25
0
파일: main.c 프로젝트: OnelungBL/CSC-159
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
}
예제 #26
0
파일: main.c 프로젝트: suond/csc159
void Scheduler() {  // to choose running PID
   if(running_pid >0)
      return;

   if(running_pid == 0)
      pcb[running_pid].state = READY;

   running_pid = DeQ(&ready_q);
   if(running_pid == -1)
      running_pid=0;

   pcb[running_pid].state = RUN;
   
}
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;
}
예제 #28
0
파일: isr.c 프로젝트: mios16/CPE159
void SemPostISR(int sem_id)
{
	int temp;
	if(sem[sem_id].wait_q.len == 0)	//check if any awaits
	{
		sem[sem_id].limit++;

	}
	else
	{
		temp = DeQ(&(sem[sem_id].wait_q));
		EnQ(temp, &ready_q);
		pcb[running_pid].state = READY;
	}
}
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
}
예제 #30
0
// **********************************************************************
// **********************************************************************
// Delete semaphore and free its resources
//
bool deleteSemaphore(Semaphore** semaphore)
{
	Semaphore* sem = semaphoreList;
	Semaphore** semLink = &semaphoreList;
  int i;
  
	// assert there is a semaphore
	assert("deleteSemaphore Error" && *semaphore);

	// look for semaphore
	while(sem)
	{
		if (sem == *semaphore)
		{
			// semaphore found, delete from list, release memory
			*semLink = (Semaphore*)sem->semLink;

			// free the name array before freeing semaphore
			printf("\ndeleteSemaphore(%s)", sem->name);

			// ?? free all semaphore memory
			// ?? What should you do if there are tasks in this
			//    semaphore's blocked queue????
      while(sem->q[0])
      {
         DeQ(sem->q,-1);        
      }
      
      
      deleteDeltaClock(dClock,sem);
      
      
      free(sem->q);
      sem->q = 0;
			free(sem->name);
      sem->name = 0;
			free(sem);

			return TRUE;
		}
		// move to next semaphore
		semLink = (Semaphore**)&sem->semLink;
		sem = (Semaphore*)sem->semLink;
	}

	// could not delete
	return FALSE;
} // end deleteSemaphore