8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / latencytop / common / util.c
blob0d4173f196f74dff431e6f9c18d416138be31e71
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 2008-2009, Intel Corporation.
23 * All Rights Reserved.
26 #include <unistd.h>
27 #include <libintl.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <procfs.h>
33 #include <fcntl.h>
34 #include <sys/types.h>
35 #include <sys/stat.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).
45 uint64_t
46 lt_millisecond(void)
48 struct timeval p;
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.
56 void
57 lt_check_null(void *p)
59 if (p == NULL) {
60 (void) fprintf(stderr, "Out of memory!\n");
61 g_assert(0);
62 exit(2);
67 * Safe malloc.
69 void *
70 lt_malloc(size_t size)
72 void *ret = malloc(size);
74 lt_check_null(ret);
76 return (ret);
80 * Safe alloc with memory cleared.
81 * It is named "zalloc" because its signature is different from
82 * calloc() in stdlib.
84 void *
85 lt_zalloc(size_t size)
87 void *ret = calloc(size, 1);
89 lt_check_null(ret);
91 return (ret);
95 * Safe strdup.
97 char *
98 lt_strdup(const char *str)
100 char *ret = strdup(str);
102 lt_check_null(ret);
104 return (ret);
108 * Get string for current time, e.g. YYYY-MM-DD
110 void
111 lt_time_str(char *buffer, int len)
113 struct tm tms;
114 time_t t;
115 int i;
117 (void) time(&t);
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])) {
124 buffer[i] = '\0';
125 } else {
126 break;
132 * Retrieves the process's executable name and arguments from /proc.
134 char *
135 lt_get_proc_field(pid_t pid, lt_field_t field)
137 char name[PATH_MAX];
138 int fd;
139 int ret;
140 psinfo_t psinfo;
142 (void) snprintf(name, PATH_MAX, "/proc/%d/psinfo", (int)pid);
143 fd = open(name, O_RDONLY);
145 if (fd == -1) {
146 return (NULL);
149 ret = read(fd, (char *)&psinfo, sizeof (psinfo_t));
150 (void) close(fd);
152 if (ret < 0) {
153 return (NULL);
156 switch (field) {
157 case LT_FIELD_FNAME:
158 return (lt_strdup(psinfo.pr_fname));
159 case LT_FIELD_PSARGS:
160 return (lt_strdup(psinfo.pr_psargs));
162 return (NULL);
166 * Helper function to update the data structure.
168 void
169 lt_update_stat_value(lt_stat_data_t *entry,
170 lt_stat_type_t type, uint64_t value)
172 switch (type) {
173 case LT_STAT_COUNT:
174 entry->lt_s_count += value;
175 break;
176 case LT_STAT_SUM:
177 entry->lt_s_total += value;
178 break;
179 case LT_STAT_MAX:
180 if (value > entry->lt_s_max) {
181 entry->lt_s_max = value;
183 break;
184 default:
185 break;
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) {
201 return (1);
202 } else if (b->lt_se_data.lt_s_total < a->lt_se_data.lt_s_total) {
203 return (-1);
204 } else {
205 return (0);
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) {
218 return (1);
219 } else if (b->lt_se_data.lt_s_max < a->lt_se_data.lt_s_max) {
220 return (-1);
221 } else {
222 return (0);
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) {
235 return (1);
236 } else if (b->lt_se_data.lt_s_count < a->lt_se_data.lt_s_count) {
237 return (-1);
238 } else {
239 return (0);
244 * Helper function to sort on average.
247 lt_sort_by_avg_desc(lt_stat_entry_t *a, lt_stat_entry_t *b)
249 double avg_a, avg_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;
256 if (avg_b > avg_a) {
257 return (1);
258 } else if (avg_b < avg_a) {
259 return (-1);
260 } else {
261 return (0);
266 * Create pipe for signal handler and wakeup.
268 void
269 lt_gpipe_init(void)
271 (void) pipe(signal_pipe);
275 * Close the pipe used in signal handler.
277 void
278 lt_gpipe_deinit(void)
280 (void) close(signal_pipe[0]);
281 (void) close(signal_pipe[1]);
285 * Break early from the main loop.
287 void
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)
305 struct stat64 st;
307 if (stat64(name, &st) == 0) {
308 return (1);
309 } else {
310 return (0);