4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2008-2009, Intel Corporation.
23 * All Rights Reserved.
34 #include <sys/types.h>
37 #include "latencytop.h"
39 /* Pipe that breaks the event loop (and exits early) */
40 static int signal_pipe
[2];
43 * Get current system time in milliseconds (1e-3).
49 (void) gettimeofday(&p
, NULL
);
50 return ((uint64_t)p
.tv_sec
* 1000 + p
.tv_usec
/ 1000);
54 * Check if we are out of memory.
57 lt_check_null(void *p
)
60 (void) fprintf(stderr
, "Out of memory!\n");
70 lt_malloc(size_t size
)
72 void *ret
= malloc(size
);
80 * Safe alloc with memory cleared.
81 * It is named "zalloc" because its signature is different from
85 lt_zalloc(size_t size
)
87 void *ret
= calloc(size
, 1);
98 lt_strdup(const char *str
)
100 char *ret
= strdup(str
);
108 * Get string for current time, e.g. YYYY-MM-DD
111 lt_time_str(char *buffer
, int len
)
118 (void) gmtime_r(&t
, &tms
);
119 (void) asctime_r(&tms
, buffer
, len
);
121 for (i
= strlen(buffer
)-1; i
> 0; --i
) {
123 if (isspace(buffer
[i
])) {
132 * Retrieves the process's executable name and arguments from /proc.
135 lt_get_proc_field(pid_t pid
, lt_field_t field
)
142 (void) snprintf(name
, PATH_MAX
, "/proc/%d/psinfo", (int)pid
);
143 fd
= open(name
, O_RDONLY
);
149 ret
= read(fd
, (char *)&psinfo
, sizeof (psinfo_t
));
158 return (lt_strdup(psinfo
.pr_fname
));
159 case LT_FIELD_PSARGS
:
160 return (lt_strdup(psinfo
.pr_psargs
));
166 * Helper function to update the data structure.
169 lt_update_stat_value(lt_stat_data_t
*entry
,
170 lt_stat_type_t type
, uint64_t value
)
174 entry
->lt_s_count
+= value
;
177 entry
->lt_s_total
+= value
;
180 if (value
> entry
->lt_s_max
) {
181 entry
->lt_s_max
= value
;
190 * Helper function to sort on total.
193 lt_sort_by_total_desc(lt_stat_entry_t
*a
, lt_stat_entry_t
*b
)
195 g_assert(a
!= NULL
&& b
!= NULL
);
197 * lt_s_total is of type int64_t, so we can't simply return
198 * (b->lt_se_data.lt_s_total - a->lt_se_data.lt_s_total).
200 if (b
->lt_se_data
.lt_s_total
> a
->lt_se_data
.lt_s_total
) {
202 } else if (b
->lt_se_data
.lt_s_total
< a
->lt_se_data
.lt_s_total
) {
210 * Helper function to sort on max.
213 lt_sort_by_max_desc(lt_stat_entry_t
*a
, lt_stat_entry_t
*b
)
215 g_assert(a
!= NULL
&& b
!= NULL
);
217 if (b
->lt_se_data
.lt_s_max
> a
->lt_se_data
.lt_s_max
) {
219 } else if (b
->lt_se_data
.lt_s_max
< a
->lt_se_data
.lt_s_max
) {
227 * Helper function to sort on count.
230 lt_sort_by_count_desc(lt_stat_entry_t
*a
, lt_stat_entry_t
*b
)
232 g_assert(a
!= NULL
&& b
!= NULL
);
234 if (b
->lt_se_data
.lt_s_count
> a
->lt_se_data
.lt_s_count
) {
236 } else if (b
->lt_se_data
.lt_s_count
< a
->lt_se_data
.lt_s_count
) {
244 * Helper function to sort on average.
247 lt_sort_by_avg_desc(lt_stat_entry_t
*a
, lt_stat_entry_t
*b
)
251 g_assert(a
!= NULL
&& b
!= NULL
);
253 avg_a
= (double)a
->lt_se_data
.lt_s_total
/ a
->lt_se_data
.lt_s_count
;
254 avg_b
= (double)b
->lt_se_data
.lt_s_total
/ b
->lt_se_data
.lt_s_count
;
258 } else if (avg_b
< avg_a
) {
266 * Create pipe for signal handler and wakeup.
271 (void) pipe(signal_pipe
);
275 * Close the pipe used in signal handler.
278 lt_gpipe_deinit(void)
280 (void) close(signal_pipe
[0]);
281 (void) close(signal_pipe
[1]);
285 * Break early from the main loop.
288 lt_gpipe_break(const char *ch
)
290 (void) write(signal_pipe
[1], ch
, 1);
294 lt_gpipe_readfd(void)
296 return (signal_pipe
[0]);
300 * Check if the given file exists.
303 lt_file_exist(const char *name
)
307 if (stat64(name
, &st
) == 0) {