📄 stresstest.c
字号:
/*
// Paradigm C++ Real-Time Kernel: Heap Stress Test
//
// This is a small example of tasking using just a single function that is
// spawned multiple times to stress the heap by having multiple tasks
// allocating, filling, and free dynamically allocated memory. Run-time library
// calls to check that the heap is intact then verify there are no errors and
// the results are reported to display tasks.
//
// This is an excellent example of how easy it is to integrate the Paradigm C++
// Real-Time Kernel into an application. Just include RTKERNEL.H and use the
// TargetExpert to select a real-time application - it could not be simpler.
*/
#include <rtkernel.h>
#include <stdlib.h>
#include <string.h>
#include <alloc.h>
#include <stdio.h>
#define ALLOCS 250 /* Number of allocations */
#define BLOCK_SIZE 100 /* Maximum block size */
typedef struct {
TaskHandle taskHandle ;
unsigned taskAllocations ;
unsigned taskAllocationErrors ;
unsigned taskPasscount ;
} HEAPSTATS ;
static Mailbox mbHeapErrors ;
static Mailbox mbHeapPassed ;
void StressTest(void)
{
HEAPSTATS taskStats ;
unsigned passcount = 0 ;
unsigned reallocs = 0 ; /* Number of successful reallocations */
unsigned allocs = 0 ; /* Number of successful allocations */
unsigned errors = 0 ; /* Number of failed allocations */
unsigned int item ; /* Index to block handle */
unsigned int size ; /* Requested block size */
char *p[ALLOCS] ; /* Allocated memory block pointers */
/* Initialize the pointer array so all are NULL before starting */
memset( p, 0, sizeof(p) ) ;
taskStats.taskHandle = RTKCurrentTask() ;
for ( ;; ) {
/* Compute the pointer and allocation size */
item = random( ALLOCS ) ;
size = random( BLOCK_SIZE ) + 1 ;
/* Free or reallocate the memory block */
if ( p[item] != NULL ) {
if ( ( allocs + reallocs + errors ) % 10 ) {
free( p[item] ) ;
}
else {
char* newPtr = realloc( p[item], size ) ;
if ( newPtr ) {
p[item] = newPtr ;
reallocs++ ;
memset( p[item], item, size ) ;
}
continue ;
}
}
/* Allocate a new block */
if ( ( p[item] = malloc(size) ) == NULL ) {
errors++ ;
}
else {
allocs++ ;
memset( p[item], item, size ) ;
}
/* Check if the heap is intact */
if ( heapcheck() == _HEAPCORRUPT ) {
RTKPut( mbHeapErrors, &taskStats.taskHandle ) ;
}
/* Release it all after a set number of allocation attempts */
if ( ( ( reallocs + allocs + errors ) % 256 ) == 0 ) {
int i ;
for ( i = 0; i < ALLOCS; i++ ) {
if ( p[i] != NULL ) {
free( p[i] ) ;
p[i] = NULL ;
}
}
/* Send a message that the current stress test pass is completed */
taskStats.taskAllocations = allocs + reallocs ;
taskStats.taskAllocationErrors = errors ;
taskStats.taskPasscount = ++passcount ;
RTKPut( mbHeapPassed, &taskStats ) ;
reallocs = allocs = errors = 0 ;
}
}
}
void ErrorDiagnostic(void)
{
while ( 1 ) {
TaskHandle heapErrorTask ;
RTKGet( mbHeapErrors, &heapErrorTask ) ;
printf( "Heap error detected in task %s\n", RTKTaskName( heapErrorTask ) ) ;
}
}
void PasscountDiagnostic(void)
{
while ( 1 ) {
HEAPSTATS taskStats ;
RTKGet( mbHeapPassed, &taskStats ) ;
printf( "Task %s pass %u completed: %u allocations, %u failures\n", RTKTaskName( taskStats.taskHandle ), taskStats.taskPasscount, taskStats.taskAllocations, taskStats.taskAllocationErrors ) ;
}
}
void main(void)
{
/* Get the last error to see if the Paradigm C++ Real-Time Kernel initialization was successful */
RTKResult lastError = RTKGetLastError() ;
if ( lastError != RTKERR_NONE ) {
printf( "Paradigm C++ Real-Time Kernel initialization failed\n" ) ;
}
else {
RTKernelInfo rtkInfo ;
RTKInfo( &rtkInfo ) ;
if ( rtkInfo.debugVersion ) {
printf( "Debug version of Paradigm C++ Real-Time Kernel is in use:\n" ) ;
printf( " Performance is reduced for improved error checking\n" ) ;
printf( " Real-Time Kernel event and error logging is available\n\n" ) ;
RTKSetTraceBufferSize( 128 ) ;
}
/* Mailboxes to get error/passcount messages */
mbHeapErrors = RTKCreateMailbox( sizeof(TaskHandle), 4, "HeapErrors" ) ;
mbHeapPassed = RTKCreateMailbox( sizeof(HEAPSTATS), 4, "PassCount" ) ;
/* Tasks to stress the heap */
RTKCreateTask( StressTest, 10, 256 + ALLOCS * sizeof(char*), "HeapTask1" ) ;
RTKCreateTask( StressTest, 10, 256 + ALLOCS * sizeof(char*), "HeapTask2" ) ;
RTKCreateTask( StressTest, 10, 256 + ALLOCS * sizeof(char*), "HeapTask3" ) ;
RTKCreateTask( StressTest, 10, 256 + ALLOCS * sizeof(char*), "HeapTask4" ) ;
RTKTimeSlice( 1 ) ;
/* Tasks to report diagnostics */
RTKCreateTask( ErrorDiagnostic, 11, 256, "ErrorDiagnostic" ) ;
RTKCreateTask( PasscountDiagnostic, 11, 256, "PasscountDiagnostic" ) ;
/* No more work for this task */
RTKDeleteTask( RTKCurrentTask() ) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -