mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
Dumping all the DDR takes significant time and there's currently no user-visible feedback provided to indicate that even the process has started. Solve this by wiring up the ux module and provide a progress bar while dumping segments, as well as information as the segments are skipped or dumped. Add missing ux_init() to the ramdump setup, and make sure to clamp value to max in the progress calculation, to avoid funky issues when progress is made beyond the size of the chunk. Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
175 lines
3.3 KiB
C
175 lines
3.3 KiB
C
// SPDX-License-Identifier: BSD-3-Clause
|
|
#include <stdarg.h>
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#else
|
|
#include <sys/ioctl.h>
|
|
#endif
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "qdl.h"
|
|
|
|
#define UX_PROGRESS_REFRESH_RATE 10
|
|
#define UX_PROGRESS_SIZE_MAX 80
|
|
|
|
#define HASHES "################################################################################"
|
|
#define DASHES "--------------------------------------------------------------------------------"
|
|
|
|
static const char * const progress_hashes = HASHES;
|
|
static const char * const progress_dashes = DASHES;
|
|
|
|
static unsigned int ux_width;
|
|
static unsigned int ux_cur_line_length;
|
|
|
|
/*
|
|
* Levels of output:
|
|
*
|
|
* error: used to signal errors to the user
|
|
* info: used to inform the user about progress
|
|
* logs: log prints from the device
|
|
* debug: protocol logs
|
|
*/
|
|
|
|
/* Clear ux_cur_line_length characters of the progress bar from the screen */
|
|
static void ux_clear_line(void)
|
|
{
|
|
if (!ux_cur_line_length)
|
|
return;
|
|
|
|
printf("%*s\r", ux_cur_line_length, "");
|
|
fflush(stdout);
|
|
ux_cur_line_length = 0;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
void ux_init(void)
|
|
{
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
int columns;
|
|
|
|
HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
if (GetConsoleScreenBufferInfo(stdoutHandle, &csbi)) {
|
|
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
|
ux_width = MIN(columns, UX_PROGRESS_SIZE_MAX);
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
void ux_init(void)
|
|
{
|
|
struct winsize w;
|
|
int ret;
|
|
|
|
ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
|
if (!ret)
|
|
ux_width = MIN(w.ws_col, UX_PROGRESS_SIZE_MAX);
|
|
}
|
|
|
|
#endif
|
|
|
|
void ux_err(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
ux_clear_line();
|
|
|
|
va_start(ap, fmt);
|
|
vfprintf(stderr, fmt, ap);
|
|
va_end(ap);
|
|
fflush(stderr);
|
|
}
|
|
|
|
void ux_info(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
ux_clear_line();
|
|
|
|
va_start(ap, fmt);
|
|
vprintf(fmt, ap);
|
|
va_end(ap);
|
|
fflush(stdout);
|
|
}
|
|
|
|
void ux_log(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
if (!qdl_debug)
|
|
return;
|
|
|
|
ux_clear_line();
|
|
|
|
va_start(ap, fmt);
|
|
vprintf(fmt, ap);
|
|
va_end(ap);
|
|
fflush(stdout);
|
|
}
|
|
|
|
void ux_debug(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
if (!qdl_debug)
|
|
return;
|
|
|
|
ux_clear_line();
|
|
|
|
va_start(ap, fmt);
|
|
vprintf(fmt, ap);
|
|
va_end(ap);
|
|
fflush(stdout);
|
|
}
|
|
|
|
void ux_progress(const char *fmt, unsigned int value, unsigned int max, ...)
|
|
{
|
|
static struct timeval last_progress_update;
|
|
unsigned long elapsed_us;
|
|
unsigned int bar_length;
|
|
unsigned int bars;
|
|
unsigned int dashes;
|
|
struct timeval now;
|
|
char task_name[32];
|
|
float percent;
|
|
va_list ap;
|
|
|
|
/* Don't print progress is window is too narrow, or if stdout is redirected */
|
|
if (ux_width < 30)
|
|
return;
|
|
|
|
/* Avoid updating the console more than UX_PROGRESS_REFRESH_RATE per second */
|
|
if (last_progress_update.tv_sec) {
|
|
gettimeofday(&now, NULL);
|
|
elapsed_us = (now.tv_sec - last_progress_update.tv_sec) * 1000000 +
|
|
(now.tv_usec - last_progress_update.tv_usec);
|
|
|
|
if (elapsed_us < (1000000 / UX_PROGRESS_REFRESH_RATE))
|
|
return;
|
|
}
|
|
|
|
if (value > max)
|
|
value = max;
|
|
|
|
va_start(ap, max);
|
|
vsnprintf(task_name, sizeof(task_name), fmt, ap);
|
|
va_end(ap);
|
|
|
|
bar_length = ux_width - (20 + 4 + 6);
|
|
percent = (float)value / max;
|
|
bars = percent * bar_length;
|
|
dashes = bar_length - bars;
|
|
|
|
printf("%-20.20s [%.*s%.*s] %1.2f%%%n\r", task_name,
|
|
bars, progress_hashes,
|
|
dashes, progress_dashes,
|
|
percent * 100,
|
|
&ux_cur_line_length);
|
|
fflush(stdout);
|
|
|
|
gettimeofday(&last_progress_update, NULL);
|
|
}
|