Add progress module to display load progress of files.
* grub-core/lib/progress.c: New file. * grub-core/Makefile.core.def (progress): New module. * grub-core/kern/file.c (grub_file_open): File name added. * (grub_file_read): Progress hook added. * grub-core/fs/cbfs.c (grub_cbfs_read): Likewise. * grub-core/fs/cpio_common.c (grub_cpio_read): Likewise. * grub-core/net/net.c (grub_net_fs_read_real): Likewise. * include/grub/file.h (struct grub_file): Add progress module * members. * include/grub/term.h (struct grub_term_output): Likewise. * grub-core/osdep/unix/emuconsole.c (grub_console_term_output): Terminal velocity added. * grub-core/osdep/windows/emuconsole.c (grub_console_term_output): * Likewise. * grub-core/term/arc/console.c (grub_console_term_output): Likewise. * grub-core/term/efi/console.c (grub_console_term_output): Likewise. * grub-core/term/gfxterm.c (grub_video_term): Likewise. * grub-core/term/i386/coreboot/cbmemc.c (grub_cbmemc_term_output): * Likewise. * grub-core/term/i386/pc/console.c (grub_console_term_output): * Likewise. * grub-core/term/i386/pc/vga_text.c (grub_vga_text_term): Likewise. * grub-core/term/ieee1275/console.c (grub_console_term_output): * Likewise. * grub-core/term/morse.c (grub_audio_term_output): Likewise. * grub-core/term/serial.c (grub_serial_term_output): Likewise. * grub-core/term/spkmodem.c (grub_spkmodem_term_output): Likewise. * grub-core/term/uboot/console.c (uboot_console_term_output): * Likewise.
This commit is contained in:
parent
0d711431c7
commit
84a0e9699f
22 changed files with 205 additions and 7 deletions
28
ChangeLog
28
ChangeLog
|
@ -1,3 +1,31 @@
|
|||
2013-10-22 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
||||
|
||||
Add new progress module that displays the load progress of files.
|
||||
|
||||
* grub-core/lib/progress.c: New file.
|
||||
* grub-core/Makefile.core.def (progress): New module.
|
||||
* grub-core/kern/file.c (grub_file_open): File name added.
|
||||
* (grub_file_read): Progress hook added.
|
||||
* grub-core/fs/cbfs.c (grub_cbfs_read): Likewise.
|
||||
* grub-core/fs/cpio_common.c (grub_cpio_read): Likewise.
|
||||
* grub-core/net/net.c (grub_net_fs_read_real): Likewise.
|
||||
* include/grub/file.h (struct grub_file): Add progress module members.
|
||||
* include/grub/term.h (struct grub_term_output): Likewise.
|
||||
* grub-core/osdep/unix/emuconsole.c (grub_console_term_output):
|
||||
Terminal velocity added.
|
||||
* grub-core/osdep/windows/emuconsole.c (grub_console_term_output): Likewise.
|
||||
* grub-core/term/arc/console.c (grub_console_term_output): Likewise.
|
||||
* grub-core/term/efi/console.c (grub_console_term_output): Likewise.
|
||||
* grub-core/term/gfxterm.c (grub_video_term): Likewise.
|
||||
* grub-core/term/i386/coreboot/cbmemc.c (grub_cbmemc_term_output): Likewise.
|
||||
* grub-core/term/i386/pc/console.c (grub_console_term_output): Likewise.
|
||||
* grub-core/term/i386/pc/vga_text.c (grub_vga_text_term): Likewise.
|
||||
* grub-core/term/ieee1275/console.c (grub_console_term_output): Likewise.
|
||||
* grub-core/term/morse.c (grub_audio_term_output): Likewise.
|
||||
* grub-core/term/serial.c (grub_serial_term_output): Likewise.
|
||||
* grub-core/term/spkmodem.c (grub_spkmodem_term_output): Likewise.
|
||||
* grub-core/term/uboot/console.c (uboot_console_term_output): Likewise.
|
||||
|
||||
2013-10-22 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Verify signatures of signatures unless --skip-sig is specified.
|
||||
|
|
|
@ -2135,3 +2135,8 @@ module = {
|
|||
name = tr;
|
||||
common = commands/tr.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = progress;
|
||||
common = lib/progress.c;
|
||||
};
|
||||
|
|
|
@ -243,10 +243,17 @@ static grub_ssize_t
|
|||
grub_cbfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
{
|
||||
struct grub_archelp_data *data;
|
||||
grub_ssize_t ret;
|
||||
|
||||
data = file->data;
|
||||
return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
|
||||
data->disk->read_hook = file->read_hook;
|
||||
data->disk->read_hook_data = file->read_hook_data;
|
||||
|
||||
ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset,
|
||||
len, buf)) ? -1 : (grub_ssize_t) len;
|
||||
data->disk->read_hook = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
|
|
@ -200,10 +200,17 @@ static grub_ssize_t
|
|||
grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
{
|
||||
struct grub_archelp_data *data;
|
||||
grub_ssize_t ret;
|
||||
|
||||
data = file->data;
|
||||
return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
|
||||
data->disk->read_hook = file->read_hook;
|
||||
data->disk->read_hook_data = file->read_hook_data;
|
||||
|
||||
ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset,
|
||||
len, buf)) ? -1 : (grub_ssize_t) len;
|
||||
data->disk->read_hook = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
|
|
@ -87,6 +87,9 @@ grub_file_open (const char *name)
|
|||
if (! file)
|
||||
goto fail;
|
||||
|
||||
file->name = grub_strdup (name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
file->device = device;
|
||||
|
||||
if (device->disk && file_name[0] != '/')
|
||||
|
@ -131,10 +134,14 @@ grub_file_open (const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
grub_disk_read_hook_t grub_file_progress_hook;
|
||||
|
||||
grub_ssize_t
|
||||
grub_file_read (grub_file_t file, void *buf, grub_size_t len)
|
||||
{
|
||||
grub_ssize_t res;
|
||||
grub_disk_read_hook_t read_hook;
|
||||
void *read_hook_data;
|
||||
|
||||
if (file->offset > file->size)
|
||||
{
|
||||
|
@ -155,7 +162,17 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
|
|||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
read_hook = file->read_hook;
|
||||
read_hook_data = file->read_hook_data;
|
||||
if (!file->read_hook)
|
||||
{
|
||||
file->read_hook = grub_file_progress_hook;
|
||||
file->read_hook_data = file;
|
||||
file->progress_offset = file->offset;
|
||||
}
|
||||
res = (file->fs->read) (file, buf, len);
|
||||
file->read_hook = read_hook;
|
||||
file->read_hook_data = read_hook_data;
|
||||
if (res > 0)
|
||||
file->offset += res;
|
||||
|
||||
|
|
100
grub-core/lib/progress.c
Normal file
100
grub-core/lib/progress.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* progress.c - show loading progress */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define UPDATE_INTERVAL 800
|
||||
|
||||
static void
|
||||
grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
|
||||
unsigned offset __attribute__ ((unused)),
|
||||
unsigned length, void *data)
|
||||
{
|
||||
grub_uint64_t now = grub_get_time_ms ();
|
||||
static grub_uint64_t last_progress_update_time;
|
||||
grub_file_t file = data;
|
||||
file->progress_offset += length;
|
||||
|
||||
if (((now - last_progress_update_time > UPDATE_INTERVAL) &&
|
||||
(file->progress_offset - file->offset > 0)) ||
|
||||
(file->progress_offset == file->size))
|
||||
{
|
||||
char buffer[80];
|
||||
struct grub_term_output *term;
|
||||
char *partial_file_name = grub_strrchr (file->name, '/') + 1;
|
||||
|
||||
grub_uint64_t current_speed = grub_divmod64 ((file->progress_offset -
|
||||
file->last_progress_offset)
|
||||
* 100ULL * 1000ULL,
|
||||
now - file->last_progress_time, 0);
|
||||
|
||||
file->estimated_speed = (file->estimated_speed + current_speed) >> 1;
|
||||
|
||||
grub_snprintf (buffer, sizeof (buffer), " [ %.20s %s %llu%% ",
|
||||
partial_file_name,
|
||||
grub_get_human_size (file->progress_offset,
|
||||
GRUB_HUMAN_SIZE_NORMAL),
|
||||
(100 * file->progress_offset) / file->size);
|
||||
|
||||
char *ptr = buffer + grub_strlen (buffer);
|
||||
grub_snprintf (ptr, sizeof (buffer) - (ptr - buffer), "%s ]",
|
||||
grub_get_human_size (file->estimated_speed,
|
||||
GRUB_HUMAN_SIZE_SPEED));
|
||||
|
||||
grub_uint16_t len = grub_strlen (buffer);
|
||||
FOR_ACTIVE_TERM_OUTPUTS (term)
|
||||
{
|
||||
if (term->progress_update_counter++ > term->progress_update_divisor ||
|
||||
(file->progress_offset == file->size &&
|
||||
term->progress_update_divisor != (unsigned) GRUB_PROGRESS_NO_UPDATE))
|
||||
{
|
||||
struct grub_term_coordinate old_pos = grub_term_getxy (term);
|
||||
struct grub_term_coordinate new_pos = old_pos;
|
||||
new_pos.x = grub_term_width (term) - len - 1;
|
||||
|
||||
grub_term_gotoxy (term, new_pos);
|
||||
grub_puts_terminal (buffer, term);
|
||||
grub_term_gotoxy (term, old_pos);
|
||||
|
||||
term->progress_update_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
file->last_progress_offset = file->progress_offset;
|
||||
file->last_progress_time = now;
|
||||
last_progress_update_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT(progress)
|
||||
{
|
||||
grub_file_progress_hook = grub_file_progress_hook_real;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(progress)
|
||||
{
|
||||
grub_file_progress_hook = 0;
|
||||
}
|
|
@ -1536,6 +1536,8 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
|
|||
len -= amount;
|
||||
total += amount;
|
||||
file->device->net->offset += amount;
|
||||
if (grub_file_progress_hook)
|
||||
grub_file_progress_hook (0, 0, amount, file);
|
||||
if (buf)
|
||||
{
|
||||
grub_memcpy (ptr, nb->data, amount);
|
||||
|
|
|
@ -149,6 +149,7 @@ static struct grub_term_output grub_console_term_output =
|
|||
.setcolorstate = grub_terminfo_setcolorstate,
|
||||
.setcursor = grub_terminfo_setcursor,
|
||||
.data = &grub_console_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -283,7 +283,8 @@ static struct grub_term_output grub_console_term_output =
|
|||
.cls = grub_console_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -188,6 +188,7 @@ static struct grub_term_output grub_console_term_output =
|
|||
.setcursor = grub_terminfo_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_console_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -276,7 +276,8 @@ static struct grub_term_output grub_console_term_output =
|
|||
.cls = grub_console_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -1108,6 +1108,7 @@ static struct grub_term_output grub_video_term =
|
|||
.refresh = grub_gfxterm_refresh,
|
||||
.fullscreen = grub_gfxterm_fullscreen,
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
|
||||
.progress_update_divisor = GRUB_PROGRESS_SLOW,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ static struct grub_term_output grub_cbmemc_term_output =
|
|||
.setcursor = grub_terminfo_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_cbmemc_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
@ -292,6 +292,7 @@ static struct grub_term_output grub_console_term_output =
|
|||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_CP437,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -267,6 +267,7 @@ static struct grub_term_output grub_vga_text_term =
|
|||
.setcolorstate = grub_vga_text_setcolorstate,
|
||||
.setcursor = grub_vga_text_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_CP437,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
/* FIXME: this is was too spaghetti. */
|
||||
|
|
|
@ -236,6 +236,7 @@ static struct grub_term_output grub_console_term_output =
|
|||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_console_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -118,7 +118,8 @@ static struct grub_term_output grub_audio_term_output =
|
|||
.cls = (void *) dummy,
|
||||
.setcolorstate = (void *) dummy,
|
||||
.setcursor = (void *) dummy,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB,
|
||||
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT (morse)
|
||||
|
|
|
@ -123,6 +123,7 @@ static struct grub_term_output grub_serial_term_output =
|
|||
.setcursor = grub_terminfo_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_serial_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_SLOW
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ static struct grub_term_output grub_spkmodem_term_output =
|
|||
.setcursor = grub_terminfo_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_spkmodem_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT (spkmodem)
|
||||
|
|
|
@ -95,6 +95,7 @@ static struct grub_term_output uboot_console_term_output = {
|
|||
.setcursor = uboot_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &uboot_console_terminfo_output,
|
||||
.progress_update_divisor = GRUB_PROGRESS_FAST
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
/* File description. */
|
||||
struct grub_file
|
||||
{
|
||||
/* File name. */
|
||||
char *name;
|
||||
|
||||
/* The underlying device. */
|
||||
grub_device_t device;
|
||||
|
||||
|
@ -36,6 +39,12 @@ struct grub_file
|
|||
|
||||
/* The current offset. */
|
||||
grub_off_t offset;
|
||||
grub_off_t progress_offset;
|
||||
|
||||
/* Progress info. */
|
||||
grub_uint64_t last_progress_time;
|
||||
grub_off_t last_progress_offset;
|
||||
grub_uint64_t estimated_speed;
|
||||
|
||||
/* The file size. */
|
||||
grub_off_t size;
|
||||
|
@ -54,6 +63,8 @@ struct grub_file
|
|||
};
|
||||
typedef struct grub_file *grub_file_t;
|
||||
|
||||
extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
#define GRUB_TERM_TAB '\t'
|
||||
#define GRUB_TERM_BACKSPACE '\b'
|
||||
|
||||
#define GRUB_PROGRESS_NO_UPDATE -1
|
||||
#define GRUB_PROGRESS_FAST 0
|
||||
#define GRUB_PROGRESS_SLOW 2
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
#include <grub/err.h>
|
||||
|
@ -215,6 +219,10 @@ struct grub_term_output
|
|||
/* The feature flags defined above. */
|
||||
grub_uint32_t flags;
|
||||
|
||||
/* Progress data. */
|
||||
grub_uint32_t progress_update_divisor;
|
||||
grub_uint32_t progress_update_counter;
|
||||
|
||||
void *data;
|
||||
};
|
||||
typedef struct grub_term_output *grub_term_output_t;
|
||||
|
|
Loading…
Reference in a new issue