Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2358, adds TIME module command to set CFE_TIME_Print() format #2370

Closed
wants to merge 1 commit into from

Conversation

CDKnightNASA
Copy link
Contributor

Checklist (Please check before submitting)

Describe the contribution
Adds a CFE TIME command to configure how to print time information, mostly used by CFE_EVS to print to stdout, and CFE ES for writing to syslog.

Testing performed
Build and test using standard cFE coverage tests which have been updated to test different formats and error conditions.

Expected behavior changes
Enhances CFE_TIME_Print() function and allows for more concise and helpful timestamps.

System(s) tested on
Ubuntu 23 desktop VM.

Contributor Info - All information REQUIRED for consideration of pull request
Christopher.D.Knight@nasa.gov

@CDKnightNASA CDKnightNASA self-assigned this Jun 7, 2023
@@ -98,6 +98,8 @@
static const UT_TaskPipeDispatchId_t UT_TPID_CFE_TIME_INVALID_MID = {.MsgId = CFE_SB_MSGID_RESERVED, .CommandCode = 0};
static const UT_TaskPipeDispatchId_t UT_TPID_CFE_TIME_CMD_INVALID_CC = {
.MsgId = CFE_SB_MSGID_WRAP_VALUE(CFE_TIME_CMD_MID), .CommandCode = 0x7F};
static const UT_TaskPipeDispatchId_t UT_TPID_CFE_TIME_SET_PRINT_CC = {

Check notice

Code scanning / CodeQL

Variable scope too large

The variable UT_TPID_CFE_TIME_SET_PRINT_CC is only accessed in [Test_PipeCmds](1) and should be scoped accordingly.
@@ -240,6 +240,13 @@
}
break;

case CFE_TIME_SET_PRINT_CC:
if (CFE_TIME_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_TIME_SetPrintCmd_t)))

Check warning

Code scanning / CodeQL

Side effect in a Boolean expression

This Boolean expression is not side-effect free.
Comment on lines +592 to +632
while(*FmtPtr != '\0' && OutChrs < CFE_TIME_PRINTED_STRING_SIZE)
{
/* if we have "%f", call strftime for string before and string after */
PctF = strstr(FmtBuf, "%f");
if (PctF)
{
*PctF = '\0'; /* blot out "%f", for now */
}

TimeSz = strftime(PrintBuffer + OutChrs, CFE_TIME_PRINTED_STRING_SIZE - OutChrs, FmtPtr, &tm);

if (*FmtPtr && TimeSz == 0)
{
/* strftime returns 0 if the buffer is too small */
return CFE_TIME_FORMAT_TOO_LONG;
}

OutChrs += TimeSz;

/* we found/blotted %f above */
if (PctF)
{
/* write %f value */
if (OutChrs < CFE_TIME_PRINTED_STRING_SIZE - 5)
{
OutChrs += snprintf(PrintBuffer + OutChrs, CFE_TIME_PRINTED_STRING_SIZE - OutChrs, "%05d", mic);
}
else
{
return CFE_TIME_FORMAT_TOO_LONG;
}

/* go back through the loop with the remaining format */
FmtPtr = PctF + 2;
}
else
{
PrintBuffer[OutChrs] = '\0'; /* just in case, null-terminate the string */
break; /* break while */
}
}

Check warning

Code scanning / CodeQL

Unbounded loop

The loop counter OutChrs is not always incremented in the loop body.
Comment on lines +585 to +641
switch (CFE_TIME_Global.PrintState)
{
case CFE_TIME_PrintState_DateTime:
gmtime_r(&sec, &tm);

strncpy(FmtPtr, CFE_TIME_Global.PrintFormat, CFE_TIME_FORMAT_SIZE);

while(*FmtPtr != '\0' && OutChrs < CFE_TIME_PRINTED_STRING_SIZE)
{
/* if we have "%f", call strftime for string before and string after */
PctF = strstr(FmtBuf, "%f");
if (PctF)
{
*PctF = '\0'; /* blot out "%f", for now */
}

TimeSz = strftime(PrintBuffer + OutChrs, CFE_TIME_PRINTED_STRING_SIZE - OutChrs, FmtPtr, &tm);

if (*FmtPtr && TimeSz == 0)
{
/* strftime returns 0 if the buffer is too small */
return CFE_TIME_FORMAT_TOO_LONG;
}

OutChrs += TimeSz;

/* we found/blotted %f above */
if (PctF)
{
/* write %f value */
if (OutChrs < CFE_TIME_PRINTED_STRING_SIZE - 5)
{
OutChrs += snprintf(PrintBuffer + OutChrs, CFE_TIME_PRINTED_STRING_SIZE - OutChrs, "%05d", mic);
}
else
{
return CFE_TIME_FORMAT_TOO_LONG;
}

/* go back through the loop with the remaining format */
FmtPtr = PctF + 2;
}
else
{
PrintBuffer[OutChrs] = '\0'; /* just in case, null-terminate the string */
break; /* break while */
}
}
break;
case CFE_TIME_PrintState_SecsSinceStart:
OutChrs += snprintf(PrintBuffer, CFE_TIME_PRINTED_STRING_SIZE, "%ld.%06d", (long int)sec, mic);
PrintBuffer[OutChrs] = '\0';
break;
default:
PrintBuffer[0] = '\0';
break;
}

Check notice

Code scanning / CodeQL

Long switch case

