2 ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
4 ** This file is part of TACK.
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)
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.
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.
25 MODULE_ID("$Id: sync.c,v 1.2 2000/03/04 20:28:16 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 = {
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 *****************************************************************************/
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.
90 if (ack < TTY_ACK_SIZE - 2) {
92 tty_ACK[ack + 1] = '\0';
94 if (ch == ACK_terminator) {
97 if (++ack >= ACK_length) {
100 ch = getnext(STRIP_PARITY);
101 if (event_time(TIME_SYNC) > 400000) {
106 set_attr(0); /* just in case */
109 /* The terminal won't sync. Life is not good. */
112 put_str(" -- sync -- ");
120 ** Throw away any output.
125 if (tty_can_sync == SYNC_TESTED && ACK_terminator >= 0) {
126 (void) tty_sync_error();
135 ** does the terminal do enq/ack handshaking?
142 put_str("Testing ENQ/ACK, standby...");
144 can_test("u8 u9", FLAG_TESTED);
146 tty_ENQ = user9 ? user9 : "\005";
148 event_start(TIME_SYNC); /* start the timer */
149 read_key(tty_ACK, TTY_ACK_SIZE - 1);
151 if (event_time(TIME_SYNC) > 400000 || tty_ACK[0] == '\0') {
152 /* These characters came from the user. Sigh. */
153 tty_can_sync = SYNC_FAILED;
154 ptext("\nThis program expects the ENQ sequence to be");
155 ptext(" answered with the ACK character. This will help");
156 ptext(" the program reestablish synchronization when");
157 ptextln(" the terminal is overrun with data.");
158 ptext("\nENQ sequence from (u9): ");
159 putln(expand(tty_ENQ));
160 ptext("ACK received: ");
161 putln(expand(tty_ACK));
162 len = user8 ? strlen(user8) : 0;
163 sprintf(temp, "Length of ACK %d. Expected length of ACK %d.",
164 (int) strlen(tty_ACK), len);
167 temp[0] = user8[len - 1];
169 ptext("Terminating character found in (u8): ");
175 tty_can_sync = SYNC_TESTED;
176 if ((len = strlen(tty_ACK)) == 1) {
177 /* single character acknowledge string */
178 ACK_terminator = tty_ACK[0];
182 tc = tty_ACK[len - 1];
184 ulen = strlen(user8);
185 if (tc == user8[ulen - 1]) {
186 /* ANSI style acknowledge string */
192 /* fixed length acknowledge string */
200 ** verify that the time tests are ready to run.
201 ** If the baud rate is not set then compute it.
208 if (tty_can_sync == SYNC_FAILED) {
213 if (tty_can_sync == SYNC_TESTED) {
215 if (ACK_terminator >= 0) {
216 ptext("ACK terminating character: ");
217 temp[0] = ACK_terminator;
219 ptextln(expand(temp));
221 sprintf(temp, "Fixed length ACK, %d characters",
226 if (tty_baud_rate == 0) {
227 sync_home(&sync_test_list[0], &status, &ch);
231 /*****************************************************************************
233 * Terminal performance tests
235 * Find out how fast the terminal can:
236 * 1) accept characters
237 * 2) scroll the screen
238 * 3) clear the screen
240 *****************************************************************************/
243 ** sync_home(test_list, status, ch)
256 if (!cursor_home && !cursor_address && !row_address) {
257 ptext("Terminal can not home cursor. ");
258 generic_done_message(t, state, ch);
261 if (skip_pad_test(t, state, ch,
262 "(home) Start baudrate search")) {
268 for (j = 1; j < lines; j++) {
269 for (k = 0; k < columns; k++) {
279 } while(still_testing());
280 pad_test_shutdown(t, auto_right_margin == 0);
281 /* note: tty_frame_size is the real framesize times two.
282 This takes care of half bits. */
283 rate = (tx_cps * tty_frame_size) >> 1;
284 if (rate > tty_baud_rate) {
285 tty_baud_rate = rate;
287 if (tx_cps > tty_cps) {
290 sprintf(temp, "%d characters per second. Baudrate %d ", tx_cps, j);
292 generic_done_message(t, state, ch);
296 ** sync_lines(test_list, status, ch)
298 ** How many newlines/second?
308 if (skip_pad_test(t, state, ch,
309 "(nel) Start scroll performance test")) {
315 sprintf(temp, "%d", test_complete);
317 put_newlines(repeats);
318 } while(still_testing());
319 pad_test_shutdown(t, 0);
320 j = sliding_scale(tx_count[0], 1000000, usec_run_time);
321 if (j > tty_newline_rate) {
322 tty_newline_rate = j;
324 sprintf(temp, "%d linefeeds per second. ", j);
326 generic_done_message(t, state, ch);
330 ** sync_clear(test_list, status, ch)
332 ** How many clear-screens/second?
343 ptext("Terminal can not clear-screen. ");
344 generic_done_message(t, state, ch);
347 if (skip_pad_test(t, state, ch,
348 "(clear) Start clear-screen performance test")) {
354 sprintf(temp, "%d", test_complete);
356 for (j = 0; j < repeats; j++) {
359 } while(still_testing());
360 pad_test_shutdown(t, 0);
361 j = sliding_scale(tx_count[0], 1000000, usec_run_time);
362 if (j > tty_clear_rate) {
365 sprintf(temp, "%d clear-screens per second. ", j);
367 generic_done_message(t, state, ch);
371 ** sync_summary(test_list, status, ch)
373 ** Print out the test results.
384 ptextln("Terminal size characters/sec linefeeds/sec clears/sec");
385 sprintf(size, "%dx%d", columns, lines);
386 sprintf(temp, "%-10s%-11s%11d %11d %11d", tty_basename, size,
387 tty_cps, tty_newline_rate, tty_clear_rate);
389 generic_done_message(t, state, ch);
395 ** Run at the beginning of the pad tests and function key tests
399 struct test_menu *menu)
402 if (tty_can_sync == SYNC_NOT_TESTED) {
405 if (menu->menu_title) {
407 ptextln(menu->menu_title);
412 ** sync_handshake(test_list, status, ch)
414 ** Test or retest the ENQ/ACK handshake
418 struct test_list *t GCC_UNUSED,
419 int *state GCC_UNUSED,
422 tty_can_sync = SYNC_NOT_TESTED;