//------------------------------------------------------------------------------
// Function: PollInterrupt
// Description: Poll for HDMI interrupt.
//              This can be polling the interrupt pin on the processor,
//              or polling the register over I2C.
//------------------------------------------------------------------------------
void PollInterrupt(void)
{
    if (INTERRUPT_PENDING)
         InterruptHandler();
}
//CPU Thread Function
void *CPURun(void *args)
{
	//put the first PCB as running
	if (aCPU->runningPCB == NULL)
	{
		aCPU->runningPCB = dequeue(ReadyQPtr);
		aCPU->runningPCB->state = 0;
	}

	//1 for interrupt has occurred, 0 for interrupt did not occur
	int interruptOccurred = (IO1INT || IO2INT || KBINT || TIMERINT);

	while(aCPU->count > 0)
	{	
		
		//PRINT OUT OF CURRENT SETTINGS
		sleep(1);
		printf("\n\n\n\n\n\n\n\n");
		printf("P%d - running", aCPU->runningPCB->pid);
		if (aCPU->IO1->owner != NULL) printf("\nI/O1 - P%d", aCPU->IO1->owner->pid);
		if (aCPU->IO2->owner != NULL) printf("\nI/O2 - P%d", aCPU->IO2->owner->pid);
		if (aCPU->IoQueue->count > 0)
		{
			printf("\nI/O Waiting - ");
			printQueue(aCPU->IoQueue);
		}
		int m;
		for(m = 0; m < pcproc_count; m++)
		{
			if (mutex[m]->owner != NULL) printf("\nM%d - P%d owns", m, mutex[m]->owner->pid);
		}
		for(m = 0; m < pcproc_count * 2; m++)
		{
			if (condVar[m] != NULL ) 
			{
				if (condVar[m]->pcbQueue->count > 0)
				{
					printf("\nCV%d - ", m);
					printQueue(condVar[m]->pcbQueue);
				}
			}
		}
		//Keyboard
		//printf();
		printf("\n-------------------------");
		
		if(interruptOccurred == 0)
		{
			if(aCPU->runningPCB->curr_count > WAIT_TIME)
			{
				runForCount = WAIT_TIME;
			}
		} 
		else
		{
			runForCount = aCPU->runningPCB->curr_count;
		}
		runForCount = rand() % 7;
		
		while(runForCount > 0)
		{
			runForCount--;
			aCPU->runningPCB->curr_count++;
			if (aCPU->runningPCB->curr_count == WAIT_TIME) TIMERINT = 1;
			interruptOccurred = (IO1INT || IO2INT || KBINT || TIMERINT);

			if (interruptOccurred)
			{
				if(TIMERINT)
				{
					InterruptHandler( 7, aCPU->runningPCB);
					runForCount = 0;
				}
				if(IO1INT) InterruptHandler( 3, aCPU->IO1->owner);
				if(IO2INT) InterruptHandler( 4, aCPU->IO2->owner);
				if(KBINT) InterruptHandler( 5, aCPU->Keyboard->owner);
			}
			int processType = aCPU->runningPCB->process->proc_type;
			if ((processType == 0) && (runForCount != 0))
			{
				if (runForCount == 1)
				{
					TIMERINT = 1;
				}
			}
			else if ((processType == 1) && (runForCount != 0))
			{
				int i;
				for(i = 0; i < aCPU->runningPCB->process->no_requests; i++)
				{
					if ( (rand() % 10) == (rand() % 10) )
					{
						aCPU->runningPCB->state = 2;
						aCPU->runningPCB->curr_count = runForCount;
						runForCount = 0;
						InterruptHandler( 1, aCPU->runningPCB);
					}
					else if ( runForCount == 1 )
					{
						TIMERINT = 1;
					}
				}
			}
			else if ((processType == 2) && (runForCount != 0))
			{
				InterruptHandler( 2, aCPU->runningPCB);
				runForCount = 0;
			}
			else if ((processType == 3) || (processType == 4) && (runForCount != 0))
			{
				if(processType == 3)
				{
					pthread_create(&aCPU->producer_thread[aCPU->runningPCB->sharedMemInd], NULL, incCount, (void *) aCPU->runningPCB);
				}
				else if (processType == 4)
				{
					pthread_create(&aCPU->consumer_thread[aCPU->runningPCB->sharedMemInd], NULL, resetCount, (void *) aCPU->runningPCB);
				}
				aCPU->runningPCB->state = 1;
				printf("\nP%d returned to ready queue", aCPU->runningPCB->pid);
				enqueue(ReadyQPtr, aCPU->runningPCB);
				aCPU->runningPCB = dequeue(ReadyQPtr);
				printf("\nP%d selected from ready queue", aCPU->runningPCB->pid);
				runForCount = 0;
			}
			aCPU->count--;
			if (aCPU->count == 0)
			{
			cpuRunning = 0;
			KBDevDestructor(aCPU->Keyboard);
			pthread_exit(NULL);
			}
		}
	}
}