rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
panel_perf.c File Reference

The PSRAM probe at start-up, the frame times, and the lows of every stack and of the internal heap (panel_perf.h). More...

#include "panel_perf.h"
#include <stdatomic.h>
#include <stdint.h>
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "display.h"
#include "gfx.h"
#include "panel.h"
#include "perf_watch.h"
#include "ui_screen.h"

Macros

#define PERF_SCAN_WINDOWS   6u
 Rate lines between two stack scans: 30s at 60.4fps.

Functions

void perf_probe_psram (void)
 Time the clears of the back buffer and log one's time (panel_perf.h).
static UBaseType_t task_room (void)
 Room in s_tasks and s_names for every task now and 8 more, from PSRAM.
static bool scan_stacks (void)
 Read every task's stack high-water mark into the table of lows.
static void note_heap (void)
 Note the internal heap's lowest free figure; its line is due when it fell.
static void rate_line (uint32_t draw_us)
 Print the rate line: fps, the last frame's DRAW, WAIT and TURN, the panel's VSYNC rate since the last one, and the counts.
static void window_line (void)
 Print the window the last rate line closed, if one waits.
static void low_line (void)
 Print one due line of the lows: the scan's time, then the heap, then the first stack due; nothing when none is due.
void perf_frame (int screen, uint32_t draw_us, bool flip_timed_out, bool quiet)
 Account one frame and print the line due after it (panel_perf.h).

Variables

static const char * TAG = "rcbench"
 The log tag of the panel's own lines.
static perf_lows_t s_stacks
 Every task's least free stack, as last noted.
static uint32_t s_heap_low = UINT32_MAX
 The internal heap's lowest free figure, as last noted, B.
static bool s_heap_due
 Whether the heap line is due.
static uint32_t s_scan_us_max
 The longest stack scan so far, us; its line is due when it grows.
static UBaseType_t s_scan_due_tasks
 Tasks the longest scan read; 0 while its line is not due.
static bool s_scan_wanted = true
 Whether a stack scan waits for a frame it may run on.
static uint32_t s_since_scan
 Rate lines since the last stack scan.
static TaskStatus_t * s_tasks
 The task list uxTaskGetSystemState() fills, in PSRAM.
static char(* s_names )[PERF_LOWS_NAME]
 Each task's name, copied out of s_tasks right after the scan.
static UBaseType_t s_task_room
 Room in s_tasks and s_names, in tasks.
static bool s_started
 Whether perf_frame() has seen its first frame.
static uint32_t s_frames
 Frames since the loop started.
static uint32_t s_flip_timeouts
 The flips since start-up that timed out.
static uint32_t s_last_vs
 VSYNC count and time at the last rate line.
static uint32_t s_last_vs_us
 The time of s_last_vs, us.
static perf_window_t s_window
 The frames since the last rate line, on one screen.
static perf_window_t s_closed
 The window the last rate line closed, for the window line; no frames when none waits.

Detailed Description

The PSRAM probe at start-up, the frame times, and the lows of every stack and of the internal heap (panel_perf.h).

Compiled with RCBENCH_PERF_LOG only. The lines, as docs/Performance.md quotes them:

PSRAM probe: 4 clears of 1228800B in <n> us, <n> us each
<f> fps  DRAW <n> us  WAIT <n> us  TURN <n> us  VSYNC <f> Hz  FLIP TIMEOUTS <n>  TOUCHLOST <n>/<n>
frames <n> on <title> #<id>: DRAW <min>/<mean>/<max> WAIT <...> TURN <...> us
stack scan: <n> tasks in <n> us
stack <task>: <n> B never used
internal RAM: <n> B free at the lowest, <n> B free now, largest block <n> B

SPDX-License-Identifier: MIT

Function Documentation

◆ perf_frame()

void perf_frame ( int screen,
uint32_t draw_us,
bool flip_timed_out,
bool quiet )

Account one frame and print the line due after it (panel_perf.h).

Parameters
screenThe screen the frame drew.
draw_usThe frame's paint time, us.
flip_timed_outWhether its flip timed out.
quietWhether the stack scan may run.

◆ rate_line()

void rate_line ( uint32_t draw_us)
static

Print the rate line: fps, the last frame's DRAW, WAIT and TURN, the panel's VSYNC rate since the last one, and the counts.

Parameters
draw_usThe last frame's paint time, us.

◆ scan_stacks()

bool scan_stacks ( void )
static

Read every task's stack high-water mark into the table of lows.

uxTaskGetSystemState() reads all of them in one critical section: this core's interrupts are masked and the kernel lock is held while it scans each task's unused stack, so a kernel call on the other core waits for it. The time is logged; the scan runs on a quiet frame only.

The status it fills points at each task's name in the task's control block, which a task that ends after the lock is released frees. The names are copied at once, at most PERF_LOWS_NAME - 1 bytes each, a task waiting for its clean-up is skipped, and the scan counts only if the number of tasks after the copy is the number the scan read: FreeRTOS lowers the count under the kernel lock before it frees a control block, so a block freed before or during the copy shows as a lower count.

Returns
true when the scan counted; false when there was no room or a task ended during it, and the next rate line tries again.

◆ task_room()

UBaseType_t task_room ( void )
static

Room in s_tasks and s_names for every task now and 8 more, from PSRAM.

Returns
The room, in tasks; 0 when the heap has none.