Switch has at least one case that is too long: [CFE_TIME_PrintState_DateTime (46 lines)](1).
@chillfig chillfig added the CCB:Ready Ready for discussion at the Configuration Control Board (CCB) label Jun 8, 2023
@CDKnightNASA CDKnightNASA removed the CCB:Ready Ready for discussion at the Configuration Control Board (CCB) label Jun 8, 2023
@CDKnightNASA CDKnightNASA changed the title fix#2358, adds TIME module command to set CFE_TIME_Print() format Fix #2358, adds TIME module command to set CFE_TIME_Print() format Jun 8, 2023
@CDKnightNASA CDKnightNASA marked this pull request as ready for review June 8, 2023 19:29
@CDKnightNASA CDKnightNASA added the CCB:Ready Ready for discussion at the Configuration Control Board (CCB) label Jun 8, 2023
@CDKnightNASA
Copy link
Contributor Author

Two issues raised in the CCB:

  1. "%%f" would not work properly (should be replaced with "%f" in the formatted string.)
  2. strstr is fairly expensive, is there a more efficient way?
    a) remove the "%f" logic and have a flag in CFE_TIME_Global to tack microseconds at the end.
    b) do a one-time scan (at startup, at command) to set offset(s) for the %f(s)

@CDKnightNASA CDKnightNASA added Equuleus-rc2 and removed CCB:Ready Ready for discussion at the Configuration Control Board (CCB) labels Jun 22, 2023
@chillfig
Copy link
Contributor

chillfig commented Sep 7, 2023

CCB 09/07/2023: Dan plans to run tests and this pr will be considered to be merged next week

@dmknutsen
Copy link
Contributor

I was able to perform some initial testing and think we are on track to merge into Equuleus-rc2. I did run into a couple issues that I would like to resolve prior to merging:

  1. We should make the default format backward compatible with the existing timestamp (there was a '-' removed between the Julian Day and Hour)
  2. Because CFE_TIME_Print is called so often - I'd like to benchmark the new logic/while loop against a GR712 (which we are currently setting up in the cFS lab or CI/CD + bench-marking performance) to make sure there are not performance implications.
  3. We will need to submit a separate PR to ensure that the example mission and platform config files are kept in sync (we added those toward the end of the Equuleus-rc1 dev cycle to demonstrate backward compatibility).
  4. I'm seeing timestamp corruption prior to cFE_TIME initialization (after which they are fine). I'd like to understand if that is an actual bug or if it is related to how I merged the PR into my test environment.

@chillfig
Copy link
Contributor

chillfig commented Nov 9, 2023

CCB: 11-9-2023: put on hold

@dzbaker
Copy link
Collaborator

dzbaker commented Nov 30, 2023

CCB 30 November 2023: Going to run performance tests to make sure that changes don't result in a performance hit. Afterwards, backwards compatibility issues will be fixed.

@dmknutsen
Copy link
Contributor

@CDKnightNASA - I set up a test to benchmark this against a GR712 running RTEMS 5. During the test, I called CFE_TIME_Print 10,000 times to see how long it takes with and without the patch. I ran the test three times to get an average.

Without patch:
EVS Port1 1980-012-14:03:27.26382 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013326 usec
EVS Port1 1980-012-14:03:27.25918 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013291 usec
EVS Port1 1980-012-14:03:27.27995 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013685 usec

With patch:
EVS Port1 1980-012 14:03:27.53286 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1312445 usec
EVS Port1 1980-012 14:03:27.56680 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1313442 usec
EVS Port1 1980-012 14:03:27.54457 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1313067 usec

Against the GR712, the time to execute CFE_TIME_Print is 28% slower with the patch - which i do not believe is cause for concern. In this case, the enhanced functionality is most likely worth the performance trade. In practice the performance loss will be negligible as CFE_TIME_Print should never be called at a rate where this loss would be noticeable/impactful.

Lets plan to discuss/get concurrence at the next CCB.

@CDKnightNASA
Copy link
Contributor Author

@CDKnightNASA - I set up a test to benchmark this against a GR712 running RTEMS 5. During the test, I called CFE_TIME_Print 10,000 times to see how long it takes with and without the patch. I ran the test three times to get an average.

Without patch: EVS Port1 1980-012-14:03:27.26382 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013326 usec EVS Port1 1980-012-14:03:27.25918 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013291 usec EVS Port1 1980-012-14:03:27.27995 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1013685 usec

With patch: EVS Port1 1980-012 14:03:27.53286 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1312445 usec EVS Port1 1980-012 14:03:27.56680 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1313442 usec EVS Port1 1980-012 14:03:27.54457 66/1/CFE_TEST_APP 5: [ MIR] 01.005 time_misc_test.c:66 - Elapsed time for Time Print test: 1313067 usec

Against the GR712, the time to execute CFE_TIME_Print is 28% slower with the patch - which i do not believe is cause for concern. In this case, the enhanced functionality is most likely worth the performance trade. In practice the performance loss will be negligible as CFE_TIME_Print should never be called at a rate where this loss would be noticeable/impactful.

Lets plan to discuss/get concurrence at the next CCB.

As mentioned in the Teams chat, I think that the performance impact is significant enough to pull this PR. Missions can, instead, just modify the code so that they get the output format they prefer with less/zero impact. But I will await the CCB's decision and will implement suggested changes if the consensus is that the PR is worthwhile even with the performance impact.

@dzbaker
Copy link
Collaborator

dzbaker commented Jan 4, 2024

CCB 4 January 2024: Determined that formatting can be applied at compile-time.

@dzbaker dzbaker closed this Jan 4, 2024
@CDKnightNASA CDKnightNASA deleted the fix-2358-evs_fmt branch January 4, 2024 19:24
@CDKnightNASA CDKnightNASA restored the fix-2358-evs_fmt branch January 4, 2024 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants