49 #if defined(BOARD_DMA_ALLOC_POOL_SIZE) 50 #include <px4_platform/board_dma_alloc.h> 53 #if defined(CONFIG_SCHED_INSTRUMENTATION) 55 #if !defined(CONFIG_TASK_NAME_SIZE) 56 #error print_load_nuttx requires CONFIG_TASK_NAME_SIZE 59 #if !defined(CONFIG_STACK_COLORATION) 60 #error print_load_nuttx requires CONFIG_STACK_COLORATION 65 #define CL "\033[K" // clear line 89 case TSTATE_TASK_INVALID:
92 case TSTATE_TASK_PENDING:
95 case TSTATE_TASK_READYTORUN:
98 case TSTATE_TASK_RUNNING:
101 case TSTATE_TASK_INACTIVE:
104 case TSTATE_WAIT_SEM:
106 #ifndef CONFIG_DISABLE_SIGNALS 108 case TSTATE_WAIT_SIG:
111 #ifndef CONFIG_DISABLE_MQUEUE 113 case TSTATE_WAIT_MQNOTEMPTY:
116 case TSTATE_WAIT_MQNOTFULL:
121 case TSTATE_WAIT_PAGEFILL:
133 #pragma GCC diagnostic push 134 #pragma GCC diagnostic ignored "-Wformat" // NuttX uses a different printf format 135 #pragma GCC diagnostic ignored "-Wformat-extra-args" 139 uint64_t curr_time_us;
140 uint64_t idle_time_us;
141 float idle_load = 0.f;
150 snprintf(buffer, buffer_length,
"%4s %-*s %8s %6s %11s %10s %-5s %2s",
152 CONFIG_TASK_NAME_SIZE,
"COMMAND",
157 #
if CONFIG_RR_INTERVAL > 0
176 total_runtime[i] = (uint32_t)(
system_load.tasks[i].total_runtime / 1000);
188 uint64_t interval_runtime;
190 size_t stack_size =
system_load.tasks[i].tcb->adj_stack_size;
191 ssize_t stack_free = 0;
192 char tcb_name[CONFIG_TASK_NAME_SIZE + 1];
193 strncpy(tcb_name,
system_load.tasks[i].tcb->name, CONFIG_TASK_NAME_SIZE + 1);
195 #if CONFIG_ARCH_INTERRUPTSTACK > 3 198 stack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
199 stack_free = up_check_intstack_remain();
202 stack_free = up_check_tcbstack_remain(
system_load.tasks[i].tcb);
206 stack_free = up_check_tcbstack_remain(
system_load.tasks[i].tcb);
209 #if CONFIG_ARCH_BOARD_SIM || !defined(CONFIG_PRIORITY_INHERITANCE) 211 unsigned tcb_base_priority =
system_load.tasks[i].tcb->base_priority;
213 #if CONFIG_RR_INTERVAL > 0 214 unsigned tcb_timeslice =
system_load.tasks[i].tcb->timeslice;
216 unsigned tcb_task_state =
system_load.tasks[i].tcb->task_state;
217 unsigned tcb_sched_priority =
system_load.tasks[i].tcb->sched_priority;
219 unsigned int tcb_num_used_fds = 0;
220 #if CONFIG_NFILE_DESCRIPTORS > 0 221 FAR
struct task_group_s *group =
system_load.tasks[i].tcb->group;
224 for (
int fd_index = 0; fd_index < CONFIG_NFILE_DESCRIPTORS; ++fd_index) {
225 if (group->tg_filelist.fl_files[fd_index].f_inode) {
235 switch (tcb_task_state) {
236 case TSTATE_TASK_PENDING:
237 case TSTATE_TASK_READYTORUN:
238 case TSTATE_TASK_RUNNING:
242 #ifndef CONFIG_DISABLE_SIGNALS 244 case TSTATE_WAIT_SIG:
246 #ifndef CONFIG_DISABLE_MQUEUE 247 case TSTATE_WAIT_MQNOTEMPTY:
248 case TSTATE_WAIT_MQNOTFULL:
251 case TSTATE_WAIT_PAGEFILL:
253 case TSTATE_TASK_INVALID:
254 case TSTATE_TASK_INACTIVE:
255 case TSTATE_WAIT_SEM:
260 interval_runtime = (print_state->
last_times[i] > 0 && total_runtime[i] > print_state->
last_times[i])
261 ? (total_runtime[i] - print_state->
last_times[i]) : 0;
263 print_state->
last_times[i] = total_runtime[i];
265 float current_load = 0.f;
274 idle_load = current_load;
285 int print_len = snprintf(buffer, buffer_length,
"%4d %-*s %8d %2d.%03d %5u/%5u %3u (%3u) ",
287 CONFIG_TASK_NAME_SIZE, tcb_name,
289 (
int)(current_load * 100.0
f),
290 (
int)((current_load * 100.0f - (
int)(current_load * 100.0f)) * 1000),
291 stack_size - stack_free,
294 #
if CONFIG_ARCH_BOARD_SIM || !defined(CONFIG_PRIORITY_INHERITANCE)
299 #if CONFIG_RR_INTERVAL > 0 301 snprintf(buffer + print_len, buffer_length - print_len,
" %5d %2d", tcb_timeslice, tcb_num_used_fds);
305 snprintf(buffer + print_len, buffer_length - print_len,
" %-5s %2d",
tstate_name(tcb_task_state), tcb_num_used_fds);
325 if (task_load > (1.f - idle_load)) {
326 task_load = (1.f - idle_load);
329 sched_load = 1.f - idle_load - task_load;
331 snprintf(buffer, buffer_length,
"Processes: %d total, %d running, %d sleeping, max FDs: %d",
335 CONFIG_NFILE_DESCRIPTORS);
337 snprintf(buffer, buffer_length,
"CPU usage: %.2f%% tasks, %.2f%% sched, %.2f%% idle",
338 (
double)(task_load * 100.f),
339 (
double)(sched_load * 100.f),
340 (
double)(idle_load * 100.f));
342 #if defined(BOARD_DMA_ALLOC_POOL_SIZE) 345 uint16_t dma_peak_used;
347 if (board_get_dma_usage(&dma_total, &dma_used, &dma_peak_used) >= 0) {
348 snprintf(buffer, buffer_length,
"DMA Memory: %d total, %d used %d peak",
356 snprintf(buffer, buffer_length,
"Uptime: %.3fs total, %.3fs idle",
357 (
double)curr_time_us / 1000000.d,
358 (
double)idle_time_us / 1000000.d);
363 #pragma GCC diagnostic pop 367 struct print_load_callback_data_s {
372 static void print_load_callback(
void *user)
374 char *clear_line =
"";
375 struct print_load_callback_data_s *
data = (
struct print_load_callback_data_s *)user;
381 dprintf(data->fd,
"%s%s\n", clear_line, data->buffer);
388 dprintf(fd,
"\033[H");
391 struct print_load_callback_data_s data;
395 print_load_buffer(t, data.buffer,
sizeof(data.buffer), print_load_callback, &data, print_state);
398 #endif // if CONFIG_SCHED_INSTRUMENTATION
void init_print_load_s(uint64_t t, struct print_load_s *s)
High-resolution timer with callouts and timekeeping.
void(* print_load_callback_f)(void *user)
Print the current system load.
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
struct system_load_s system_load
float interval_time_ms_inv
void print_load_buffer(uint64_t t, char *buffer, int buffer_length, print_load_callback_f cb, void *user, struct print_load_s *print_state)
Print load to a buffer, and call cb after each written line (buffer will not include ' ') ...
uint64_t interval_start_time
void print_load(uint64_t t, int fd, struct print_load_s *print_state)
uint32_t last_times[CONFIG_MAX_TASKS]
static const char * tstate_name(const tstate_t s)