⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stresstest.c

📁 Real-Time Kernel
💻 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 + -