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.
31 #include <sys/types.h>
37 #include "latencytop.h"
39 static GHashTable
*proc_table
= NULL
; /* pid -> char * */
40 static GHashTable
*klog_table
= NULL
; /* char * -> uint64_t total */
41 static char klog_filename
[PATH_MAX
] = DEFAULT_KLOG_FILE
;
42 static int klog_level
= LT_KLOG_LEVEL_NONE
;
45 print_proc(void *key
, const char *args
, FILE *fp
)
47 (void) fprintf(fp
, "%-8ld \"%s\"\n", (long)key
, args
);
51 print_stat(const char *key
, lt_stat_data_t
*log
, FILE *fp
)
53 (void) fprintf(fp
, "%lld, %lld, %lld, %s\n",
54 (long long)log
->lt_s_total
,
55 (long long)log
->lt_s_count
,
56 (long long)log
->lt_s_max
,
61 * Initialization for kernel logging.
66 if (klog_table
!= NULL
|| proc_table
!= NULL
) {
70 klog_table
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
71 (GDestroyNotify
)free
, (GDestroyNotify
)free
);
72 lt_check_null(klog_table
);
74 proc_table
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
75 NULL
, (GDestroyNotify
)free
);
76 lt_check_null(proc_table
);
83 lt_klog_set_log_file(const char *filename
)
88 g_assert(strlen(filename
) < sizeof (klog_filename
));
90 file_exist
= lt_file_exist(filename
);
91 /* Test if we can write to the file */
92 fp
= fopen(filename
, "a");
99 /* Don't leave empty file around */
101 (void) unlink(filename
);
104 (void) strncpy(klog_filename
, filename
,
105 sizeof (klog_filename
));
114 lt_klog_set_log_level(int level
)
116 if (level
< 0 || level
> (int)LT_KLOG_LEVEL_ALL
) {
126 * Write content to log file.
134 if (klog_level
== LT_KLOG_LEVEL_NONE
) {
138 g_assert(klog_table
!= NULL
&& proc_table
!= NULL
);
139 fp
= fopen(klog_filename
, "a");
145 lt_time_str(buffer
, sizeof (buffer
));
147 (void) fprintf(fp
, "# Log generated at %s by %s\n", buffer
, TITLE
);
148 (void) fprintf(fp
, "# List of processes\n");
149 (void) fprintf(fp
, "PID, CMD\n");
150 g_hash_table_foreach(proc_table
, (GHFunc
)print_proc
, fp
);
152 (void) fprintf(fp
, "# Statistics\n");
153 (void) fprintf(fp
, "TOTAL, COUNT, MAX, PID, KSTACK\n");
154 g_hash_table_foreach(klog_table
, (GHFunc
)print_stat
, fp
);
160 * Clean up. It flushes all log content in memory to log file.
165 if (klog_table
!= NULL
) {
166 g_hash_table_destroy(klog_table
);
170 if (proc_table
!= NULL
) {
171 g_hash_table_destroy(proc_table
);
177 * Write a kernel stack and its statistics to log file. Only "total" will
178 * be logged, others are internally discarded.
182 lt_klog_log(int level
, pid_t pid
, char *stack
,
183 lt_stat_type_t type
, uint64_t value
)
185 lt_stat_data_t
*entry
= NULL
;
190 if ((level
& klog_level
) == 0) {
194 g_assert(klog_table
!= NULL
&& proc_table
!= NULL
);
195 psargs
= (char *)g_hash_table_lookup(proc_table
,
196 LT_INT_TO_POINTER(pid
));
198 if (psargs
== NULL
) {
199 psargs
= lt_get_proc_field(pid
, LT_FIELD_PSARGS
);
201 if (psargs
== NULL
) {
202 psargs
= lt_get_proc_field(pid
, LT_FIELD_FNAME
);
205 if (psargs
== NULL
) {
209 g_hash_table_insert(proc_table
,
210 LT_INT_TO_POINTER(pid
), psargs
);
213 str_len
= strlen(stack
) + 20;
214 str
= lt_malloc(str_len
);
215 (void) snprintf(str
, str_len
, "%ld, \"%s\"", pid
, stack
);
216 entry
= (lt_stat_data_t
*)g_hash_table_lookup(klog_table
, str
);
219 entry
= (lt_stat_data_t
*)lt_zalloc(sizeof (lt_stat_data_t
));
220 g_hash_table_insert(klog_table
, str
, entry
);
225 lt_update_stat_value(entry
, type
, value
);