Skip to content

Add optional tracing to sleep manager lock/unlock #6142

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

Merged
merged 9 commits into from Mar 2, 2018
Merged

Add optional tracing to sleep manager lock/unlock #6142

merged 9 commits into from Mar 2, 2018

Conversation

ghost
Copy link

@ghost ghost commented Feb 20, 2018

Description

Add tracing output to console to track when drivers lock and unlock deep sleep. Tracing output is enabled by configuring the 'MBED_SLEEP_TRACING_ENABLED ' at compile time.

  • Wrapped sleep_manager_lock/sleep_manager_unlock in a macro to conditionally call tracing functions when 'MBED_SLEEP_TRACING_ENABLED' is set.
  • Define a global structure to track driver names and how many locks they hold in the sleep manager.

Status

IN DEVELOPMENT

Todos

  • Tests
  • Documentation

Steps to test or reproduce

Define the SLEEP_PROFILING_ENABLED macro in an application, eg:

{
  "config": {
    "sleep_profiling_enabled": {
      "value": 1,
      "macro_name": "SLEEP_PROFILING_ENABLED"
    }
  }
}

cause deep sleep to be locked/unlock by calling a driver that locks it:

void trigger(){}
int main()
{
  Timer* timer = new Timer();
  timer->start();

  Ticker* ticker = new Ticker();
  ticker->attach(&trigger, 500);

  sleep();
}

output should show:

LOCK: Timer.cpp, ln: 50, lock count: 1
LOCK: Ticker.h, ln: 120, lock count: 2
LOCK: mbed_rtx_idle.cpp, ln: 227, lock count: 3
UNLOCK: mbed_rtx_idle.cpp, ln: 229, lock count: 2
[id: Timer., count: 1]
[id: Ticker, count: 1]

@amq
Copy link
Contributor

amq commented Feb 20, 2018

It would be nice if the print function was configurable, so that e.g. tr_info() could be used instead of printf()

@0xc0170
Copy link
Contributor

0xc0170 commented Feb 21, 2018

It would be nice if the print function was configurable, so that e.g. tr_info() could be used instead of printf()

Had the same comment to be added here. @deepikabhavnani is working on tracing lib, but that might take a while. we have some logs in this codebase in some parts (not yet unified), but rather than own config would be easier to align this on something that it's been already used, then the new tracing lib would come and refactor this? @scartmell-arm please chat with @deepikabhavnani

@ghost
Copy link
Author

ghost commented Feb 21, 2018

Yes, the intention was to use the tracing library with this, which as far as I can tell should just require replacing the printfs with the trace macros/functions that get added.

@deepikabhavnani
Copy link

Printing filename and line number was part of the logging implementation and was removed recently for string based implementation, will that be required here?

@ghost
Copy link
Author

ghost commented Feb 21, 2018

The line number isn't important and the filename output isn't required as part of the interface. The FILE macro is used as an identifier to track which drivers have called the lock/unlock functions, so it isn't required as part of the interface as it's already accessible when printing the lock statistics.

@amq
Copy link
Contributor

amq commented Feb 22, 2018

For consistency across mbed-os, the macro could be named MBED_SLEEP_STATS_ENABLED, similarly to:

MBED_TRAP_ERRORS_ENABLED
MBED_HEAP_STATS_ENABLED
MBED_STACK_STATS_ENABLED

It would be also helpful if sleep_tracker_print_stats() could be used manually, otherwise there often may be an unmanagable stream of

LOCK: mbed_wait_api_rtos.cpp, ln: 42, lock count: 3
UNLOCK: mbed_wait_api_rtos.cpp, ln: 44, lock count: 2
[id: Timer., count: 1]
[id: Ticker, count: 1]

@bulislaw bulislaw requested review from senthilr and SenRamakri and removed request for senthilr February 26, 2018 08:52
Copy link
Member

@bulislaw bulislaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not actually sure why sleep manager lives in HAL, it's a driver. @SenRamakri do you think we could move it to drivers?

// Number of drivers that can be stored in the structure
#define STATISTIC_COUNT 10

typedef struct __PACKED sleep_statistic {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the __PACKED it doesn't make any difference here and generally I'm sceptical about use of packed structures, it may have negative effects on performance and put pressure on the bus with unaligned accesses.

sleep_tracker_unlock(__FILE__, __LINE__); \
} while (0);

