📄 bufftest.c
字号:
/*
* Copyright 2003 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
/* "@(#) DSP/BIOS 4.90.270 01-13-05 (barracuda-o07)" */
/***************************************************************************/
/* */
/* B U F F T E S T . C */
/* */
/* Simulating a network environment where the server program gathers */
/* statistics about various requests from clients in real-time. */
/* CLK Object simulates hardware interrupts from clients. CLK Isr */
/* allocates buffers from a Buffer Pool created statically in CDB and */
/* make them available in a queue for processing task. A periodic object */
/* prints the statistics about the Buffer Pool usage and type of */
/* requests from clients. */
/* */
/***************************************************************************/
#include <std.h>
#include <log.h>
#include <swi.h>
#include <clk.h>
#include <que.h>
#include <sys.h>
#include <buf.h>
#include "bufftestcfg.h"
#define TOTAL_SERVICES 4 /* Total number of various request types from clinets */
#define MAX_BUFFERS 5 /* Total number of buffers in the Buffer Pool */
/* define client request types (these services can be extended) */
typedef enum ServiceType {
GET_SYSTEM_TIME_HIGH = 0,
GET_SYSTEM_TIME_LOW,
GET_CPU_LOAD,
RUN_USER_FXN
}ServiceType;
/*
* define a structure for buffer header which contains information
* about the type of request from clients
*/
typedef struct BufferHeader {
QUE_Elem elem; /* elem will be used by QUE module */
ServiceType service; /* client request type */
Fxn userFxn; /* user function to be executed */
}BufferHeader;
extern BUF_Obj bufferPool;
extern QUE_Obj bufferQueue;
extern SWI_Obj buffSwi;
extern LOG_Obj trace;
extern Int SEG0;
BUF_Handle buffPoolHandle = &bufferPool;
QUE_Handle bufferQueueHandle = &bufferQueue;
/* numberOfBuffers holds number of Buffers allocated by SWI */
Int numberOfBuffers;
/* define an array for collecting statistics about various request types */
Int requestStatistics[TOTAL_SERVICES];
/* service functions */
Void serviceClientRequest(Ptr buffPtr);
Void getSystemTimeHigh();
Void getSystemTimeLow();
Void getMemoryStatus(Int segid);
Void getCpuLoad();
Int defaultUserFunction();
/*
* ======== main ========
*/
Void main()
{
LOG_printf(&trace,"Bufftest example started.\n");
}
/*
* ======== processingTskFxn ========
*
* FUNCTION: Called from DSP/BIOS startup to process the client requests
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void processingTskFxn()
{
Ptr buffPtr;
for (;;) {
if (QUE_empty(bufferQueueHandle)) {
TSK_sleep(1);
} else {
while (!QUE_empty(bufferQueueHandle)) {
/* get a request(i.e. buffer filled with request info) from buffer queue */
buffPtr = QUE_get(bufferQueueHandle);
/* update the statistics */
serviceClientRequest(buffPtr);
/* free the buffer after servicing the request*/
BUF_free(buffPoolHandle, buffPtr);
}
}
}
}
/*
* ======== serviceClientRequest ========
*
* FUNCTION: Called from processingTskFxn function to service the client request
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void serviceClientRequest(Ptr buffPtr)
{
BufferHeader *header;
ServiceType service;
header = (BufferHeader *) buffPtr;
service = header->service;
/* update the statisics for each occurence of the request */
requestStatistics[service]++ ;
/* service the request */
switch (service) {
case GET_SYSTEM_TIME_HIGH :
getSystemTimeHigh();
break;
case GET_SYSTEM_TIME_LOW :
getSystemTimeLow();
break;
case GET_CPU_LOAD :
getCpuLoad();
break;
case RUN_USER_FXN :
( *(header->userFxn) )() ;
}
}
/*
* ======== clkIsr ========
*
* FUNCTION: Called by CLK module for each timer interrupt. It generates the
* number of buffers to be allocated and pass it to buffSwi
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void clkIsr()
{
BUF_Stat stat;
Int randomBuffers;
/* Get the random number of buffers required */
randomBuffers = getRandomNum(MAX_BUFFERS) + 1;
/* Read the Buffer Pool statistics to get number of freebuffers */
BUF_stat(buffPoolHandle, &stat);
if ( randomBuffers > stat.freebuffers ){
randomBuffers = stat.freebuffers;
}
numberOfBuffers = randomBuffers;
/* post a SWI to allocate buffers (numberOfBuffers)*/
SWI_post(&buffSwi);
}
/*
* ======== buffAllocate ========
*
* FUNCTION: Called from buffSwi to allocate buffers and fill them with client request info
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void buffAllocate(Arg numberOfBuffers)
{
BufferHeader * header;
Ptr buffPtr;
Int numbuff, i;
numbuff = *(Int *) numberOfBuffers;
for (i = 0; i < numbuff; i++) {
/* allocating a buffer in SWI context*/
buffPtr = BUF_alloc(buffPoolHandle);
if (buffPtr == NULL ) {
SYS_abort("BUF_alloc failed");
}
/* fill the buffer with info about request type */
header = (BufferHeader *) buffPtr;
header->service = (ServiceType) getRandomNum(TOTAL_SERVICES);
if (header->service == RUN_USER_FXN ) {
/* this is a dummy function used here and can be replaced */
header->userFxn = defaultUserFunction;
}
/*
* make the buffer available to the processing task
* by putting the buffer in the buffer queue
*/
QUE_put(bufferQueueHandle, buffPtr);
}
}
/*
* ======== printStatistics ========
*
* FUNCTION: Called from statisticsPrd to print statistics about client requests
* and Buffer Pool usage for every 16 ticks
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void printStatistics()
{
BUF_Stat stat;
Int maxbuff;
Int service;
Int totalRequests = 0;
BUF_stat(buffPoolHandle, &stat);
maxbuff = BUF_maxbuff(buffPoolHandle);
LOG_printf(&trace, "After 16 ticks, Free buffers Available : %d, Max buffers used : %d ", stat.freebuffers, maxbuff);
for (service = 0; service < TOTAL_SERVICES; service++ ) {
/* print statistics for each request */
switch (service) {
case GET_SYSTEM_TIME_HIGH :
LOG_printf(&trace, "Number of GET_SYSTEM_TIME_HIGH requests : %d", requestStatistics[service]);
break;
case GET_SYSTEM_TIME_LOW :
LOG_printf(&trace, "Number of GET_SYSTEM_TIME_LOW requests : %d", requestStatistics[service]);
break;
case GET_CPU_LOAD :
LOG_printf(&trace, "Number of GET_CPU_LOAD requests : %d", requestStatistics[service]);
break;
case RUN_USER_FXN :
LOG_printf(&trace, "Number of RUN_USER_FXN requests : %d", requestStatistics[service]);
}
totalRequests += requestStatistics[service];
/* Reset the count for the next statistics */
requestStatistics[service] = 0;
}
LOG_printf(&trace, "Total number of requests in 16 ticks : %d \n", totalRequests );
}
/*
* ======== getRandomNum ========
*
* FUNCTION: Called from clkIsr and buffAllocate generate a random number
* It returns a integer between 0 to maxValue-1 inclusive
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Int getRandomNum(Int maxValue)
{
LgInt randomNumber;
randomNumber = CLK_gethtime() % maxValue;
if (randomNumber < 0) {
randomNumber *= -1;
}
return randomNumber ;
}
/*
* ======== getSystemTimeHigh ========
*
* FUNCTION: Called from serviceClientRequest to service GET_SYSTEM_TIME_HIGH request
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void getSystemTimeHigh()
{
LgUns currtime;
currtime = CLK_gethtime();
#ifdef _28_
LOG_printf(&trace, "High Resolution System Time : 0x%04x%04x\n", (Arg)(currtime >> 16), (Arg)(currtime & 0xffff));
#else
LOG_printf(&trace, "High Resolution System Time : 0x%04x%04x\n", (Int)(currtime >> 16), (Int)(currtime & 0xffff));
#endif
}
/*
* ======== getSystemTimeLow ========
*
* FUNCTION: Called from serviceClientRequest to service GET_SYSTEM_TIME_LOW request
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void getSystemTimeLow()
{
LgUns currtime;
currtime = CLK_getltime();
#ifdef _28_
LOG_printf(&trace, "Low Resolution System Time : 0x%04x%04x\n", (Arg)(currtime >> 16), (Arg)(currtime & 0xffff));
#else
LOG_printf(&trace, "Low Resolution System Time : 0x%04x%04x\n", (Int)(currtime >> 16), (Int)(currtime & 0xffff));
#endif
}
/*
* ======== getCpuLoad ========
*
* FUNCTION: Called from serviceClientRequest to service GET_CPU_LOAD request
*
* PARAMETERS: none
*
* RETURN VALUE: none.
*/
Void getCpuLoad()
{
LgInt max, num, acc; /* max, num, acc fields of STS Object */
Int cpuload;
/*
* Read BIOS defined STS object IDL_busyObj to get the following
* num : number of times the DSP/BIOS idle loop is run in 1 second.
* max : minimum number of CPU cycles taken for one idle loop execution.
* acc : total number of CPU cycles elapsed in 1 second.
*
* cpu load = app_cycles / total_cycles
* = (total_cycles - idleloop_cycles) / total_cycles
* = 1 - (idleloop_cycles / total_cycles)
* idleloop_cycles = num * max / acc
*/
#if defined(_54_) /* Handle specific implementation for 54x */
Int maxh, maxl, numh, numl, acch, accl;
maxh = IDL_busyObj.maxh;
maxl = IDL_busyObj.maxl;
numh = IDL_busyObj.numh;
numl = IDL_busyObj.numl;
acch = IDL_busyObj.acch;
accl = IDL_busyObj.accl;
max = maxh;
max = (max << 16) | (0x0000ffff & maxl);
num = numh;
num = (num << 16) | (0x0000ffff & numl);
acc = acch;
acc = (acc << 16) | (0x0000ffff & accl);
#else
max = IDL_busyObj.max;
num = IDL_busyObj.num;
acc = IDL_busyObj.acc;
#endif
/* Calculate approximate cpu load */
cpuload = ( num * max * 1.0 / acc ) * 100; /* gives idleload% */
if (cpuload < 0) { /* since STS maintains -ve numbers for max/acc field */
cpuload *= -1;
}
cpuload = 100 - cpuload ; /* cpuload% = 100 - idleload% */
#ifndef _28_ /* due to 28x BIOS issue, num, acc and max fields are invalid */
LOG_printf(&trace, "cpu load is : %d%%\n", cpuload);
#endif
}
/*
* ======== defaultUserFunction ========
*
* FUNCTION: Called from serviceClientRequest to service RUN_USER_FXN request
*
* PARAMETERS: none
*
* RETURN VALUE: Int ( dummy return since Fxn type returns integer).
*/
Int defaultUserFunction()
{
LOG_printf(&trace, "User Function called\n");
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -