school/ecen425/lab6app.c

188 lines
4.9 KiB
C

/*
File: lab6app.c
Revision date: 4 November 2009
Description: Application code for EE 425 lab 6 (Message queues)
*/
#include "clib.h"
#include "yakk.h" /* contains kernel definitions */
#include "lab6defs.h" /* contains definitions for this lab */
#define TASK_STACK_SIZE 512 /* stack size in words */
#define MSGQSIZE 10
struct msg MsgArray[MSGARRAYSIZE]; /* buffers for message content */
int ATaskStk[TASK_STACK_SIZE]; /* a stack for each task */
int BTaskStk[TASK_STACK_SIZE];
int STaskStk[TASK_STACK_SIZE];
int GlobalFlag;
void *MsgQ[MSGQSIZE]; /* space for message queue */
YKQ *MsgQPtr; /* actual name of queue */
void ATask(void) /* processes data in messages */
{
struct msg *tmp;
int min, max, count;
min = 100;
max = 0;
count = 0;
while (1)
{
tmp = (struct msg *) YKQPend(MsgQPtr); /* get next msg */
/* check sequence count in msg; were msgs dropped? */
if (tmp->tick != count+1)
{
print("! Dropped msgs: tick ", 21);
if (tmp->tick - (count+1) > 1) {
printInt(count+1);
printChar('-');
printInt(tmp->tick-1);
printNewLine();
}
else {
printInt(tmp->tick-1);
printNewLine();
}
}
/* update sequence count */
count = tmp->tick;
/* process data; update statistics for this sample */
if (tmp->data < min)
min = tmp->data;
if (tmp->data > max)
max = tmp->data;
/* output min, max, tick values */
print("Ticks: ", 7);
printInt(count);
print("\t", 1);
print("Min: ", 5);
printInt(min);
print("\t", 1);
print("Max: ", 5);
printInt(max);
printNewLine();
}
}
void BTask(void) /* saturates the CPU for 5 ticks */
{
int busycount, curval, j, flag, chcount;
unsigned tickNum;
curval = 1001;
chcount = 0;
while (1)
{
YKDelayTask(2);
if (GlobalFlag == 1)
{ /* flag set -- loop for 5 ticks */
YKEnterMutex();
//busycount = YKTickNum;
busycount = getYKTickNum();
YKExitMutex();
while (1)
{
YKEnterMutex();
//tickNum = YKTickNum;
tickNum = getYKTickNum();
YKExitMutex();
if(tickNum >= busycount + 5) break;
curval += 2; /* evaluate next number */
flag = 0;
for (j = 3; (j*j) < curval; j += 2)
{
if (curval % j == 0)
{
flag = 1;
break;
}
}
if (!flag)
{
printChar('.'); /* output a marker for each prime */
if (++chcount > 75)
{
printNewLine();
chcount = 0;
}
}
}
printNewLine();
chcount = 0;
GlobalFlag = 0; /* clear flag */
}
}
}
void STask(void) /* tracks 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;
setYKIdleCount(0);
YKDelayTask(5);
//max = YKIdleCount / 25;
max = getYKIdleCount() / 25;
//YKIdleCount = 0;
setYKIdleCount(0);
YKNewTask(BTask, (void *) &BTaskStk[TASK_STACK_SIZE], 10);
YKNewTask(ATask, (void *) &ATaskStk[TASK_STACK_SIZE], 20);
while (1)
{
YKDelayTask(20);
YKEnterMutex();
//switchCount = YKCtxSwCount;
switchCount = getYKCtxSwCount();
//idleCount = YKIdleCount;
idleCount = getYKIdleCount();
YKExitMutex();
printString("<<<<< Context switches: ");
printInt((int)switchCount);
printString(", CPU usage: ");
tmp = (int) (idleCount/max);
printInt(100-tmp);
printString("% >>>>>\r\n");
YKEnterMutex();
//YKCtxSwCount = 0;
setYKCtxSwCount(0);
//YKIdleCount = 0;
setYKIdleCount(0);
YKExitMutex();
}
}
void main(void)
{
YKInitialize();
/* create queue, at least one user task, etc. */
GlobalFlag = 0;
MsgQPtr = YKQCreate(MsgQ, MSGQSIZE);
YKNewTask(STask, (void *) &STaskStk[TASK_STACK_SIZE], 30);
YKRun();
}