mirror of
https://github.com/xboot/xfel.git
synced 2024-11-27 11:43:28 +08:00
75 lines
1.6 KiB
C
75 lines
1.6 KiB
C
#include <progress.h>
|
|
|
|
static double gettime(void)
|
|
{
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
return tv.tv_sec + (double)tv.tv_usec / 1000000.0;
|
|
}
|
|
|
|
static const char * format_eta(double remaining)
|
|
{
|
|
static char result[6] = "";
|
|
int seconds = remaining + 0.5;
|
|
if(seconds >= 0 && seconds < 6000)
|
|
{
|
|
snprintf(result, sizeof(result), "%02d:%02d", seconds / 60, seconds % 60);
|
|
return result;
|
|
}
|
|
return "--:--";
|
|
}
|
|
|
|
static char * ssize(char * buf, double size)
|
|
{
|
|
const char * unit[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
|
|
int count = 0;
|
|
|
|
while((size > 1024) && (count < 8))
|
|
{
|
|
size /= 1024;
|
|
count++;
|
|
}
|
|
sprintf(buf, "%5.3f %s", size, unit[count]);
|
|
return buf;
|
|
}
|
|
|
|
void progress_start(struct progress_t * p, uint64_t total)
|
|
{
|
|
if(p && (total > 0))
|
|
{
|
|
p->total = total;
|
|
p->done = 0;
|
|
p->start = gettime();
|
|
}
|
|
}
|
|
|
|
void progress_update(struct progress_t * p, uint64_t bytes)
|
|
{
|
|
char buf1[32], buf2[32];
|
|
|
|
if(p)
|
|
{
|
|
p->done += bytes;
|
|
double ratio = p->total > 0 ? (double)p->done / (double)p->total : 0.0;
|
|
double speed = (double)p->done / (gettime() - p->start);
|
|
double eta = speed > 0 ? (p->total - p->done) / speed : 0;
|
|
int i, pos = 48 * ratio;
|
|
printf("\r%3.0f%% [", ratio * 100);
|
|
for(i = 0; i < pos; i++)
|
|
putchar('=');
|
|
for(i = pos; i < 48; i++)
|
|
putchar(' ');
|
|
if(p->done < p->total)
|
|
printf("] %s/s, ETA %s \r", ssize(buf1, speed), format_eta(eta));
|
|
else
|
|
printf("] %s, %s/s \r", ssize(buf1, p->done), ssize(buf2, speed));
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
|
|
void progress_stop(struct progress_t * p)
|
|
{
|
|
if(p)
|
|
printf("\r\n");
|
|
}
|