예제 #1
0
void handleNewPieceTask()
{
	int type;
	
	while(1) 
	{
		//wait for a new piece to be created
		YKSemPend(newPieceSEM);
		YKEnterMutex();
		type = NewPieceType;
		/*printString("NEW PIECE id = ");
		printInt(NewPieceID);
		printString(" type = ");
		printInt(NewPieceType);
		printString(" column = ");
		printInt(NewPieceColumn);
		printString(" Orientation = ");
		printInt(NewPieceOrientation);
		printNewLine();//*/
		YKExitMutex();
		
		//Accessing global variables, so better be in mutex
		if(type) //Straight piece
		{
			straightPieceHandler();
		}
		else //square piece
		{
			cornerPieceHandler();
		}
			
	}
}
예제 #2
0
int YKQPost(YKQ* queue, void* msg) {

	TCB* readyTask;
	int retVal;

	YKEnterMutex();
	if (queue->currentSize < queue->maxSize) {
		queue->messages[queue->currentSize] = msg;
		queue->currentSize++;
		retVal = 1;

	} else {
		retVal = 1;
	}
		
	readyTask = removePriorityQueue(&(queue->queue));
	if (readyTask == null) {
		YKExitMutex();
		return retVal;
	} else {
		readyTask->state = T_READY;
		insertPriorityQueue(&readyQueue, readyTask);
		YKExitMutex();
		if (YKGetISRCallDepth() == 0) {
			asm("int 0x20");
		}
	}
	return retVal;

}
예제 #3
0
void* YKQPend(YKQ* queue) {

	void* message;
	int i;
	TCB* runningTask;

	if (queue == null) return null;
	
	YKEnterMutex();
	if (*queue->messages == null) {
		runningTask = removePriorityQueue(&readyQueue);
		runningTask->state = T_BLOCKED;
		insertPriorityQueue((&(queue->queue)), runningTask);
		YKExitMutex();
		asm("int 0x20");
	}

	message = queue->messages[0];
	for (i = 0; i < queue->currentSize-1; i++) {
		queue->messages[i] = queue->messages[i+1];
	}
	queue->currentSize--;
	queue->messages[queue->currentSize] = null;

	YKExitMutex();
	return message;
	
}
예제 #4
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKIdleTask(void) {
	while(1) {
		YKEnterMutex();
		YKIdleTask = YKIdleTask+1;
		YKExitMutex();
	}
}
예제 #5
0
파일: myinth.c 프로젝트: Bipsy/yak-kernel
void newPieceHandler(void) {
	/* 	This function needs to get the details of the new simptris piece and 
		place a new piece on the piece queue. It obtains the next piece from 
		the piece array using a static counter.
	*/

	static unsigned int nextPiece;
	int temp;

	//Build new piece
	YKEnterMutex();
	//printString("NewPieceHandler\n");
	/*printInt(NewPieceID);
	printNewLine();
	printInt(NewPieceType);
	printNewLine();
	printInt(NewPieceOrientation);
	printNewLine();
	printInt(NewPieceColumn);*/
	PiecesArray[nextPiece].id = NewPieceID;
	PiecesArray[nextPiece].type = NewPieceType;
	PiecesArray[nextPiece].orientation = NewPieceOrientation;
	PiecesArray[nextPiece].column = NewPieceColumn;
	YKExitMutex();
	YKQPost(PiecesQPtr, &PiecesArray[nextPiece]);
	if (nextPiece+1 < MSGQSIZE) {	
		nextPiece++;
	} else {
		nextPiece = 0;
	}

	return;	

}
예제 #6
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
//Initalizing code -----------------------------------------------------------------------------
void YKInitialize()
{
	//Initializes all required kernel data structures
	int i;
	YKEnterMutex();
	//Initalize the YKAvailTCBList queue
	YKAvailTCBList = &(YKTCBArray[0]);
    for (i = 0; i < MAXTASKS; i++)
	{
		if(i != 0)
		{
			YKTCBArray[i].prev = &(YKTCBArray[i-1]);
		}
		YKTCBArray[i].next = &(YKTCBArray[i+1]);
	}
	YKTCBArray[0].prev = NULL;
    YKTCBArray[MAXTASKS].next = NULL;
	if(MAXTASKS > 0)
	{
		YKTCBArray[MAXTASKS].prev = &(YKTCBArray[MAXTASKS - 1]);
	}
	YKReadyList = NULL;
	YKSuspList = NULL;
	nestedInterruptLevel = 0;
	curTask = NULL;
	YKNewTask(YKIdleTask, (void *)&IdleStk[IDLESTACKSIZE], 100);
}
예제 #7
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
//YKEventPend
unsigned YKEventPend(YKEVENT *event, unsigned eventMask, int waitMode)
{
	int i;
	YKEnterMutex();
	if(waitMode == EVENT_WAIT_ALL)
	{
		if(event->flags == eventMask)
		{
			return event->flags;
		}
	}
	
	else // wait mode any
	{
		if((event->flags & eventMask) > 0)
		{
			return event->flags;
		}
	}
	YKReadyList->waitMode = waitMode;
	YKReadyList->eventMask = eventMask;
	YKMoveTCB(YKReadyList, &YKReadyList, &(event->blockedList));
	YKScheduler(1);
	return event->flags;
}
예제 #8
0
void Task(void)
{
    unsigned idleCount;
    unsigned numCtxSwitches;

    printString("Task started.\n");
    while (1)
    {
        printString("Delaying task...\n");

        YKDelayTask(2);

        YKEnterMutex();
        numCtxSwitches = YKCtxSwCount;
        idleCount = YKIdleCount;
        YKIdleCount = 0;
        YKExitMutex();

        printString("Task running after ");
        printUInt(numCtxSwitches);
        printString(" context switches! YKIdleCount is ");
        printUInt(idleCount);
        printString(".\n");
    }
}
예제 #9
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKInitialize(){
    int i;
    YKEnterMutex();
    YKIMRInit(0x00);
    running = 0;
    YKIdleCount = 0;
    YKCtxSwCount = 0;
    YKCurTask = NULL; 
    YKRdyList = NULL;
    YKSuspList = NULL;
    nestingLevel = 0;
    YKTickNum = 0;
    YKAvaiSems = MAXSEMS;
    
    // Initialize locations for TCB
    YKAvailTCBList = &(YKTCBArray[0]);
    for (i = 0; i < MAXTASKS; i++){
        YKTCBArray[i].next = &(YKTCBArray[i+1]);
        YKTCBArray[MAXTASKS].prev = NULL; 
    }
    YKTCBArray[MAXTASKS].next = NULL;
    YKTCBArray[MAXTASKS].prev = NULL;

    YKNewTask(YKIdleTask,(void *) &(idleStk[IDLE_STACK_SIZE]),100);  
}
예제 #10
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
//YKEventSet
void YKEventSet(YKEVENT *event, unsigned eventMask)
{
	TCBptr current, next;
	int i;
	YKEnterMutex();
	current = event->blockedList;
	event->flags = event->flags | eventMask;
	while(current != NULL)
	{
		next = current->next;
		if(current->waitMode == EVENT_WAIT_ALL)
		{
			if(current->eventMask == event->flags)
			{
				YKMoveTCB(current, &(event->blockedList), &YKReadyList);
			}
		}
		else
		{
			if((event->flags & eventMask) > 0)
			{
				YKMoveTCB(current, &(event->blockedList), &YKReadyList);
			}
		}
		current = next;
	}
	if(nestedInterruptLevel == 0) //if not in an interrupt
	{
		YKScheduler(1);
	}
}
예제 #11
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
unsigned YKEventPend(YKEVENT *event, unsigned eventMask, int waitMode){
    int conditionMet = 0;
    int i;
    unsigned flags;
    TCBptr temp, temp2, iter;
    YKEnterMutex();
    // ------- Test if Conditions are met --------//
    conditionMet = checkConditions(event->flags, eventMask, waitMode);

    // -------- If condition met, return. Else, block --------//
    if (conditionMet){
        flags = event->flags;
        YKExitMutex();
        return flags;
    }
    else{
        // Remove calling task's TCB from ready list
        temp = YKRdyList; // Hold the first ready task
        // Remove it from Ready list
        YKRdyList = temp->next; 
        if (YKRdyList != NULL)
            YKRdyList->prev = NULL;
        // modify TCB, put in suspended list
        temp->state = BLOCKED;
        temp->flags = eventMask;
        temp->waitMode = waitMode;
        // Put task at event's blocked list
        if (event->waitingOn == NULL){
            event->waitingOn = temp;
            temp->next = NULL;
            temp->prev = NULL;
        }
        else{
            iter = event->waitingOn;
            temp2 = NULL;
            while (iter != NULL && iter->priority < temp->priority){
                temp2 = iter;
                iter = iter->next;
            }
            if (iter == NULL){//At end
                temp2->next = temp;
                temp->prev = temp;
                temp->next = NULL;
            }
            else{ // insert before iterator
                temp->next = iter;
                temp->prev = temp2;
                iter->prev = temp;
                if (temp2 == NULL)//inserted at beginning of list
                    event->waitingOn = temp;
                else
                temp2->next = temp;
            }
        }
        YKScheduler(ContextNotSaved);
        flags = event->flags;
        YKExitMutex();
    }
    return flags;
}
예제 #12
0
int YKQPost(YKQ *queue, void *msg) {
    int return_value;
    // put message into queue
    YKEnterMutex();
    if (queue->size != queue->max_length ) {
        ++(queue->size);
        queue->base_addr[queue->tail] = msg;

        if ( queue->tail == (queue->max_length - 1) )
            queue->tail = 0;      
        else
            ++(queue->tail);
        
        if (queue->size == 1) {
            YKBlockQ2Ready(queue); 
            if (YKISRDepth == 0) {
                YKExitMutex();
                YKScheduler();
            }
        }
        return_value = 1;
    }
    else
        return_value = 0;
    
    YKExitMutex();
    return return_value;
}
예제 #13
0
void YKInitialize(void){
	YKEnterMutex();
	//Create Idle task and add it to the ready queue
	//printString("YKInitialize\n");
	YKNewTask(&YKIdleTask, (void *)&idleStk[IDLE_STACK_SIZE], 100);
	//new task adds to queue for us
}
예제 #14
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void *YKQPend(YKQ *queue){
    void * tempMsg;
    TCBptr temp, temp2, iter;
    TOP:
    YKEnterMutex();
    if (queue->numOfMsgs > 0){ // not empty
        // remove oldest message
        tempMsg = queue->baseAddress[queue->removeLoc];
        queue->removeLoc++;
        // handle roll over
        if (queue->removeLoc >= queue->numOfEntries){
            queue->removeLoc = 0;
        }
        queue->numOfMsgs--;
    }
    else {
        // Remove calling task's TCB from ready list
        temp = YKRdyList; // Hold the first ready task
        // Remove it from Ready list
        YKRdyList = temp->next; 
        if (YKRdyList != NULL)
            YKRdyList->prev = NULL;
        // modify TCB, put in suspended list
            temp->state = BLOCKED;
        // Put task at queue's blocked list
        if (queue->blockedOn == NULL){
            queue->blockedOn = temp;
            temp->next = NULL;
            temp->prev = NULL;
        }
        else{
            iter = queue->blockedOn;
            temp2 = NULL;
            while (iter != NULL && iter->priority < temp->priority){
                temp2 = iter;
                iter = iter->next;
            }
            if (iter == NULL){//At end
                temp2->next = temp;
                temp->prev = temp;
                temp->next = NULL;
            }
            else{ // insert before iterator
                temp->next = iter;
                temp->prev = temp2;
                iter->prev = temp;
                if (temp2 == NULL)//inserted at beginning of list
                    queue->blockedOn = temp;
                else
                temp2->next = temp;
            }
        }
        YKScheduler(ContextNotSaved);
        goto TOP;
    }
    YKExitMutex();
    return tempMsg;

}
예제 #15
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKScheduler(int saveContext){
YKEnterMutex();
    if(YKRdyList != YKCurTask){  
        YKCtxSwCount++; 
        YKDispatcher(saveContext);
    }
YKExitMutex();
}
예제 #16
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKIdleTask(){
    while(1){
        YKEnterMutex();
        YKIdleCount++;
        YKExitMutex();
    }

}
예제 #17
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKNewTask(void (* task)(void), void *stackptr, unsigned char priority){
    int i;
    unsigned *stackIter;
    TCBptr insertion, iter2;
    
    YKEnterMutex();

    insertion = YKAvailTCBList;  
    
    if(insertion == NULL){
        return;
    } 
    
    YKAvailTCBList =  insertion->next;   
     
    insertion->state = READY;
    insertion->priority = priority;
    insertion->delay = 0;
    insertion->flags = 0;
    insertion->waitMode = 0;
 
    if (YKRdyList == NULL)  /* is this first insertion? */
    {
        YKRdyList = insertion;
        insertion->next = NULL;
        insertion->prev = NULL;
    }
    else            /* not first insertion */
    {
        iter2 = YKRdyList;   /* insert in sorted ready list */
        while (iter2->priority < insertion->priority)
            iter2 = iter2->next;  /* assumes idle task is at end */
        if (iter2->prev == NULL) /* insert in list before tmp2 */
            YKRdyList = insertion;
        else
            iter2->prev->next = insertion;
        insertion->prev = iter2->prev;
        insertion->next = iter2;
        iter2->prev = insertion;
    }
    stackIter = (unsigned *)stackptr;
    stackIter -=13;

    for(i=0; i<13; i++) {
        if (i == 10) {
            stackIter[i] = (unsigned)task;
        } else if (i == 12) {
            stackIter[i] = FLAGB;   // Set the interrupt flag
        } else {
            stackIter[i] = 0;
        }
    }   
    insertion->stackptr = (void *)stackIter;
    if(running == 1) {
        YKScheduler(ContextNotSaved);
    } 
    YKExitMutex(); 
}
예제 #18
0
파일: yakc.c 프로젝트: nagneeve/ecen425
void YKExitISR(void) {
	YKEnterMutex();
	ISRCallDepth--;
	if (ISRCallDepth == 0) {
		YKExitMutex();		
		YKScheduler();
	}
	YKExitMutex();
}
예제 #19
0
파일: yakc.c 프로젝트: nagneeve/ecen425
void YKRun(void) {

	YKEnterMutex();
	kernelState = K_RUNNING;
	YKScheduler();
	YKExitMutex();
	return;

}
예제 #20
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
//YKEventReset
void YKEventReset(YKEVENT *event, unsigned eventMask)
{
	YKEnterMutex();
	event->flags = event->flags & (~eventMask);
	if(nestedInterruptLevel == 0)
	{
		YKExitMutex();
	}
}
예제 #21
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKIdleTask(){
    printString("in idle\r\n");
    while(1){
        YKEnterMutex();
        YKIdleCount++;
        YKExitMutex();
    }

}
예제 #22
0
파일: yakc.c 프로젝트: fminor/minormoore
void YKDelayTask(int count) { /* Delays a task for specified number of clock ticks*/
	YKEnterMutex();
	runningTask->delay=count;

	suspendTask(runningTask);

	YKExitMutex();
	YKScheduler(0);
}
예제 #23
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
void YKDelayTask(unsigned count)
{
	YKEnterMutex();

	YKReadyList->delay = count;
	YKMoveTCB(YKReadyList, &YKReadyList, &YKSuspList);

	YKScheduler(1);
}
예제 #24
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
void YKExitISR(void)
{
	YKEnterMutex();
	nestedInterruptLevel--;
	if(nestedInterruptLevel  == 0)
	{
		YKScheduler(0);
	}
}
예제 #25
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
void YKNewTask (void (*task)(void), void* taskStack, int priority)
{
    //Creates a new task
    //sets up tcb and stack frame
    int i;
    int temp;
    //Set up new TCB for task
    //printString("YAK is creating a new task");
    //printWord(task);
    //printNewLine();
    YKEnterMutex();

    YKAvailTCBList->task = task;
    YKAvailTCBList->stackptr = taskStack;
    YKAvailTCBList->state = READY;
    YKAvailTCBList->priority = priority;
    YKAvailTCBList->delay = 0;
    (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES;
    temp = YKAvailTCBList->stackptr;
    //Set Top of ready queue to point to this task
    //printString("SAVING CONTEXT\n\r");
    //printString("STACK PTR START = ");
    //printWord(YKAvailTCBList->stackptr);
    //printNewLine();

    *((int*)YKAvailTCBList->stackptr) = INIT_CFLAGS; //cflags
    (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES;
    *((int*)YKAvailTCBList->stackptr) = 0; //CS
    (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES;
    *((int*)YKAvailTCBList->stackptr) = (int*)task; // ip
    (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES;
    for(i = 0; i < NUM_REGS; i++)
    {
        *((int*)YKAvailTCBList->stackptr) = 0x0;
        (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES;
    }
    *((int*)YKAvailTCBList->stackptr) = temp;
    //printString("STACK PTR end = ");
    //printWord(YKAvailTCBList->stackptr);
    //printNewLine();
    //printString("CONTEXT SAVED\n\r");
    if(curTask == NULL)
    {
        curTask = YKReadyList;
    }
    YKMoveTCB(YKAvailTCBList, &YKAvailTCBList, &YKReadyList);

    if(curTask->priority == YKReadyList->priority)
    {
        return;
    }
    if(!initializing)
    {
        YKScheduler(1);
    }
}
예제 #26
0
파일: yakc.c 프로젝트: fminor/minormoore
YKSEM* YKSemCreate(int initialValue){
	static int index = 0;
	//create sem at index
	YKEnterMutex();
	SStack[index].ID = index;
	SStack[index].value = initialValue;
	YKExitMutex();
	//return address and increment index
	return &SStack[index++];
}
예제 #27
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKEventSet(YKEVENT *event, unsigned eventMask){
    int i;
    int taskMadeReady = 0;
    TCBptr iter, temp, temp2, next;
    unsigned flags;
    YKEnterMutex();
    // ----- Set Flag Group ---- //
    for (i = 0; i < 16; i++){
        if (eventMask & BIT(i)){
            event->flags |= BIT(i);
        }
    }
    flags = event->flags;
    // ----- check Conditions ---- //
    iter = event->waitingOn;
    while (iter != NULL){
        // if conditions are met for that task, put in ready list
        if (checkConditions(flags, iter->flags, iter->waitMode)){
            // remove from pending list
            next = iter->next;
            // check if the task to remove is the head
            if (iter == event->waitingOn){
                event->waitingOn = iter->next;
            }
            if (iter->prev != NULL)
                iter->prev->next = iter->next;
            if (iter->next != NULL)
                iter->next->prev = iter->prev;
            // modify TCB of that task, place in ready list
            iter->state = READY;
            // Put in Rdy List
            temp2 = YKRdyList;
            while (temp2->priority < iter->priority){
                temp2 = temp2->next;
            }
            if (temp2->prev == NULL){
                YKRdyList = iter;
            }
            else{
                temp2->prev->next = iter;
            }
            iter->prev = temp2->prev;
            iter->next = temp2;
            temp2->prev = iter;
            taskMadeReady = 1;
            iter = next;
        } else {
            iter = iter->next;
        }
    }
    // call scheduler if not called from ISR and a task was made ready
    if (taskMadeReady && nestingLevel == 0)
        YKScheduler(ContextNotSaved);
    YKExitMutex();
}
예제 #28
0
void TaskStat(void)                /* a task to track statistics */
{
    unsigned max, switchCount, idleCount;
    int tmp;
        
    YKDelayTask(1);
    printString("Welcome to the YAK kernel\r\n");
    printString("Determining CPU capacity\r\n");
    YKDelayTask(1);
    YKIdleCount = 0;
    YKDelayTask(5);
    max = YKIdleCount / 25;
	
    YKIdleCount = 0;

    YKNewTask(TaskPrime, (void *) &TaskPRMStk[TASK_STACK_SIZE], 32);
    YKNewTask(TaskWord,  (void *) &TaskWStk[TASK_STACK_SIZE], 10);
    YKNewTask(TaskSpace, (void *) &TaskSStk[TASK_STACK_SIZE], 11);
    YKNewTask(TaskPunc,  (void *) &TaskPStk[TASK_STACK_SIZE], 12);
  
    while (1)
    {
        YKDelayTask(20);
        
        YKEnterMutex();
        switchCount = YKCtxSwCount;
        idleCount = YKIdleCount;
        YKExitMutex();
        
        printString ("<<<<< Context switches: ");
        printInt((int)switchCount);
        printString(", CPU usage: ");
        tmp = (int) (idleCount/max);
        printInt(100-tmp);
        printString("% >>>>>\r\n");
        
        YKEnterMutex();
        YKCtxSwCount = 0;
        YKIdleCount = 0;
        YKExitMutex();
    }
}   
예제 #29
0
파일: yakc.c 프로젝트: YazanHalawa/ECEn-425
void YKEventReset(YKEVENT *event, unsigned eventMask){
    int i;
    YKEnterMutex();
    for (i = 0; i < 16; i++){
        // If the specified bit is set in the mask, clear it in the event flags
        if (eventMask & BIT(i)){
            event->flags &= ~(BIT(i));
        }
    }
    YKExitMutex();
}
예제 #30
0
파일: yakc.c 프로젝트: canada11/YAK-Kernel
//Semaphores --------------------------------------------------------------------------------
YKSEM* YKSemCreate(int initialValue)
{
	int semaphore;
	YKEnterMutex();
	semaphore = nextUnusedSemaphore;
	++nextUnusedSemaphore;
	semaphoreArray[semaphore].count = initialValue;
	semaphoreArray[semaphore].blockedList = NULL;
	//YKExitMutex();
	return &semaphoreArray[semaphore];
}