2 * Copyright (c) 2019 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * This code uses concepts and configuration based on 'synth', by
8 * John R. Marino <draco@marino.st>, which was written in ada.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
20 * 3. Neither the name of The DragonFly Project nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific, prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * ncurses - LINES, COLS are the main things we care about
45 static const char *Line0 = " Total - Built - Ignored - "
47 static const char *Line1 = " Left - Failed - Skipped - "
48 "Swap - Impulse - --:--:-- ";
49 static const char *LineB = "==========================================="
50 "====================================";
51 static const char *LineI = " ID Duration Build Phase Origin "
54 static time_t GuiStartTime;
55 static int LastReduce;
59 #define IGNORED_COL 36
61 #define GPKGRATE_COL 64
66 #define SKIPPED_COL 36
68 #define IMPULSE_COL 64
72 #define DURATION_COL 5
73 #define BUILD_PHASE_COL 15
82 GuiStartTime = time(NULL);
94 mvwprintw(CWin, 0, 0, "%s", Line0);
95 mvwprintw(CWin, 1, 0, "%s", Line1);
96 mvwprintw(CWin, 2, 0, "%s", LineB);
97 mvwprintw(CWin, 3, 0, "%s", LineI);
98 mvwprintw(CWin, 4, 0, "%s", LineB);
100 for (i = 0; i < MaxWorkers; ++i) {
101 mvwprintw(CWin, 5 + i, ID_COL, "%02d", i);
102 mvwprintw(CWin, 5 + i, DURATION_COL, "--:--:--");
103 mvwprintw(CWin, 5 + i, BUILD_PHASE_COL, "Idle");
104 mvwprintw(CWin, 5 + i, ORIGIN_COL, "%39.39s", "");
105 mvwprintw(CWin, 5 + i, LINES_COL, "%6.6s", "");
111 #define RHISTSIZE 600 /* 10 minutes */
112 #define ONEHOUR (60 * 60)
117 static int rate_history[RHISTSIZE];
118 static u_int last_ti;
134 t = time(NULL) - GuiStartTime;
142 getloadavg(dload, 3);
143 dswap = getswappct(&noswap) * 100.0;
146 * Rate and 10-minute impulse
149 pkgrate = (BuildSuccessCount + BuildFailCount) * ONEHOUR / t;
152 ti = (u_int)((unsigned long)t % RHISTSIZE);
153 rate_history[ti] = BuildSuccessCount + BuildFailCount;
155 dlog(DLOG_ALL, "ti[%3d] = %d\n", ti, rate_history[ti]);
157 while (last_ti != ti) {
158 rate_history[last_ti] = rate_history[ti];
159 last_ti = (last_ti + 1) % RHISTSIZE;
164 } else if (t < RHISTSIZE) {
165 pkgimpulse = rate_history[ti] -
166 rate_history[(ti - t) % RHISTSIZE];
167 pkgimpulse = pkgimpulse * ONEHOUR / t;
169 pkgimpulse = rate_history[ti] -
170 rate_history[(ti + 1) % RHISTSIZE];
171 pkgimpulse = pkgimpulse * ONEHOUR / RHISTSIZE;
173 dlog(DLOG_ALL, "pkgimpulse %d - %d -> %d\n",
175 rate_history[(ti + 1) % RHISTSIZE],
180 mvwprintw(CWin, 0, TOTAL_COL, "%-5d", BuildTotal);
181 mvwprintw(CWin, 0, BUILT_COL, "%-5d", BuildSuccessCount);
182 mvwprintw(CWin, 0, IGNORED_COL, "%-5d", -1);
183 if (dload[0] > 999.9)
184 mvwprintw(CWin, 0, LOAD_COL, "%5.0f", dload[0]);
186 mvwprintw(CWin, 0, LOAD_COL, "%5.1f", dload[0]);
187 mvwprintw(CWin, 0, GPKGRATE_COL, "%-5d", pkgrate);
190 * If dynamic worker reduction is active include a field,
191 * Otherwise blank the field.
193 if (LastReduce != DynamicMaxWorkers) {
194 LastReduce = DynamicMaxWorkers;
195 if (MaxWorkers == LastReduce)
196 mvwprintw(CWin, 0, REDUCE_COL, " ");
198 mvwprintw(CWin, 0, REDUCE_COL, "Limit %-2d",
202 mvwprintw(CWin, 1, LEFT_COL, "%-4d", BuildTotal - BuildCount);
203 mvwprintw(CWin, 1, FAILED_COL, "%-4d", BuildFailCount);
204 mvwprintw(CWin, 1, SKIPPED_COL, "%-4d", BuildSkipCount);
206 mvwprintw(CWin, 1, SWAP_COL, "- ");
208 mvwprintw(CWin, 1, SWAP_COL, "%5.1f", dswap);
209 mvwprintw(CWin, 1, IMPULSE_COL, "%-5d", pkgimpulse);
211 mvwprintw(CWin, 1, TIME_COL-1, "%3d:%02d:%02d", h, m, s);
213 mvwprintw(CWin, 1, TIME_COL, "%02d:%02d:%02d", h, m, s);
217 GuiUpdate(worker_t *work)
230 switch(work->state) {
235 if (work->state == WORKER_IDLE)
239 if (work->state == WORKER_FAILED)
243 if (work->state == WORKER_EXITING)
245 mvwprintw(CWin, 5 + i, DURATION_COL, "--:--:--");
246 mvwprintw(CWin, 5 + i, BUILD_PHASE_COL, "%-16.16s", phase);
247 mvwprintw(CWin, 5 + i, ORIGIN_COL, "%-39.39s", "");
248 mvwprintw(CWin, 5 + i, LINES_COL, "%-6.6s", "");
266 t = time(NULL) - work->start_time;
271 if (work->state == WORKER_RUNNING) {
272 switch(work->phase) {
276 case PHASE_INSTALL_PKGS:
277 phase = "install-pkgs";
279 case PHASE_CHECK_SANITY:
280 phase = "check-sanity";
282 case PHASE_PKG_DEPENDS:
283 phase = "pkg-depends";
285 case PHASE_FETCH_DEPENDS:
286 phase = "fetch-depends";
294 case PHASE_EXTRACT_DEPENDS:
295 phase = "extract-depends";
300 case PHASE_PATCH_DEPENDS:
301 phase = "patch-depends";
306 case PHASE_BUILD_DEPENDS:
307 phase = "build-depends";
309 case PHASE_LIB_DEPENDS:
310 phase = "lib-depends";
312 case PHASE_CONFIGURE:
318 case PHASE_RUN_DEPENDS:
319 phase = "run-depends";
327 case PHASE_CHECK_PLIST:
328 phase = "check-plist";
333 case PHASE_INSTALL_MTREE:
334 phase = "install-mtree";
339 case PHASE_DEINSTALL:
343 phase = "Run-Unknown";
349 origin = work->pkg->portdir;
353 mvwprintw(CWin, 5 + i, DURATION_COL, "%02d:%02d:%02d", h, m, s);
354 mvwprintw(CWin, 5 + i, BUILD_PHASE_COL, "%-16.16s", phase);
355 mvwprintw(CWin, 5 + i, ORIGIN_COL, "%-39.39s", origin);
356 mvwprintw(CWin, 5 + i, LINES_COL, "%6d", work->lines);