Print this page
arcstat
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/stat/common/common.c
+++ new/usr/src/cmd/stat/common/common.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include "statcommon.h"
27 27
28 28 #include <stdarg.h>
29 29 #include <signal.h>
30 30 #include <errno.h>
31 31 #include <string.h>
32 32 #include <stdlib.h>
33 33
34 34 extern char *cmdname;
35 35 extern int caught_cont;
36 36
37 37 /*PRINTFLIKE2*/
38 38 void
39 39 fail(int do_perror, char *message, ...)
40 40 {
41 41 va_list args;
42 42 int save_errno = errno;
43 43
44 44 va_start(args, message);
45 45 (void) fprintf(stderr, "%s: ", cmdname);
46 46 (void) vfprintf(stderr, message, args);
47 47 va_end(args);
48 48 if (do_perror)
49 49 (void) fprintf(stderr, ": %s", strerror(save_errno));
50 50 (void) fprintf(stderr, "\n");
51 51 exit(2);
52 52 }
53 53
54 54 /*
55 55 * Sleep until *wakeup + interval, keeping cadence where desired
56 56 *
57 57 * *wakeup - The time we last wanted to wake up. Updated.
58 58 * interval - We want to sleep until *wakeup + interval
59 59 * forever - Running for infinite periods, so cadence not important
60 60 * *caught_cont - Global set by signal handler if we got a SIGCONT
61 61 */
62 62 void
63 63 sleep_until(hrtime_t *wakeup, hrtime_t interval, int forever,
64 64 int *caught_cont)
65 65 {
66 66 hrtime_t now, pause, pause_left;
67 67 struct timespec pause_tv;
68 68 int status;
69 69
70 70 now = gethrtime();
71 71 pause = *wakeup + interval - now;
72 72
73 73 if (pause <= 0 || pause < (interval / 4))
74 74 if (forever || *caught_cont) {
75 75 /* Reset our cadence (see comment below) */
76 76 *wakeup = now + interval;
77 77 pause = interval;
78 78 } else {
79 79 /*
80 80 * If we got here, then the time between the
81 81 * output we just did, and the scheduled time
82 82 * for the next output is < 1/4 of our requested
83 83 * interval AND the number of intervals has been
84 84 * requested AND we have never caught a SIGCONT
85 85 * (so we have never been suspended). In this
86 86 * case, we'll try to stay to the desired
87 87 * cadence, and we will pause for 1/2 the normal
88 88 * interval this time.
89 89 */
90 90 pause = interval / 2;
91 91 *wakeup += interval;
92 92 }
93 93 else
94 94 *wakeup += interval;
↓ open down ↓ |
94 lines elided |
↑ open up ↑ |
95 95 if (pause < 1000)
96 96 /* Near enough */
97 97 return;
98 98
99 99 /* Now do the actual sleep */
100 100 pause_left = pause;
101 101 do {
102 102 pause_tv.tv_sec = pause_left / NANOSEC;
103 103 pause_tv.tv_nsec = pause_left % NANOSEC;
104 104 status = nanosleep(&pause_tv, (struct timespec *)NULL);
105 - if (status < 0)
105 + if (status < 0) {
106 106 if (errno == EINTR) {
107 107 now = gethrtime();
108 108 pause_left = *wakeup - now;
109 109 if (pause_left < 1000)
110 110 /* Near enough */
111 111 return;
112 112 } else {
113 113 fail(1, "nanosleep failed");
114 114 }
115 + }
115 116 } while (status != 0);
116 117 }
117 118
118 119 /*
119 120 * Signal handler - so we can be aware of SIGCONT
120 121 */
121 122 void
122 123 cont_handler(int sig_number)
123 124 {
124 125 /* Re-set the signal handler */
125 126 (void) signal(sig_number, cont_handler);
126 127 caught_cont = 1;
127 128 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX