From 8a999ce0abbd36f5f6349500cef06ae5c384937d Mon Sep 17 00:00:00 2001 From: siddhant Date: Fri, 22 May 2026 16:08:02 +0000 Subject: [PATCH] changes made for resource measurement for 'enc' command. (#41) Reviewed-on: http://13.234.246.121:3000/Neominds/ossl35vx69/pulls/41 Co-authored-by: siddhant Co-committed-by: siddhant --- TestPrograms/sysCallMeasurement/SysCallStat.h | 40 ++++ TestPrograms/sysCallMeasurement/sysCallStat.c | 67 ++++++ vxworks-6.9/target/src/os/io/ioLib.c | 153 ++++++++++++-- vxworks-6.9/target/src/os/mm/memPartLib.c | 193 ++++++++++++++++++ 4 files changed, 440 insertions(+), 13 deletions(-) create mode 100644 TestPrograms/sysCallMeasurement/SysCallStat.h create mode 100644 TestPrograms/sysCallMeasurement/sysCallStat.c diff --git a/TestPrograms/sysCallMeasurement/SysCallStat.h b/TestPrograms/sysCallMeasurement/SysCallStat.h new file mode 100644 index 00000000..f689e970 --- /dev/null +++ b/TestPrograms/sysCallMeasurement/SysCallStat.h @@ -0,0 +1,40 @@ + +#ifndef SYS_CALL_STAT +#define SYS_CALL_STAT +#include +#include +#include +#include +#include +#include "sysLib.h" +#include "SysCallStat.h" +#include +#include +enum kernelAPI +{ + openCall=0, + closeCall, + readCall, + writeCall, + sysCallMax, +}; + + +typedef struct +{ + unsigned int sysCallCount; + unsigned long int execTimeUsec; +} KRNL_API_STATS; + + + + +void displayStats(); +void clearSysTableData(); +void sysCallMeasurementTask(); +void CaptureSysCallMetrics(); +int measurementFlag; +TASK_ID sysCallTaskID; +static SEM_ID sysCallSemID; +UINT32 tsFreq; +#endif diff --git a/TestPrograms/sysCallMeasurement/sysCallStat.c b/TestPrograms/sysCallMeasurement/sysCallStat.c new file mode 100644 index 00000000..cefb9c95 --- /dev/null +++ b/TestPrograms/sysCallMeasurement/sysCallStat.c @@ -0,0 +1,67 @@ +#include "sysCallStat.h" +extern KRNL_API_STATS API_STATS[sysCallMax]; +/* "enc", "-pbkdf2 -aes-256-cbc -in plain.txt -out cipher.enc -kfile keyfile.key" */ +void clearSysTableData() +{ + int i=0; + + for (; i< sysCallMax; i++) + { + API_STATS[i].execTimeUsec=0; + API_STATS[i].sysCallCount=0; + } +} + +void sysCallMeasurementTask(const char* cmd, const char* arg) +{ + measurementFlag = 1; + shellCmdExec (cmd, arg); + measurementFlag=0; + semBGive(sysCallSemID); + measurementFlag = 0; + displayStats(); +} + +void CaptureSysCallMetrics(const char* cmd, const char* arg) +{ + tsFreq = sysTimestampFreq(); /*Set this once during init and neednot set during every system call execution.*/ + sysCallSemID = semBCreate(SEM_Q_FIFO,SEM_EMPTY); + if(!sysCallSemID) + { + printf("CaptureSysCallMetrics: Failed to create semaphore\n"); + return ; + } + + clearSysTableData(); + + sysCallTaskID= taskSpawn("tSysCallMeasure", + 50, /* priority */ + 0, /* options */ + 8192, /* stack */ + (FUNCPTR)sysCallMeasurementTask, + cmd, arg,0,0,0,0,0,0,0,0); + + + if(sysCallTaskID == ERROR) /*This is to avoid parent task in block state if taskSpawn fails to create a task.*/ + { + printf("CaptureSysCallMetrics: Failed to create a task\n"); + return ; + } + + semBTake(sysCallSemID, WAIT_FOREVER); /*As we crated semaphore with SEM_EMPTY, so it is unavilable and gets blocked here for parent and gets unblcoked when child executes semGive().*/ + semDelete(sysCallSemID); +} + +void displayStats() +{ + printf("------------------------------------------------------------------\n"); + printf("%-15s %-15s %-15s %-20s\n","crypto cmd","system call","Invocations","Total time (USec)"); + printf("------------------------------------------------------------------\n"); + printf("%-15s %-15s %-15d %-20lu\n","enc","open",API_STATS[openCall].sysCallCount,API_STATS[openCall].execTimeUsec); + printf("%-15s %-15s %-15d %-20lu\n","enc","close",API_STATS[closeCall].sysCallCount,API_STATS[closeCall].execTimeUsec); + printf("%-15s %-15s %-15d %-20lu\n","enc","read",API_STATS[readCall].sysCallCount,API_STATS[readCall].execTimeUsec ); + printf("%-15s %-15s %-15d %-20lu\n","enc","write",API_STATS[writeCall].sysCallCount,API_STATS[writeCall].execTimeUsec); + printf("-------------------------------------------------------------------\n"); +} + + diff --git a/vxworks-6.9/target/src/os/io/ioLib.c b/vxworks-6.9/target/src/os/io/ioLib.c index 8fa0816e..fee5d9ce 100644 --- a/vxworks-6.9/target/src/os/io/ioLib.c +++ b/vxworks-6.9/target/src/os/io/ioLib.c @@ -320,6 +320,33 @@ the VxWorks programmer guides. #define STD_VALID(fd) (((fd) >= 0) && ((fd) < 3)) /* extern variable declaration */ +/* +* uncomment the line below to measure open, close, read +* and write system calls for 'enc' command. +*/ +/* #define MEASURE_SYS_CALLS */ + +#ifdef MEASURE_SYS_CALLS +extern int measurementFlag; +extern TASK_ID sysCallTaskID; +extern UINT32 tsFreq; + +enum kernelAPI +{ + openCall=0, + closeCall, + readCall, + writeCall, + sysCallMax, +}; + +typedef struct +{ + unsigned int sysCallCount; + unsigned long int execTimeUsec; +}KRNL_API_STATS; +KRNL_API_STATS API_STATS[sysCallMax]; +#endif /* this tells core I/O if the system is configured for PSE52 */ extern BOOL iosPse52Mode; @@ -591,7 +618,33 @@ int open int mode /* mode of file to create (UNIX chmod style) */ ) { - return (ioCreateOrOpen (name, flags, mode, FALSE)); + #ifdef MEASURE_SYS_CALLS + sysTimestampEnable(); + UINT32 startTick = 0, endTick = 0, diffTick = 0; + UINT64 timeUs = 0; + UINT32 freq = tsFreq; + char toMeasure = (measurementFlag && (sysCallTaskID == taskIdSelf())); + + if (toMeasure) + { + startTick = sysTimestamp(); + (API_STATS[openCall].sysCallCount)++; + } +#endif + + int result = ioCreateOrOpen(name, flags, mode, FALSE); + +#ifdef MEASURE_SYS_CALLS + if (toMeasure) + { + endTick = sysTimestamp(); + diffTick = endTick - startTick; + timeUs = ((UINT64)diffTick * 1000000ULL) / freq; + (API_STATS[openCall].execTimeUsec)+=timeUs; + } +#endif + + return result; } /******************************************************************************* @@ -1008,20 +1061,43 @@ int close ( int fd /* file descriptor to close */ ) - { - int ret; /* the real close return value */ - int krnPthreadCnclType; /* temp kernel canceltype saved value */ + { + int ret; /* the real close return value */ + int krnPthreadCnclType; /* temp kernel canceltype saved value */ - if (_func_pthread_testandset_canceltype != NULL) - _func_pthread_testandset_canceltype (PTHREAD_CANCEL_ASYNCHRONOUS, - &krnPthreadCnclType); +#ifdef MEASURE_SYS_CALLS + sysTimestampEnable(); + UINT32 startTick = 0, endTick = 0, diffTick = 0; + UINT64 timeUs = 0; + UINT32 freq = tsFreq; + char toMeasure = (measurementFlag && (sysCallTaskID == taskIdSelf())); - ret = iosClose (fd); + if (toMeasure) + { + startTick = sysTimestamp(); + (API_STATS[closeCall].sysCallCount)++; + } +#endif - if (_func_pthread_testandset_canceltype != NULL) - _func_pthread_testandset_canceltype (krnPthreadCnclType, NULL); + if (_func_pthread_testandset_canceltype != NULL) + _func_pthread_testandset_canceltype (PTHREAD_CANCEL_ASYNCHRONOUS, + &krnPthreadCnclType); - return (ret); + ret = iosClose (fd); + + if (_func_pthread_testandset_canceltype != NULL) + _func_pthread_testandset_canceltype (krnPthreadCnclType, NULL); + +#ifdef MEASURE_SYS_CALLS + if (toMeasure) + { + endTick = sysTimestamp(); + diffTick = endTick - startTick; + timeUs = ((UINT64)diffTick * 1000000ULL) / freq; + (API_STATS[closeCall].execTimeUsec)+=timeUs; + } +#endif + return (ret); } /*************************************************************************** @@ -1099,7 +1175,33 @@ ssize_t read return (0); } - return (ioReadWrite (iosRead, fd, buffer, maxBytes)); + ssize_t result; +#ifdef MEASURE_SYS_CALLS + sysTimestampEnable(); + UINT32 startTick = 0, endTick = 0, diffTick = 0; + UINT64 timeUs = 0; + UINT32 freq = tsFreq; + char toMeasure = (measurementFlag && (sysCallTaskID == taskIdSelf())); + + if (toMeasure) + { + startTick = sysTimestamp(); + (API_STATS[readCall].sysCallCount)++; + } +#endif + + result=(ioReadWrite (iosRead, fd, buffer, maxBytes)); + +#ifdef MEASURE_SYS_CALLS + if (toMeasure) + { + endTick = sysTimestamp(); + diffTick = endTick - startTick; + timeUs = ((UINT64)diffTick * 1000000ULL) / freq; + (API_STATS[readCall].execTimeUsec)+=timeUs; + } +#endif + return result; } @@ -1137,7 +1239,32 @@ ssize_t write size_t nBytes /* number of bytes to write */ ) { - return (ioReadWrite (iosWrite, fd, buffer, nBytes)); + ssize_t result; +#ifdef MEASURE_SYS_CALLS + sysTimestampEnable(); + UINT32 startTick = 0, endTick = 0, diffTick = 0; + UINT64 timeUs = 0; + UINT32 freq = tsFreq; + char toMeasure = (measurementFlag && (sysCallTaskID == taskIdSelf())); + + if (toMeasure) + { + startTick = sysTimestamp(); + (API_STATS[writeCall].sysCallCount)++; + } +#endif + result=(ioReadWrite (iosWrite, fd, buffer, nBytes)); + +#ifdef MEASURE_SYS_CALLS + if (toMeasure) + { + endTick = sysTimestamp(); + diffTick = endTick - startTick; + timeUs = ((UINT64)diffTick * 1000000ULL) / freq; + (API_STATS[writeCall].execTimeUsec)+=timeUs; + } +#endif + return result; } /******************************************************************************* diff --git a/vxworks-6.9/target/src/os/mm/memPartLib.c b/vxworks-6.9/target/src/os/mm/memPartLib.c index c58737f9..67943df6 100644 --- a/vxworks-6.9/target/src/os/mm/memPartLib.c +++ b/vxworks-6.9/target/src/os/mm/memPartLib.c @@ -429,6 +429,9 @@ may have to be updated if this implementation is modified: SEM_DELETE_SAFE | \ SEM_INVERSION_SAFE) +/* uncomment the below line to measure heap usage for 'enc' cmd */ +/* #define MEASURE_RUNTIME_HEAP */ + /* external references */ extern void * memPartReallocInternal (PART_ID partId, char * pBlock, @@ -1947,6 +1950,170 @@ memPartAllocError: * * SEE ALSO: memPartCreate(), malloc() */ +#ifdef MEASURE_RUNTIME_HEAP +typedef struct AllocEntry + { + void *ptr; /* Pointer returned by malloc */ + size_t size; /* Size allocated */ + struct AllocEntry *next; + } AllocEntry; + +static AllocEntry *tableHead = NULL; + + +static SEM_ID heapSemID; +static TASK_ID tShellID = NULL; +static unsigned long heapRuntimePeakAlloc = 0; +static unsigned long heapRuntimeNetTotalAlloc = 0; +static unsigned long totalHeapMemoryAlloc = 0; +static unsigned long totalHeapMemoryFreed = 0; + +/* Add entry to table */ +void addTableEntry + ( + void *ptr, + size_t size + ) + { + AllocEntry *entry = (AllocEntry *)malloc(sizeof(AllocEntry)); + + entry->ptr = ptr; + entry->size = size; + entry->next = tableHead; + tableHead = entry; + + totalHeapMemoryAlloc += size; + } + +/* Remove entry from table */ +void removeTableEntry + ( + void *ptr + ) + { + AllocEntry *curr = tableHead, *prev = NULL; + while (curr) + { + if (curr->ptr == ptr) + { + if (prev) + prev->next = curr->next; + else + tableHead = curr->next; + + totalHeapMemoryFreed += curr->size; + + free(curr); + + return; + } + prev = curr; + curr = curr->next; + } + } + +size_t getTotalAllocSize () + { + size_t size = 0; + AllocEntry *curr = tableHead; + + if (!curr) + return 0; + + while (curr) + { + size += curr->size; + curr = curr->next; + } + + return size; + } + +void getHeapRuntimeStat () + { + printf ("Peak Heap Usage : %u bytes\n", heapRuntimePeakAlloc); + printf ("Total Heap Allocated : %u bytes\n", totalHeapMemoryAlloc); + printf ("Total Heap Freed : %u bytes\n", totalHeapMemoryFreed); + } + +void resetHeapRuntimeCounter () + { + heapRuntimePeakAlloc = 0; + heapRuntimeNetTotalAlloc = 0; + totalHeapMemoryFreed = 0; + totalHeapMemoryAlloc = 0; + } + +void setTaskId + ( + TASK_ID tID + ) + { + tShellID = tID; + } + +void runHeapMeasurementTask + ( + const char* cmd, + const char* arg + ) + { + STATUS ret; + + semBTake (heapSemID, WAIT_FOREVER); + + ret = shellCmdExec (cmd, arg); + + if (ret != OK) + { + printf("runHeapMeasurementTask: Failed to execute command\n"); + return; + } + + printf ("Program completed successfully\n"); + } + +void getHeapUsage + ( + const char* cmd, + const char* arg + ) + { + TASK_ID tID; + STATUS ret; + + /* err check */ + if (!cmd || !arg) + { + printf ("getHeapUsage: Invalid parameter(s)\n"); + return; + } + + heapSemID = semBCreate (SEM_Q_FIFO, SEM_FULL); + if (!heapSemID) + { + printf ("getHeapUsage: Failed to create semaphore.\n"); + return; + } + + /* init semaphore */ + tID = taskSpawn ("tHeapUse", 30, 0, 10000, runHeapMeasurementTask, + cmd, arg, 0, 0, 0, 0, 0, 0, 0, 0); + + /* specify the task for which to measure the heap */ + setTaskId (tID); + + resetHeapRuntimeCounter (); + + semBGive (heapSemID); + + /* add some delay for the task to complete */ + taskDelay(sysClkRateGet()); + + getHeapRuntimeStat (); + } + +#endif /* MEASURE_RUNTIME_HEAP */ void * memPartAlloc ( @@ -1954,6 +2121,22 @@ void * memPartAlloc size_t nBytes /* number of bytes to allocate */ ) { + +#ifdef MEASURE_RUNTIME_HEAP + if (tShellID == taskIdSelf()) + { + if (nBytes > 0) + { + addTableEntry(partId, nBytes); + heapRuntimeNetTotalAlloc = getTotalAllocSize(); + + if ((heapRuntimeNetTotalAlloc > 0) && + (heapRuntimeNetTotalAlloc > heapRuntimePeakAlloc)) + heapRuntimePeakAlloc = heapRuntimeNetTotalAlloc; + } + } +#endif /* MEASURE_RUNTIME_HEAP */ + return (memPartAlignedAlloc (partId, nBytes, memDefaultAlignment)); } @@ -2020,6 +2203,16 @@ STATUS memPartFree retVal = memPartFreeInlined (partId, pBlock); +#ifdef MEASURE_RUNTIME_HEAP + if (retVal == OK) + { + if (tShellID == taskIdSelf()) + { + removeTableEntry (partId); + } + } +#endif /* MEASURE_RUNTIME_HEAP */ + #ifdef _WRS_CONFIG_SMP if ((partId != memSysPartId) && (REF_CNT_DEC (partId) == 1)) {