fix more seg faults on amd64 when NO_UI is not defined
[debian/gcpegg] / eggui.c
1 /* PROGRAM:     eggsh
2  * FILE:        $Header: /home/egg/src/RCS/eggui.c,v 1.8 1999/02/28 20:02:54 ghn Exp $
3  * PURPOSE:     EGG site user interface
4  * AUTHOR:      Greg Nelson
5  * DATE:        98-06-28
6  *
7  * REVISED:
8  * $Log: eggui.c,v $
9  * Revision 1.8  1999/02/28 20:02:54  ghn
10  * Version 5.1: The user interface now leaves the cursor at the bottom of
11  * the screen and responds to ^L to redraw the entire screen.
12  *
13  * Revision 1.7  1999/01/01 23:58:56  ghn
14  * Take out "CPU_BOUND" conditionals; we won't run CPU_BOUND any more.
15  *
16  * Revision 1.6  1998/12/31 22:07:56  ghn
17  * Rev 5 code: includes multi-reg support, HTML, etc.
18  *
19  * Revision 1.5  1998/08/03 20:36:28  kelvin
20  * Show time of last data collection by basket.
21  *
22  * Revision 1.4  1998/08/01  21:33:28  ghn
23  * Added real implementation for ncursed() based UI for egg.
24  *
25  * Revision 1.3  1998/08/01 18:51:25  ghn
26  * Added John's byte-order-independence changes.
27  *
28  * Revision 1.2  1998/08/01 17:05:48  ghn
29  * Trivial additions of curses related code.
30  *
31  * Revision 1.1  1998/07/21 11:41:23  ghn
32  * Initial revision
33  *
34  * Copyright 1998 - Greg Nelson
35  */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <curses.h>
40 #include <time.h>
41 #include <string.h>
42
43 /*  Curses takes it upon itself to define TRUE and FALSE,
44     incompatibly, as it happens, with the definitions in
45     global.h.  So, clear out the CURSES definitions.  */
46 #ifdef TRUE
47 #undef TRUE
48 #endif
49 #ifdef FALSE
50 #undef FALSE
51 #endif
52
53 #include "global.h"
54 #include "genlib.h"
55 #include "errnos.h"
56 #include "regs.h"
57 #include "version.h"
58
59 #ifndef NO_UI
60 static uint32 inittm = 0;
61 #endif
62
63 extern uint32 lastDataSent;
64 extern uint32 time_latency, time_housekeeping;
65
66 /* Initialize user interface, as needed. */
67 int32 UIInit(void) {
68 #ifndef NO_UI
69   initscr(); 
70   cbreak(); noecho(); 
71   nonl();
72   intrflush(stdscr, FALSE);
73   keypad(stdscr, TRUE);
74   timeout(0);
75   clear();
76   move(0, 0);
77   printw("Please wait, initializing...");
78   refresh();
79   inittm = 0;
80 #endif
81   return ERR_NONE;
82 }
83
84 /* Close down user interface */
85 int32 UIClose(void) {
86 #ifndef NO_UI
87   endwin();
88 #endif
89   return ERR_NONE;
90 }
91
92 /* Update user interface once on every data collection, receiving the
93    current collection result and CollectRecord. */
94 int32 UIUpdate(int32 cres, CollectRecord *coll) {
95 #ifndef NO_UI
96   char *tmstr;
97   double recavg;
98   static double grandavg = 0;
99   static int32 totsamp = 0;
100   int32 i, line, now;
101
102   if ((i = getch()) != ERR) {
103     if (i == 12) clear();
104   }
105
106   if (inittm == 0) {
107     inittm = getzulutime(NULL);
108     clear();
109   }
110
111   /* Show protocol. */
112
113   if (coll->sampct == 1) {
114     line = 11;
115     move(line++, 5); printw("Samples per record: %3d", coll->opts.samp_rec);
116     move(line++, 5); printw("Seconds per record: %3d", coll->opts.sec_rec);
117     move(line++, 5); printw("Records per packet: %3d", coll->opts.rec_pkt);
118     move(line++, 5); printw("Bits per trial:     %3d", coll->opts.trialsz);
119     refresh();
120   }
121
122   if (cres < 0) return ERR_NONE;
123
124   line = 0;
125   move(line++, 3);
126   printw("EGG %s ID %d REG %s %s", eggtable[0].name, eggtable[0].id,
127          configuredREG->reg_name, Version);
128
129   tmstr = ctime(&inittm); tmstr[strlen(tmstr)-1] = 0;
130   move(line++, 5);
131   printw("Up since       %25s", tmstr);
132
133   move(line++, 5);
134   now = getzulutime(NULL);
135   time_t now_val = now;
136   tmstr = ctime(&now_val); tmstr[strlen(tmstr)-1] = 0;
137   printw("Last sample at %25s", tmstr);
138
139   move(line++, 5);
140   time_t lastDataSent_val = lastDataSent;
141   tmstr = ctime(&lastDataSent_val);
142   tmstr[strlen(tmstr)-1] = 0;
143   printw("Last packet at %25s", lastDataSent == 0 ? "Never" : tmstr);
144
145   /* Note that for a non-CPU_BOUND built, UIUpdate is passed a
146      collection record filled with the last 10 samples collected.
147      Since missing samples do not figure in this record, there
148      is no need to test EGG_MISSING_DATA when computing the
149      mean below. */
150
151   /* Show mean since egg started and, each time 10 samples
152      are collected, the mean for the last 10 samples. */
153
154   line++;
155   grandavg *= totsamp;
156   grandavg += coll->data.trials[coll->sampct-1]; totsamp++;
157   grandavg /= totsamp;
158   move(line++, 5);
159   printw("Grand mean:       %6.2f", grandavg);
160
161   if (cres == 1) {
162     for (recavg = 0, i = 0; i < coll->opts.samp_rec; i++)
163       recavg += coll->data.trials[i];
164     recavg /= coll->opts.samp_rec;
165     move(line, 5); 
166     printw("Last record mean: %6.2f (%d seconds)", recavg, coll->opts.sec_rec);
167   }
168   line++;                             /* Advance whether we show record mean or not */
169
170   /* Show latency (lapse between start of second as measured by
171      the computer's clock and when collection of the sample
172      actually began) and time elapsed in housekeeping (saving
173      packets in local files, talking to the basket, updating
174      the user interface, etc.) following collection of the sample.
175      If housekeeping time frequently consumes a substantial portion
176      of the inter-sample interval, the probability of lost
177      samples increases.  Both times are shown in milliseconds. */
178
179   line++;
180   move(line++, 5);
181   printw("Sampling latency:   ");
182   clrtoeol();
183   printw("%.3f ms", time_latency / 1000.0);
184   move(line++, 5);
185   printw("Housekeeping time:  ");
186   clrtoeol();
187   printw("%.3f ms", time_housekeeping / 1000.0);
188
189   move(16, 0);
190
191   refresh();
192 #endif
193
194   return ERR_NONE;
195 }