option.c: fixed warnings
[k8jam.git] / src / progress.c
blob7a5ea658ef9168c8d52c4e0f0092494bbd9f05ed
1 /*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, version 3 of the License ONLY.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #include <stdlib.h>
15 #include <string.h>
16 #include <time.h>
18 #include "jam.h"
19 #include "lists.h"
20 #include "parse.h"
21 #include "rules.h"
22 #include "newstr.h"
23 #include "hash.h"
24 #include "variable.h"
25 #include "search.h"
27 #include "progress.h"
30 #define PROGRESS_WINDOW (10)
33 typedef struct {
34 time_t when;
35 int completed;
36 } TIMESTAMP;
39 struct _PROGRESS {
40 int total;
41 int stampcount;
42 TIMESTAMP stamps[PROGRESS_WINDOW];
46 static double get_time_delta (void) {
47 static double res = 10.0;
48 static int checked = 0;
49 if (!checked) {
50 LIST *var = var_get("K8JAM-PROGRESS-TIME-DELTA"); /*FIXME: a perfectly idiotic name*/
51 if (var) {
52 TARGET *t = bindtarget(var->string);
53 pushsettings(t->settings);
54 t->boundname = search(t->name, &t->time);
55 popsettings(t->settings);
56 if (t->boundname) {
57 res = atof(t->boundname);
58 if (res < 0.0) res = 0.0;
60 checked = 1;
63 return res;
67 #define LAST_STAMP(p) ((p)->stamps[(p)->stampcount-1])
68 #define FIRST_STAMP(p) ((p)->stamps[0])
71 PROGRESS *progress_start (int total) {
72 PROGRESS *p = malloc(sizeof(PROGRESS));
73 p->total = total;
74 p->stampcount = 0;
75 progress_update(p, 0);
76 return p;
80 static double progress_estimate (PROGRESS *progress) {
81 int count, left;
82 double elapsed, rate;
83 if (progress->stampcount < 2) return 0.0;
84 count = LAST_STAMP(progress).completed-FIRST_STAMP(progress).completed;
85 left = progress->total-LAST_STAMP(progress).completed;
86 elapsed = (double)(LAST_STAMP(progress).when-FIRST_STAMP(progress).when);
87 if (elapsed <= 0.1) elapsed = 0.1;
88 rate = count/elapsed;
89 return left/rate;
93 double progress_update (PROGRESS *progress, int completed) {
94 time_t now;
95 double dd = get_time_delta();
96 time(&now);
97 /* only return progress every 10 seconds */
98 if (progress->stampcount > 0 && (dd <= 0.00001 || difftime(now, LAST_STAMP(progress).when) < dd)) return 0.0;
99 if (progress->stampcount == PROGRESS_WINDOW) {
100 memmove(progress->stamps, progress->stamps+1, sizeof(progress->stamps[0])*(PROGRESS_WINDOW-1));
101 --progress->stampcount;
103 ++progress->stampcount;
104 LAST_STAMP(progress).completed = completed;
105 LAST_STAMP(progress).when = now;
106 return progress_estimate(progress);