void sleep_tracker_lock(const char *const filename, int line);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need it here?

Copy link

@deepikabhavnani deepikabhavnani Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's sort of the other way around, if you use serial then the deep sleep is disabled.

I am thinking of case, when no device/peripheral has locked deep sleep, so device can actually enter deep sleep.

  1. Last unlock, sleep_manager_unlock_deep_sleep_internal() - Counter goes down to zero.
  2. sleep_tracker_unlock(__FILE__, __LINE__); - This will enable UART.
  3. So it will lock deep sleep again unlock again.

Will this be recursive? Correct me if I am missing anything or interpreting it wrongly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like it could be an issue, but I've never seen it happen. I've not seen UART lock the deep sleep while running the tracker, perhaps it locks it through some other means.

@geky
Copy link
Contributor

geky commented Feb 26, 2018

We currently have a distinction between "tracing" and "stats". "Tracing" utilities continuously log data on relevant events, whereas "stats" utilities allow you to manually grab snapshots about the current state.

Looking at this pr, MBED_SLEEP_TRACING_ENABLED would probably be a better config name.


Building on @amq comment, it'd be useful to have the MBED_SLEEP_STATS_ENABLED side as well. If you're interested this would require adding a mbed_stats_deep_sleep_get sort of function that fills out a struct with relevant data. Here's the heap/stack stats for example:
https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_stats.h

This would be useful for tools that report stats on their own tick and profiling tests in the CI.

cc @kegilbert, @c1728p9

@@ -64,6 +64,34 @@ extern "C" {
* }
* @endcode
*/
#ifdef MBED_SLEEP_STATS_ENABLED

#define sleep_manager_lock_deep_sleep() \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How deep is sleep for peripherals at present? Do we disable clock for UART in any target device?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's sort of the other way around, if you use serial then the deep sleep is disabled. So this info is theoretical and @scartmell-arm will create a docs how to interpret that data.


