autoupdater: update download progress display less frequently
Updating the "XXXXX / XXXXX KiB" display for every run of recv_image_cb() is a significant bottleneck on slow consoles. This was reported for a device using a 9600 Baud serial console, but the slowdown is noticeable even on a 115200 Baud console, especially when the network is fast. Replace the output with a "XX.X / XX.X MiB" display and only update it every 0.1 MiB to fix the issue. Closes #273
This commit is contained in:
parent
3d08b0fee8
commit
e350f4804d
|
@ -72,6 +72,7 @@ struct recv_manifest_ctx {
|
||||||
struct recv_image_ctx {
|
struct recv_image_ctx {
|
||||||
int fd;
|
int fd;
|
||||||
ecdsa_sha256_context_t hash_ctx;
|
ecdsa_sha256_context_t hash_ctx;
|
||||||
|
ssize_t downloaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,6 +249,32 @@ static void recv_manifest_cb(struct uclient *cl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Updates the "XX.X / XX.X MiB" progress display */
|
||||||
|
static void update_progress(struct recv_image_ctx *ctx, ssize_t downloaded, ssize_t length)
|
||||||
|
{
|
||||||
|
/* Numbers in 0.1 MiB units */
|
||||||
|
ssize_t downloaded_01_mib = ((downloaded / 1024) * 10) / 1024;
|
||||||
|
ssize_t length_01_mib = ((length / 1024) * 10) / 1024;
|
||||||
|
|
||||||
|
if (downloaded_01_mib == ctx->downloaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx->downloaded = downloaded_01_mib;
|
||||||
|
|
||||||
|
/* Integer and 1 digit fractional part in 1 MiB units */
|
||||||
|
ssize_t downloaded_mib = downloaded_01_mib / 10;
|
||||||
|
int downloaded_mib_frac = downloaded_01_mib % 10;
|
||||||
|
ssize_t length_mib = length_01_mib / 10;
|
||||||
|
int length_mib_frac = length_01_mib % 10;
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"\rDownloading image: % 3zi.%i / %zi.%i MiB",
|
||||||
|
downloaded_mib, downloaded_mib_frac,
|
||||||
|
length_mib, length_mib_frac
|
||||||
|
);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Receives data from uclient and writes it to file */
|
/** Receives data from uclient and writes it to file */
|
||||||
static void recv_image_cb(struct uclient *cl) {
|
static void recv_image_cb(struct uclient *cl) {
|
||||||
|
@ -260,12 +287,7 @@ static void recv_image_cb(struct uclient *cl) {
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printf(
|
update_progress(ctx, uclient_data(cl)->downloaded, uclient_data(cl)->length);
|
||||||
"\rDownloading image: % 5zi / %zi KiB",
|
|
||||||
uclient_data(cl)->downloaded / 1024,
|
|
||||||
uclient_data(cl)->length / 1024
|
|
||||||
);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (write(ctx->fd, buf, len) < len) {
|
if (write(ctx->fd, buf, len) < len) {
|
||||||
fputs("autoupdater: error: downloading firmware image failed: ", stderr);
|
fputs("autoupdater: error: downloading firmware image failed: ", stderr);
|
||||||
|
@ -349,7 +371,7 @@ static bool autoupdate(const char *mirror, struct settings *s, int lock_fd) {
|
||||||
/* Begin download of the image */
|
/* Begin download of the image */
|
||||||
run_dir(download_d_dir);
|
run_dir(download_d_dir);
|
||||||
|
|
||||||
struct recv_image_ctx image_ctx = { };
|
struct recv_image_ctx image_ctx = { .downloaded = -1 };
|
||||||
image_ctx.fd = open(firmware_path, O_WRONLY|O_CREAT, 0600);
|
image_ctx.fd = open(firmware_path, O_WRONLY|O_CREAT, 0600);
|
||||||
if (image_ctx.fd < 0) {
|
if (image_ctx.fd < 0) {
|
||||||
fprintf(stderr, "autoupdater: error: failed opening firmware file %s\n", firmware_path);
|
fprintf(stderr, "autoupdater: error: failed opening firmware file %s\n", firmware_path);
|
||||||
|
|
Loading…
Reference in New Issue