kernel: use timing functions to gather thread runtime stats
This uses the timing functions to gather execution cycles of threads. This provides greater details if arch/SoC/board uses timer with higher resolution. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
11e6b43090
commit
fd7a68dbe9
4 changed files with 48 additions and 2 deletions
|
@ -19,6 +19,10 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
#include <timing/timing.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -283,14 +287,22 @@ struct z_poller {
|
||||||
#ifdef CONFIG_THREAD_RUNTIME_STATS
|
#ifdef CONFIG_THREAD_RUNTIME_STATS
|
||||||
struct k_thread_runtime_stats {
|
struct k_thread_runtime_stats {
|
||||||
/* Thread execution cycles */
|
/* Thread execution cycles */
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
timing_t execution_cycles;
|
||||||
|
#else
|
||||||
uint64_t execution_cycles;
|
uint64_t execution_cycles;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct k_thread_runtime_stats k_thread_runtime_stats_t;
|
typedef struct k_thread_runtime_stats k_thread_runtime_stats_t;
|
||||||
|
|
||||||
struct _thread_runtime_stats {
|
struct _thread_runtime_stats {
|
||||||
/* Timestamp when last switched in */
|
/* Timestamp when last switched in */
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
timing_t last_switched_in;
|
||||||
|
#else
|
||||||
uint32_t last_switched_in;
|
uint32_t last_switched_in;
|
||||||
|
#endif
|
||||||
|
|
||||||
k_thread_runtime_stats_t stats;
|
k_thread_runtime_stats_t stats;
|
||||||
};
|
};
|
||||||
|
|
|
@ -355,7 +355,7 @@ config THREAD_MAX_NAME_LEN
|
||||||
config INSTRUMENT_THREAD_SWITCHING
|
config INSTRUMENT_THREAD_SWITCHING
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config THREAD_RUNTIME_STATS
|
menuconfig THREAD_RUNTIME_STATS
|
||||||
bool "Thread runtime statistics"
|
bool "Thread runtime statistics"
|
||||||
select INSTRUMENT_THREAD_SWITCHING
|
select INSTRUMENT_THREAD_SWITCHING
|
||||||
help
|
help
|
||||||
|
@ -364,6 +364,19 @@ config THREAD_RUNTIME_STATS
|
||||||
For example:
|
For example:
|
||||||
- Thread total execution cycles
|
- Thread total execution cycles
|
||||||
|
|
||||||
|
if THREAD_RUNTIME_STATS
|
||||||
|
|
||||||
|
config THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
bool "Use timing functions to gather statistics"
|
||||||
|
select TIMING_FUNCTIONS
|
||||||
|
help
|
||||||
|
Use timing functions to gather thread runtime statistics.
|
||||||
|
|
||||||
|
Note that timing functions may use a different timer than
|
||||||
|
the default timer for OS timekeeping.
|
||||||
|
|
||||||
|
endif # THREAD_RUNTIME_STATS
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Work Queue Options"
|
menu "Work Queue Options"
|
||||||
|
|
|
@ -480,6 +480,11 @@ FUNC_NORETURN void z_cstart(void)
|
||||||
__stack_chk_guard <<= 8;
|
__stack_chk_guard <<= 8;
|
||||||
#endif /* CONFIG_STACK_CANARIES */
|
#endif /* CONFIG_STACK_CANARIES */
|
||||||
|
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
timing_init();
|
||||||
|
timing_start();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MULTITHREADING
|
#ifdef CONFIG_MULTITHREADING
|
||||||
switch_to_main_thread(prepare_multithreading());
|
switch_to_main_thread(prepare_multithreading());
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1036,14 +1036,24 @@ void z_thread_mark_switched_in(void)
|
||||||
struct k_thread *thread;
|
struct k_thread *thread;
|
||||||
|
|
||||||
thread = k_current_get();
|
thread = k_current_get();
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
thread->rt_stats.last_switched_in = timing_counter_get();
|
||||||
|
#else
|
||||||
thread->rt_stats.last_switched_in = k_cycle_get_32();
|
thread->rt_stats.last_switched_in = k_cycle_get_32();
|
||||||
|
#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */
|
||||||
|
|
||||||
#endif /* CONFIG_THREAD_RUNTIME_STATS */
|
#endif /* CONFIG_THREAD_RUNTIME_STATS */
|
||||||
}
|
}
|
||||||
|
|
||||||
void z_thread_mark_switched_out(void)
|
void z_thread_mark_switched_out(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_THREAD_RUNTIME_STATS
|
#ifdef CONFIG_THREAD_RUNTIME_STATS
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
timing_t now;
|
||||||
|
#else
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
|
#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */
|
||||||
|
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
struct k_thread *thread;
|
struct k_thread *thread;
|
||||||
|
|
||||||
|
@ -1059,10 +1069,16 @@ void z_thread_mark_switched_out(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS
|
||||||
|
now = timing_counter_get();
|
||||||
|
diff = timing_cycles_get(&thread->rt_stats.last_switched_in, &now);
|
||||||
|
#else
|
||||||
now = k_cycle_get_32();
|
now = k_cycle_get_32();
|
||||||
diff = (uint64_t)now - thread->rt_stats.last_switched_in;
|
diff = (uint64_t)now - thread->rt_stats.last_switched_in;
|
||||||
thread->rt_stats.stats.execution_cycles += diff;
|
|
||||||
thread->rt_stats.last_switched_in = 0;
|
thread->rt_stats.last_switched_in = 0;
|
||||||
|
#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */
|
||||||
|
|
||||||
|
thread->rt_stats.stats.execution_cycles += diff;
|
||||||
|
|
||||||
threads_runtime_stats.execution_cycles += diff;
|
threads_runtime_stats.execution_cycles += diff;
|
||||||
#endif /* CONFIG_THREAD_RUNTIME_STATS */
|
#endif /* CONFIG_THREAD_RUNTIME_STATS */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue