kernel - Update swapcache manual page
[dragonfly.git] / contrib / ncurses / tack / sync.c
blob6eb91b256a75a37e94efd541e17f162a5876653c
1 /*
2 ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
3 **
4 ** This file is part of TACK.
5 **
6 ** TACK is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2, or (at your option)
9 ** any later version.
10 **
11 ** TACK is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with TACK; see the file COPYING. If not, write to
18 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
22 #include <tack.h>
23 #include <time.h>
25 MODULE_ID("$Id: sync.c,v 1.3 2001/06/16 17:55:48 tom Exp $")
27 /* terminal-synchronization and performance tests */
29 static void sync_home(struct test_list *, int *, int *);
30 static void sync_lines(struct test_list *, int *, int *);
31 static void sync_clear(struct test_list *, int *, int *);
32 static void sync_summary(struct test_list *, int *, int *);
34 struct test_list sync_test_list[] = {
35 {MENU_NEXT, 0, 0, 0, "b) baud rate test", sync_home, 0},
36 {MENU_NEXT, 0, 0, 0, "l) scroll performance", sync_lines, 0},
37 {MENU_NEXT, 0, 0, 0, "c) clear screen performance", sync_clear, 0},
38 {MENU_NEXT, 0, 0, 0, "p) summary of results", sync_summary, 0},
39 {0, 0, 0, 0, txt_longer_test_time, longer_test_time, 0},
40 {0, 0, 0, 0, txt_shorter_test_time, shorter_test_time, 0},
41 {MENU_LAST, 0, 0, 0, 0, 0, 0}
44 struct test_menu sync_menu = {
45 0, 'n', 0,
46 "Performance tests", "perf", "n) run standard tests",
47 sync_test, sync_test_list, 0, 0, 0
50 int tty_can_sync; /* TRUE if tty_sync_error() returned FALSE */
51 int tty_newline_rate; /* The number of newlines per second */
52 int tty_clear_rate; /* The number of clear-screens per second */
53 int tty_cps; /* The number of characters per second */
55 #define TTY_ACK_SIZE 64
57 int ACK_terminator; /* terminating ACK character */
58 int ACK_length; /* length of ACK string */
59 const char *tty_ENQ; /* enquire string */
60 char tty_ACK[TTY_ACK_SIZE]; /* ACK response, set by tty_sync_error() */
62 /*****************************************************************************
64 * Terminal synchronization.
66 * These functions handle the messy business of enq-ack handshaking
67 * for timing purposes.
69 *****************************************************************************/
71 int
72 tty_sync_error(void)
74 int ch, trouble, ack;
76 trouble = FALSE;
77 for (;;) {
78 tt_putp(tty_ENQ); /* send ENQ */
79 ch = getnext(STRIP_PARITY);
80 event_start(TIME_SYNC); /* start the timer */
83 The timer doesn't start until we get the first character.
84 After that I expect to get the remaining characters of
85 the acknowledge string in a short period of time. If
86 that is not true then these characters are coming from
87 the user and we need to send the ENQ sequence out again.
89 for (ack = 0; ; ) {
90 if (ack < TTY_ACK_SIZE - 2) {
91 tty_ACK[ack] = ch;
92 tty_ACK[ack + 1] = '\0';
94 if (ch == ACK_terminator) {
95 return trouble;
97 if (++ack >= ACK_length) {
98 return trouble;
100 ch = getnext(STRIP_PARITY);
101 if (event_time(TIME_SYNC) > 400000) {
102 break;
106 set_attr(0); /* just in case */
107 put_crlf();
108 if (trouble) {
109 /* The terminal won't sync. Life is not good. */
110 return TRUE;
112 put_str(" -- sync -- ");
113 trouble = TRUE;
118 ** flush_input()
120 ** Throw away any output.
122 void
123 flush_input(void)
125 if (tty_can_sync == SYNC_TESTED && ACK_terminator >= 0) {
126 (void) tty_sync_error();
127 } else {
128 spin_flush();
133 ** probe_enq_ok()
135 ** does the terminal do enq/ack handshaking?
137 static void
138 probe_enq_ok(void)
140 int tc, len, ulen;
142 put_str("Testing ENQ/ACK, standby...");
143 fflush(stdout);
144 can_test("u8 u9", FLAG_TESTED);
146 #ifdef user9
147 tty_ENQ = user9 ? user9 : "\005";
148 #else
149 tty_ENQ = "\005";
150 #endif
151 tc_putp(tty_ENQ);
152 event_start(TIME_SYNC); /* start the timer */
153 read_key(tty_ACK, TTY_ACK_SIZE - 1);
155 if (event_time(TIME_SYNC) > 400000 || tty_ACK[0] == '\0') {
156 /* These characters came from the user. Sigh. */
157 tty_can_sync = SYNC_FAILED;
158 ptext("\nThis program expects the ENQ sequence to be");
159 ptext(" answered with the ACK character. This will help");
160 ptext(" the program reestablish synchronization when");
161 ptextln(" the terminal is overrun with data.");
162 ptext("\nENQ sequence from (u9): ");
163 putln(expand(tty_ENQ));
164 ptext("ACK received: ");
165 putln(expand(tty_ACK));
166 #ifdef user8
167 len = user8 ? strlen(user8) : 0;
168 #else
169 len = 0;
170 #endif
171 sprintf(temp, "Length of ACK %d. Expected length of ACK %d.",
172 (int) strlen(tty_ACK), len);
173 ptextln(temp);
174 #ifdef user8
175 if (len) {
176 temp[0] = user8[len - 1];
177 temp[1] = '\0';
178 ptext("Terminating character found in (u8): ");
179 putln(expand(temp));
181 #endif
182 return;
185 tty_can_sync = SYNC_TESTED;
186 if ((len = strlen(tty_ACK)) == 1) {
187 /* single character acknowledge string */
188 ACK_terminator = tty_ACK[0];
189 ACK_length = 4096;
190 return;
192 tc = tty_ACK[len - 1];
193 #ifdef user8
194 if (user8) {
195 ulen = strlen(user8);
196 if (tc == user8[ulen - 1]) {
197 /* ANSI style acknowledge string */
198 ACK_terminator = tc;
199 ACK_length = 4096;
200 return;
203 #endif
204 /* fixed length acknowledge string */
205 ACK_length = len;
206 ACK_terminator = -2;
210 ** verify_time()
212 ** verify that the time tests are ready to run.
213 ** If the baud rate is not set then compute it.
215 void
216 verify_time(void)
218 int status, ch;
220 if (tty_can_sync == SYNC_FAILED) {
221 return;
223 probe_enq_ok();
224 put_crlf();
225 if (tty_can_sync == SYNC_TESTED) {
226 put_crlf();
227 if (ACK_terminator >= 0) {
228 ptext("ACK terminating character: ");
229 temp[0] = ACK_terminator;
230 temp[1] = '\0';
231 ptextln(expand(temp));
232 } else {
233 sprintf(temp, "Fixed length ACK, %d characters",
234 ACK_length);
235 ptextln(temp);
238 if (tty_baud_rate == 0) {
239 sync_home(&sync_test_list[0], &status, &ch);
243 /*****************************************************************************
245 * Terminal performance tests
247 * Find out how fast the terminal can:
248 * 1) accept characters
249 * 2) scroll the screen
250 * 3) clear the screen
252 *****************************************************************************/
255 ** sync_home(test_list, status, ch)
257 ** Baudrate test
259 void
260 sync_home(
261 struct test_list *t,
262 int *state,
263 int *ch)
265 int j, k;
266 unsigned long rate;
268 if (!cursor_home && !cursor_address && !row_address) {
269 ptext("Terminal can not home cursor. ");
270 generic_done_message(t, state, ch);
271 return;
273 if (skip_pad_test(t, state, ch,
274 "(home) Start baudrate search")) {
275 return;
277 pad_test_startup(1);
278 do {
279 go_home();
280 for (j = 1; j < lines; j++) {
281 for (k = 0; k < columns; k++) {
282 if (k & 0xF) {
283 put_this(letter);
284 } else {
285 put_this('.');
288 SLOW_TERMINAL_EXIT;
290 NEXT_LETTER;
291 } while(still_testing());
292 pad_test_shutdown(t, auto_right_margin == 0);
293 /* note: tty_frame_size is the real framesize times two.
294 This takes care of half bits. */
295 rate = (tx_cps * tty_frame_size) >> 1;
296 if (rate > tty_baud_rate) {
297 tty_baud_rate = rate;
299 if (tx_cps > tty_cps) {
300 tty_cps = tx_cps;
302 sprintf(temp, "%d characters per second. Baudrate %d ", tx_cps, j);
303 ptext(temp);
304 generic_done_message(t, state, ch);
308 ** sync_lines(test_list, status, ch)
310 ** How many newlines/second?
312 static void
313 sync_lines(
314 struct test_list *t,
315 int *state,
316 int *ch)
318 int j;
320 if (skip_pad_test(t, state, ch,
321 "(nel) Start scroll performance test")) {
322 return;
324 pad_test_startup(0);
325 repeats = 100;
326 do {
327 sprintf(temp, "%d", test_complete);
328 put_str(temp);
329 put_newlines(repeats);
330 } while(still_testing());
331 pad_test_shutdown(t, 0);
332 j = sliding_scale(tx_count[0], 1000000, usec_run_time);
333 if (j > tty_newline_rate) {
334 tty_newline_rate = j;
336 sprintf(temp, "%d linefeeds per second. ", j);
337 ptext(temp);
338 generic_done_message(t, state, ch);
342 ** sync_clear(test_list, status, ch)
344 ** How many clear-screens/second?
346 static void
347 sync_clear(
348 struct test_list *t,
349 int *state,
350 int *ch)
352 int j;
354 if (!clear_screen) {
355 ptext("Terminal can not clear-screen. ");
356 generic_done_message(t, state, ch);
357 return;
359 if (skip_pad_test(t, state, ch,
360 "(clear) Start clear-screen performance test")) {
361 return;
363 pad_test_startup(0);
364 repeats = 20;
365 do {
366 sprintf(temp, "%d", test_complete);
367 put_str(temp);
368 for (j = 0; j < repeats; j++) {
369 put_clear();
371 } while(still_testing());
372 pad_test_shutdown(t, 0);
373 j = sliding_scale(tx_count[0], 1000000, usec_run_time);
374 if (j > tty_clear_rate) {
375 tty_clear_rate = j;
377 sprintf(temp, "%d clear-screens per second. ", j);
378 ptext(temp);
379 generic_done_message(t, state, ch);
383 ** sync_summary(test_list, status, ch)
385 ** Print out the test results.
387 static void
388 sync_summary(
389 struct test_list *t,
390 int *state,
391 int *ch)
393 char size[32];
395 put_crlf();
396 ptextln("Terminal size characters/sec linefeeds/sec clears/sec");
397 sprintf(size, "%dx%d", columns, lines);
398 sprintf(temp, "%-10s%-11s%11d %11d %11d", tty_basename, size,
399 tty_cps, tty_newline_rate, tty_clear_rate);
400 ptextln(temp);
401 generic_done_message(t, state, ch);
405 ** sync_test(menu)
407 ** Run at the beginning of the pad tests and function key tests
409 void
410 sync_test(
411 struct test_menu *menu)
413 control_init();
414 if (tty_can_sync == SYNC_NOT_TESTED) {
415 verify_time();
417 if (menu->menu_title) {
418 put_crlf();
419 ptextln(menu->menu_title);
424 ** sync_handshake(test_list, status, ch)
426 ** Test or retest the ENQ/ACK handshake
428 void
429 sync_handshake(
430 struct test_list *t GCC_UNUSED,
431 int *state GCC_UNUSED,
432 int *ch GCC_UNUSED)
434 tty_can_sync = SYNC_NOT_TESTED;
435 verify_time();