openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

progress.c (3564B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * Progress Report module
      8  *
      9  *   Usage:
     10  *
     11  *	Call progress_init and pass it a measure of the total count.
     12  *		To avoid messing up the display, try not to print
     13  *		anything from now until you've called progress_done.
     14  *
     15  *	In your loop, call progress_report on every iteration and pass it
     16  *		an increment to the current count (usually 1).
     17  *		Regardless of how often it is called, an adaptive
     18  *		algorithm calls time() on average once per second,
     19  *		and updates the display if the percentage changes.
     20  *
     21  *	Call progress_status at any time to add or change a status
     22  *		message displayed along with the percent done.
     23  *
     24  *	Call progress_done when finished.
     25  *
     26  *   If the entire procedure completes before start_seconds
     27  *		elapses, nothing is printed at all.
     28  */
     29 
     30 #include <appl/diag/progress.h>
     31 #include <sal/appl/sal.h>
     32 #include <shared/bsl.h>
     33 #include <sal/appl/io.h>
     34 #include <sal/core/time.h>
     35 
     36 struct {
     37     int start_seconds;
     38     int disable;
     39     uint32 total_count;
     40     uint32 partial_count;
     41     sal_time_t start_time;
     42     sal_time_t check_time;
     43     int printed_something;
     44     int last_frac_printed;
     45     int iter_per_check_time;
     46     int iter_count;
     47     char *status_str;
     48 } progress;
     49 
     50 #define VT100_CLEAR_TO_EOL	"\033\133\113"
     51 
     52 void
     53 progress_init(uint32 total_count, int start_seconds, int disable)
     54 {
     55     progress.start_seconds = start_seconds;
     56     progress.disable = disable;
     57     progress.total_count = total_count;
     58     progress.partial_count = 0;
     59     progress.start_time = sal_time();
     60     progress.check_time = progress.start_time;
     61     progress.printed_something = 0;
     62     progress.last_frac_printed = -1;
     63     progress.iter_per_check_time = 1;
     64     progress.iter_count = 0;
     65     progress.status_str = 0;
     66 }
     67 
     68 void
     69 progress_status(char *status_str)
     70 {
     71     progress.status_str = status_str;
     72     progress.last_frac_printed = -1;
     73 }
     74 
     75 void
     76 progress_report(uint32 count_incr)
     77 {
     78     sal_time_t tm;
     79     if (progress.disable)
     80 	return;
     81     if ((progress.partial_count += count_incr) > progress.total_count)
     82 	progress.partial_count = progress.total_count;
     83     if (++progress.iter_count < progress.iter_per_check_time)
     84 	return;
     85     tm = sal_time();
     86     if (progress.check_time == tm) {
     87 	int old_iter = progress.iter_per_check_time;
     88 	/* Calling time() more than once per second; slow down */
     89 	progress.iter_per_check_time =
     90 	    progress.iter_per_check_time * 5 / 4;
     91 	if (progress.iter_per_check_time == old_iter)
     92 	    progress.iter_per_check_time++;
     93     } else {
     94 	if (tm > progress.check_time + 1) {
     95 	    /* Calling time() less than once per second; speed up */
     96 	    progress.iter_per_check_time =
     97 		progress.iter_per_check_time * 4 / 5;
     98 	}
     99 	progress.check_time = tm;
    100 	if (tm > progress.start_time + progress.start_seconds) {
    101 	    int frac;
    102 	    if (progress.total_count >= 0x1000000)	/* Don't overflow */
    103 		frac = progress.partial_count / (progress.total_count / 100);
    104 	    else
    105 		frac = (100 * progress.partial_count) / progress.total_count;
    106 	    if (frac != progress.last_frac_printed) {
    107 		cli_out("\r[%d%% done] %s " VT100_CLEAR_TO_EOL,
    108                         frac,
    109                         progress.status_str ? progress.status_str : "");
    110 		progress.printed_something = 1;
    111 		progress.last_frac_printed = frac;
    112 	    }
    113 	}
    114     }
    115     progress.iter_count = 0;
    116 }
    117 
    118 void
    119 progress_done(void)
    120 {
    121     if (progress.printed_something)
    122 	cli_out("\r" VT100_CLEAR_TO_EOL);
    123 }