fixed pkg-config rule
[k8jam.git] / src / progress.c
blob68e47c427797cbe76f83bd852b21b63aa341c2ee
1 #ifndef __NEATCC__
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
6 #include "jam.h"
7 #include "lists.h"
8 #include "parse.h"
9 #include "rules.h"
10 #include "newstr.h"
11 #include "hash.h"
12 #include "variable.h"
13 #include "search.h"
15 #include "progress.h"
18 #define PROGRESS_WINDOW (10)
21 typedef struct {
22 time_t when;
23 int completed;
24 } TIMESTAMP;
27 struct _PROGRESS {
28 int total;
29 int stampcount;
30 TIMESTAMP stamps[PROGRESS_WINDOW];
34 static double getTimeDelta (void) {
35 static double res = 10.0;
36 static int checked = 0;
37 if (!checked) {
38 LIST *var = var_get("K8JAM-PROGRESS-TIME-DELTA"); /*FIXME: a perfectly idiotic name*/
39 if (var) {
40 TARGET *t = bindtarget(var->string);
41 pushsettings(t->settings);
42 t->boundname = search(t->name, &t->time);
43 popsettings(t->settings);
44 if (t->boundname) {
45 res = atof(t->boundname);
46 if (res < 0.0) res = 0.0;
48 checked = 1;
51 return res;
55 #define LAST_STAMP(p) ((p)->stamps[(p)->stampcount-1])
56 #define FIRST_STAMP(p) ((p)->stamps[0])
59 PROGRESS *progress_start (int total) {
60 PROGRESS *p = malloc(sizeof(PROGRESS));
61 p->total = total;
62 p->stampcount = 0;
63 progress_update(p, 0);
64 return p;
68 static double progress_estimate (PROGRESS *progress) {
69 int count;
70 int left;
71 double elapsed;
72 double rate;
74 if (progress->stampcount < 2) return 0.0;
75 count = LAST_STAMP(progress).completed-FIRST_STAMP(progress).completed;
76 left = progress->total-LAST_STAMP(progress).completed;
77 elapsed = (double)(LAST_STAMP(progress).when-FIRST_STAMP(progress).when);
78 if (elapsed <= 0.1) elapsed = 0.1;
79 rate = count/elapsed;
80 return left/rate;
84 double progress_update (PROGRESS *progress, int completed) {
85 time_t now;
86 double dd = getTimeDelta();
88 time(&now);
89 /* only return progress every 10 seconds */
90 if (progress->stampcount > 0 && (dd <= 0.00001 || difftime(now, LAST_STAMP(progress).when) < dd)) return 0.0;
91 if (progress->stampcount == PROGRESS_WINDOW) {
92 memmove(progress->stamps, progress->stamps+1, sizeof(progress->stamps[0])*(PROGRESS_WINDOW-1));
93 --progress->stampcount;
95 ++progress->stampcount;
96 LAST_STAMP(progress).completed = completed;
97 LAST_STAMP(progress).when = now;
98 return progress_estimate(progress);
100 #endif