printf("UNLOCK: %s, ln: %i, lock count: %u\r\n", stripped_path, line, deep_sleep_lock);
sleep_tracker_print_stats();
printf("\r\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this printf inside sleep_tracker_print_stats, makes it look cleaner.

do \
{ \
sleep_manager_lock_deep_sleep_internal(); \
sleep_tracker_lock(__FILE__, __LINE__); \
Copy link

@deepikabhavnani deepikabhavnani Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use __MODULE__ for ARM and __BASE_FILE__ for GCC_ARM instead of __FILE__ to get just filename without path details.

--no_path_in_file_macros option in IAR is to exclude path from __BASE_FILE__, but I have not tested that.

@bulislaw
Copy link
Member

bulislaw commented Feb 27, 2018

Building on @amq comment, it'd be useful to have the MBED_SLEEP_STATS_ENABLED side as well. If you're interested this would require adding a mbed_stats_deep_sleep_get sort of function that fills out a struct with relevant data. Here's the heap/stack stats for example:
https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_stats.h

This would be useful for tools that report stats on their own tick and profiling tests in the CI.

cc @kegilbert, @c1728p9

We are dangerously close to the code freeze, lets park this one for now.

@0xc0170 0xc0170 changed the title Added optional tracing to sleep manager lock/unlock Add optional tracing to sleep manager lock/unlock Feb 27, 2018
bulislaw
bulislaw previously approved these changes Feb 27, 2018
@bulislaw
Copy link
Member

Guys the code freeze is coming please rereview: @deepikabhavnani @SenRamakri @geky

@ghost
Copy link
Author

ghost commented Feb 28, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Feb 28, 2018

Build : SUCCESS

Build number : 1295
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6142/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build


static sleep_statistic_t sleep_stats[STATISTIC_COUNT];

static const char* strip_path(const char* const filename)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this runtime processing can be avoided, if we use proper compile time pre-processing macros (__MODULE__ for ARM and __BASE_FILE__ for GCC_ARM). Not blocking the release, but please update this in next PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine for ARM and GCC, but the only way to do it for IAR seems to be enabling --no_path_in_file_macros which seems excessive unless it can be applied selectively to this file.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--no_path_in_file_macros : I guess we will be adding this anyways in future for unified tracing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using filename can we use function name of the caller( the caller will pass __FUNCTION__ ), that will avoid all these processing as well, does that work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using __BASE_FILE__ would work better, it can be added when this is altered to use the tracing.

Using __FUNCTION__ might be problematic. The names of the functions that call lock and unlock are going to be different so tracking which unlock is associated with each lock would be complicated, multiple drivers are also likely to have the same function names that lock/unlock the sleep manager, and it's difficult to identify which driver locked the sleep manager based on the function name alone

@mbed-ci
Copy link

mbed-ci commented Feb 28, 2018

@mbed-ci
Copy link

mbed-ci commented Feb 28, 2018

@ghost
Copy link
Author

ghost commented Mar 1, 2018

Heh, should all be sorted now, as indicated fixing merge conflicts is not my forte.

@ghost
Copy link
Author

ghost commented Mar 1, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Mar 1, 2018

Build : SUCCESS

Build number : 1316
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6142/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@cmonr
Copy link
Contributor

cmonr commented Mar 1, 2018

@bulislaw Is the intention for this to make it into 5.8-rc1? I'm reading conflicting message from you:
#6142 (comment) vs #6142 (comment)
Marking this as 5.8 for now.

@scartmell-arm A friendly reminder that only maintainers should be triggering builds, especially this close to generating a release PR.

@cmonr
Copy link
Contributor

cmonr commented Mar 1, 2018

@scartmell-arm Do you run tests or at least do a sanity compilation in between commits? I'm wondering how those merge errors got into the history in the first place, especially since they're so far apart from each other (2 days vs 6 days).

@ghost
Copy link
Author

ghost commented Mar 1, 2018

@cmonr No, I rebased all seven commits about 1-2 hours ago, the merge conflict happened in one of the earlier ones and I forgot to commit the manual merge before continuing. The conflict only happened ~3 hours ago when #6230 got merged and the file I was committing to got moved around.

@mbed-ci
Copy link

mbed-ci commented Mar 1, 2018

@bulislaw
Copy link
Member

bulislaw commented Mar 1, 2018

Yes, it's 5.8 the #6142 (comment) was about Chrises comment and adding extra features.

@cmonr
Copy link
Contributor

cmonr commented Mar 1, 2018

@bulislaw @sg- @deepikabhavnani @SenRamakri @geky @c1728p9 Any final words on this PR while there's still a chance?

core_util_atomic_decr_u8(&stat->count, 1);

printf("UNLOCK: %s, ln: %i, lock count: %u\r\n", stripped_path, line, deep_sleep_lock);
sleep_tracker_print_stats();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its an overkill to print the stats on every unlock call, particularly when we are printing the LOCK/UNLOCK info in the sleep_tracker_lock/unlock calls. But, I'm not going to block this PR for that as its not a major blocker, but you may want to re-think on that.

SenRamakri
SenRamakri previously approved these changes Mar 1, 2018
@mbed-ci
Copy link

mbed-ci commented Mar 1, 2018


core_util_atomic_incr_u8(&stat->count, 1);

printf("LOCK: %s, ln: %i, lock count: %u\r\n", stripped_path, line, deep_sleep_lock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this printf and not debug? If debug it could be stripped from a release build.


core_util_atomic_decr_u8(&stat->count, 1);

printf("UNLOCK: %s, ln: %i, lock count: %u\r\n", stripped_path, line, deep_sleep_lock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this printf and not debug? If debug it could be stripped from a release build.

@bulislaw
Copy link
Member

bulislaw commented Mar 2, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Mar 2, 2018

Build : SUCCESS

Build number : 1319
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6142/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Mar 2, 2018

@mbed-ci
Copy link

mbed-ci commented Mar 2, 2018

Copy link
Author

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@adbridge adbridge self-requested a review March 2, 2018 10:52
Copy link
Contributor

@adbridge adbridge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the review comments have been completed and Steve has approved them. Thus approving this PR overall in order to merge.

@adbridge adbridge merged commit a137444 into ARMmbed:master Mar 2, 2018
@mbed-ci
Copy link

mbed-ci commented Aug 2, 2018

@ghost ghost deleted the feature-deep-sleep-tracing branch December 5, 2018 16:48
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.

10 participants