188 lines
4.9 KiB
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();
|
||
|
}
|