xref: /titanic_52/usr/src/cmd/latencytop/common/dwrapper.c (revision a9c12afde877c596eed286ac3f1d518246e5cd1e)
115db2897SKrishnendu Sadhukhan - Sun Microsystems /*
215db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER START
315db2897SKrishnendu Sadhukhan - Sun Microsystems  *
415db2897SKrishnendu Sadhukhan - Sun Microsystems  * The contents of this file are subject to the terms of the
515db2897SKrishnendu Sadhukhan - Sun Microsystems  * Common Development and Distribution License (the "License").
615db2897SKrishnendu Sadhukhan - Sun Microsystems  * You may not use this file except in compliance with the License.
715db2897SKrishnendu Sadhukhan - Sun Microsystems  *
815db2897SKrishnendu Sadhukhan - Sun Microsystems  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
915db2897SKrishnendu Sadhukhan - Sun Microsystems  * or http://www.opensolaris.org/os/licensing.
1015db2897SKrishnendu Sadhukhan - Sun Microsystems  * See the License for the specific language governing permissions
1115db2897SKrishnendu Sadhukhan - Sun Microsystems  * and limitations under the License.
1215db2897SKrishnendu Sadhukhan - Sun Microsystems  *
1315db2897SKrishnendu Sadhukhan - Sun Microsystems  * When distributing Covered Code, include this CDDL HEADER in each
1415db2897SKrishnendu Sadhukhan - Sun Microsystems  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1515db2897SKrishnendu Sadhukhan - Sun Microsystems  * If applicable, add the following below this CDDL HEADER, with the
1615db2897SKrishnendu Sadhukhan - Sun Microsystems  * fields enclosed by brackets "[]" replaced with your own identifying
1715db2897SKrishnendu Sadhukhan - Sun Microsystems  * information: Portions Copyright [yyyy] [name of copyright owner]
1815db2897SKrishnendu Sadhukhan - Sun Microsystems  *
1915db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER END
2015db2897SKrishnendu Sadhukhan - Sun Microsystems  */
2115db2897SKrishnendu Sadhukhan - Sun Microsystems /*
2215db2897SKrishnendu Sadhukhan - Sun Microsystems  * Copyright (c) 2008-2009, Intel Corporation.
2315db2897SKrishnendu Sadhukhan - Sun Microsystems  * All Rights Reserved.
2415db2897SKrishnendu Sadhukhan - Sun Microsystems  */
2515db2897SKrishnendu Sadhukhan - Sun Microsystems 
2615db2897SKrishnendu Sadhukhan - Sun Microsystems #include <unistd.h>
2715db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdio.h>
2815db2897SKrishnendu Sadhukhan - Sun Microsystems #include <dtrace.h>
2915db2897SKrishnendu Sadhukhan - Sun Microsystems #include <string.h>
3015db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdlib.h>
3115db2897SKrishnendu Sadhukhan - Sun Microsystems #include <memory.h>
3215db2897SKrishnendu Sadhukhan - Sun Microsystems #include <limits.h>
3315db2897SKrishnendu Sadhukhan - Sun Microsystems 
3415db2897SKrishnendu Sadhukhan - Sun Microsystems #include "latencytop.h"
3515db2897SKrishnendu Sadhukhan - Sun Microsystems 
3615db2897SKrishnendu Sadhukhan - Sun Microsystems static dtrace_hdl_t *g_dtp = NULL;	/* dtrace handle */
3715db2897SKrishnendu Sadhukhan - Sun Microsystems static pid_t pid_self = -1;		/* PID of our own process */
3815db2897SKrishnendu Sadhukhan - Sun Microsystems 
3915db2897SKrishnendu Sadhukhan - Sun Microsystems /*
4015db2897SKrishnendu Sadhukhan - Sun Microsystems  * Ignore sched if sched is not tracked.
4115db2897SKrishnendu Sadhukhan - Sun Microsystems  * Also ignore ourselves (i.e., latencytop).
4215db2897SKrishnendu Sadhukhan - Sun Microsystems  */
4315db2897SKrishnendu Sadhukhan - Sun Microsystems #define	SHOULD_IGNORE(pid)		\
4415db2897SKrishnendu Sadhukhan - Sun Microsystems 	((!g_config.lt_cfg_trace_sched && 0 == (pid)) || pid_self == (pid))
4515db2897SKrishnendu Sadhukhan - Sun Microsystems 
4615db2897SKrishnendu Sadhukhan - Sun Microsystems /*
4715db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get an integer value from dtrace record.
4815db2897SKrishnendu Sadhukhan - Sun Microsystems  */
4915db2897SKrishnendu Sadhukhan - Sun Microsystems static uint64_t
5015db2897SKrishnendu Sadhukhan - Sun Microsystems rec_get_value(void *a, size_t b)
5115db2897SKrishnendu Sadhukhan - Sun Microsystems {
5215db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t ret = 0;
5315db2897SKrishnendu Sadhukhan - Sun Microsystems 
5415db2897SKrishnendu Sadhukhan - Sun Microsystems 	switch (b) {
5515db2897SKrishnendu Sadhukhan - Sun Microsystems 	case sizeof (uint64_t):
5615db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = *((uint64_t *)(a));
5715db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
5815db2897SKrishnendu Sadhukhan - Sun Microsystems 	case sizeof (uint32_t):
5915db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = *((uint32_t *)(a));
6015db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
6115db2897SKrishnendu Sadhukhan - Sun Microsystems 	case sizeof (uint16_t):
6215db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = *((uint16_t *)(a));
6315db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
6415db2897SKrishnendu Sadhukhan - Sun Microsystems 	case sizeof (uint8_t):
6515db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = *((uint8_t *)(a));
6615db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
6715db2897SKrishnendu Sadhukhan - Sun Microsystems 	default:
6815db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
6915db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
7015db2897SKrishnendu Sadhukhan - Sun Microsystems 
7115db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
7215db2897SKrishnendu Sadhukhan - Sun Microsystems }
7315db2897SKrishnendu Sadhukhan - Sun Microsystems 
7415db2897SKrishnendu Sadhukhan - Sun Microsystems /*
7515db2897SKrishnendu Sadhukhan - Sun Microsystems  * Callback to process aggregation lt_call_* (related to on/off cpu
7615db2897SKrishnendu Sadhukhan - Sun Microsystems  * activities) in the snapshot.
7715db2897SKrishnendu Sadhukhan - Sun Microsystems  */
7815db2897SKrishnendu Sadhukhan - Sun Microsystems static int
7915db2897SKrishnendu Sadhukhan - Sun Microsystems aggwalk_call(const dtrace_aggdata_t *data, lt_stat_type_t stat_type)
8015db2897SKrishnendu Sadhukhan - Sun Microsystems {
8115db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_aggdesc_t *aggdesc = data->dtada_desc;
8215db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_syminfo_t dts;
8315db2897SKrishnendu Sadhukhan - Sun Microsystems 	GElf_Sym sym;
8415db2897SKrishnendu Sadhukhan - Sun Microsystems 	caddr_t addr;
8515db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_t pid;
8615db2897SKrishnendu Sadhukhan - Sun Microsystems 	id_t tid;
8715db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned int stack_depth;
8815db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned int pc_size;
8915db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t pc;
9015db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t agg_value;
9115db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *ptr = NULL;
9215db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *buffer = NULL;
9315db2897SKrishnendu Sadhukhan - Sun Microsystems 	int ptrsize;
9415db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned int buffersize;
9515db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *tag = NULL;
9615db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned int priority;
9715db2897SKrishnendu Sadhukhan - Sun Microsystems 	enum { REC_PID = 1, REC_TID, REC_STACK, REC_TAG, REC_PRIO, REC_AGG,
9815db2897SKrishnendu Sadhukhan - Sun Microsystems 	    NREC };
9915db2897SKrishnendu Sadhukhan - Sun Microsystems 
10015db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Check action type */
10115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((aggdesc->dtagd_nrecs < NREC) ||
10215db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) ||
10315db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) ||
10415db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_TAG].dtrd_action != DTRACEACT_DIFEXPR) ||
10515db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_PRIO].dtrd_action != DTRACEACT_DIFEXPR) ||
10615db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action)) ||
10715db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_STACK].dtrd_action != DTRACEACT_STACK)) {
10815db2897SKrishnendu Sadhukhan - Sun Microsystems 
10915db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
11015db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
11115db2897SKrishnendu Sadhukhan - Sun Microsystems 
11215db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid = rec_get_value(
11315db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset,
11415db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_PID].dtrd_size);
11515db2897SKrishnendu Sadhukhan - Sun Microsystems 
11615db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (SHOULD_IGNORE(pid)) {
11715db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
11815db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
11915db2897SKrishnendu Sadhukhan - Sun Microsystems 
12015db2897SKrishnendu Sadhukhan - Sun Microsystems 	tid = rec_get_value(
12115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset,
12215db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_TID].dtrd_size);
12315db2897SKrishnendu Sadhukhan - Sun Microsystems 
12415db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Parse stack array from dtagd_rec */
12515db2897SKrishnendu Sadhukhan - Sun Microsystems 	stack_depth = aggdesc->dtagd_rec[REC_STACK].dtrd_arg;
12615db2897SKrishnendu Sadhukhan - Sun Microsystems 	pc_size = aggdesc->dtagd_rec[REC_STACK].dtrd_size / stack_depth;
12715db2897SKrishnendu Sadhukhan - Sun Microsystems 	addr = data->dtada_data + aggdesc->dtagd_rec[REC_STACK].dtrd_offset;
12815db2897SKrishnendu Sadhukhan - Sun Microsystems 	buffersize = (stack_depth * (2 * PATH_MAX + 2) + 1) * sizeof (char);
12915db2897SKrishnendu Sadhukhan - Sun Microsystems 	buffer = (char *)lt_malloc(buffersize);
13015db2897SKrishnendu Sadhukhan - Sun Microsystems 	ptr = buffer;
13115db2897SKrishnendu Sadhukhan - Sun Microsystems 	ptrsize = buffersize;
13215db2897SKrishnendu Sadhukhan - Sun Microsystems 
13315db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Print the stack */
13415db2897SKrishnendu Sadhukhan - Sun Microsystems 	while (stack_depth > 0) {
13515db2897SKrishnendu Sadhukhan - Sun Microsystems 		pc = rec_get_value(addr, pc_size);
13615db2897SKrishnendu Sadhukhan - Sun Microsystems 
13715db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (pc == 0) {
13815db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
13915db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
14015db2897SKrishnendu Sadhukhan - Sun Microsystems 
14115db2897SKrishnendu Sadhukhan - Sun Microsystems 		addr += pc_size;
14215db2897SKrishnendu Sadhukhan - Sun Microsystems 
14315db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (dtrace_lookup_by_addr(g_dtp, pc, &sym, &dts) == 0) {
14415db2897SKrishnendu Sadhukhan - Sun Microsystems 			int len;
14515db2897SKrishnendu Sadhukhan - Sun Microsystems 			len = snprintf(ptr, ptrsize,
14615db2897SKrishnendu Sadhukhan - Sun Microsystems 			    "%s`%s ", dts.dts_object, dts.dts_name);
14715db2897SKrishnendu Sadhukhan - Sun Microsystems 			ptrsize -= len;
14815db2897SKrishnendu Sadhukhan - Sun Microsystems 
14915db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (ptrsize <= 0) {
15015db2897SKrishnendu Sadhukhan - Sun Microsystems 				/*
15115db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * snprintf returns "desired" length, so
15215db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * reaching here means our buffer is full.
15315db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * Move ptr to the last byte of the buffer and
15415db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * break.
15515db2897SKrishnendu Sadhukhan - Sun Microsystems 				 */
15615db2897SKrishnendu Sadhukhan - Sun Microsystems 				ptr = &buffer[buffersize-1];
15715db2897SKrishnendu Sadhukhan - Sun Microsystems 				break;
15815db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else {
15915db2897SKrishnendu Sadhukhan - Sun Microsystems 				ptr += len;
16015db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
16115db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
16215db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
16315db2897SKrishnendu Sadhukhan - Sun Microsystems 
16415db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (ptr != buffer) {
16515db2897SKrishnendu Sadhukhan - Sun Microsystems 		/*
16615db2897SKrishnendu Sadhukhan - Sun Microsystems 		 * We have printed something, so it is safe to remove
16715db2897SKrishnendu Sadhukhan - Sun Microsystems 		 * the last ' '.
16815db2897SKrishnendu Sadhukhan - Sun Microsystems 		 */
16915db2897SKrishnendu Sadhukhan - Sun Microsystems 		*(ptr-1) = '\0';
17015db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
17115db2897SKrishnendu Sadhukhan - Sun Microsystems 
17215db2897SKrishnendu Sadhukhan - Sun Microsystems 	tag = (char *)data->dtada_data +
17315db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_TAG].dtrd_offset;
17415db2897SKrishnendu Sadhukhan - Sun Microsystems 
17515db2897SKrishnendu Sadhukhan - Sun Microsystems 	priority = rec_get_value(
17615db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_PRIO].dtrd_offset,
17715db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_PRIO].dtrd_size);
17815db2897SKrishnendu Sadhukhan - Sun Microsystems 
17915db2897SKrishnendu Sadhukhan - Sun Microsystems 	agg_value = rec_get_value(
18015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset,
18115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_AGG].dtrd_size);
18215db2897SKrishnendu Sadhukhan - Sun Microsystems 
18315db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_update(pid, tid, buffer, tag, priority, stat_type, agg_value);
18415db2897SKrishnendu Sadhukhan - Sun Microsystems 
18515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (buffer != NULL)  {
18615db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(buffer);
18715db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
18815db2897SKrishnendu Sadhukhan - Sun Microsystems 
18915db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
19015db2897SKrishnendu Sadhukhan - Sun Microsystems }
19115db2897SKrishnendu Sadhukhan - Sun Microsystems 
19215db2897SKrishnendu Sadhukhan - Sun Microsystems /*
19315db2897SKrishnendu Sadhukhan - Sun Microsystems  * Callback to process aggregation lt_named_* (related to lock spinning etc.),
19415db2897SKrishnendu Sadhukhan - Sun Microsystems  * in the snapshot.
19515db2897SKrishnendu Sadhukhan - Sun Microsystems  */
19615db2897SKrishnendu Sadhukhan - Sun Microsystems static int
19715db2897SKrishnendu Sadhukhan - Sun Microsystems aggwalk_named(const dtrace_aggdata_t *data, lt_stat_type_t stat_type)
19815db2897SKrishnendu Sadhukhan - Sun Microsystems {
19915db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_aggdesc_t *aggdesc = data->dtada_desc;
20015db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_t pid;
20115db2897SKrishnendu Sadhukhan - Sun Microsystems 	id_t tid;
20215db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t agg_value;
20315db2897SKrishnendu Sadhukhan - Sun Microsystems 	int cause_id;
20415db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *type = NULL;
20515db2897SKrishnendu Sadhukhan - Sun Microsystems 	enum { REC_PID = 1, REC_TID, REC_TYPE, REC_AGG, NREC };
20615db2897SKrishnendu Sadhukhan - Sun Microsystems 
20715db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Check action type */
20815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((aggdesc->dtagd_nrecs < NREC) ||
20915db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) ||
21015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) ||
21115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_TYPE].dtrd_action != DTRACEACT_DIFEXPR) ||
21215db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action))) {
21315db2897SKrishnendu Sadhukhan - Sun Microsystems 
21415db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
21515db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
21615db2897SKrishnendu Sadhukhan - Sun Microsystems 
21715db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid = rec_get_value(
21815db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset,
21915db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_PID].dtrd_size);
22015db2897SKrishnendu Sadhukhan - Sun Microsystems 
22115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (SHOULD_IGNORE(pid)) {
22215db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
22315db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
22415db2897SKrishnendu Sadhukhan - Sun Microsystems 
22515db2897SKrishnendu Sadhukhan - Sun Microsystems 	tid = rec_get_value(
22615db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset,
22715db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_TID].dtrd_size);
22815db2897SKrishnendu Sadhukhan - Sun Microsystems 
22915db2897SKrishnendu Sadhukhan - Sun Microsystems 	type = (char *)data->dtada_data
23015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    + aggdesc->dtagd_rec[REC_TYPE].dtrd_offset;
23115db2897SKrishnendu Sadhukhan - Sun Microsystems 	cause_id = lt_table_cause_from_name(type, 1, CAUSE_FLAG_SPECIAL);
23215db2897SKrishnendu Sadhukhan - Sun Microsystems 
23315db2897SKrishnendu Sadhukhan - Sun Microsystems 	agg_value = rec_get_value(
23415db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset,
23515db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_AGG].dtrd_size);
23615db2897SKrishnendu Sadhukhan - Sun Microsystems 
23715db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_update_cause(pid, tid, cause_id, stat_type, agg_value);
23815db2897SKrishnendu Sadhukhan - Sun Microsystems 
23915db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
24015db2897SKrishnendu Sadhukhan - Sun Microsystems 
24115db2897SKrishnendu Sadhukhan - Sun Microsystems }
24215db2897SKrishnendu Sadhukhan - Sun Microsystems 
24315db2897SKrishnendu Sadhukhan - Sun Microsystems /*
24415db2897SKrishnendu Sadhukhan - Sun Microsystems  * Callback to process aggregation lt_sync_* (related to synchronization
24515db2897SKrishnendu Sadhukhan - Sun Microsystems  * objects), in the snapshot.
24615db2897SKrishnendu Sadhukhan - Sun Microsystems  */
24715db2897SKrishnendu Sadhukhan - Sun Microsystems static int
24815db2897SKrishnendu Sadhukhan - Sun Microsystems aggwalk_sync(const dtrace_aggdata_t *data, lt_stat_type_t stat_type)
24915db2897SKrishnendu Sadhukhan - Sun Microsystems {
25015db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_aggdesc_t *aggdesc = data->dtada_desc;
25115db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_t pid;
25215db2897SKrishnendu Sadhukhan - Sun Microsystems 	id_t tid;
25315db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t agg_value;
25415db2897SKrishnendu Sadhukhan - Sun Microsystems 	int stype;
25515db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned long long wchan;
25615db2897SKrishnendu Sadhukhan - Sun Microsystems 	enum { REC_PID = 1, REC_TID, REC_STYPE, REC_WCHAN, REC_AGG, NREC };
25715db2897SKrishnendu Sadhukhan - Sun Microsystems 
25815db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Check action type */
25915db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((aggdesc->dtagd_nrecs < NREC) ||
26015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) ||
26115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) ||
26215db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_STYPE].dtrd_action != DTRACEACT_DIFEXPR) ||
26315db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (aggdesc->dtagd_rec[REC_WCHAN].dtrd_action != DTRACEACT_DIFEXPR) ||
26415db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action))) {
26515db2897SKrishnendu Sadhukhan - Sun Microsystems 
26615db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
26715db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
26815db2897SKrishnendu Sadhukhan - Sun Microsystems 
26915db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid = rec_get_value(
27015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset,
27115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_PID].dtrd_size);
27215db2897SKrishnendu Sadhukhan - Sun Microsystems 
27315db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (SHOULD_IGNORE(pid)) {
27415db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
27515db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
27615db2897SKrishnendu Sadhukhan - Sun Microsystems 
27715db2897SKrishnendu Sadhukhan - Sun Microsystems 	tid = rec_get_value(
27815db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset,
27915db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_TID].dtrd_size);
28015db2897SKrishnendu Sadhukhan - Sun Microsystems 
28115db2897SKrishnendu Sadhukhan - Sun Microsystems 	stype = rec_get_value(
28215db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_STYPE].dtrd_offset,
28315db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_STYPE].dtrd_size);
28415db2897SKrishnendu Sadhukhan - Sun Microsystems 
28515db2897SKrishnendu Sadhukhan - Sun Microsystems 	wchan = rec_get_value(
28615db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_WCHAN].dtrd_offset,
28715db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_WCHAN].dtrd_size);
28815db2897SKrishnendu Sadhukhan - Sun Microsystems 
28915db2897SKrishnendu Sadhukhan - Sun Microsystems 	agg_value = rec_get_value(
29015db2897SKrishnendu Sadhukhan - Sun Microsystems 	    data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset,
29115db2897SKrishnendu Sadhukhan - Sun Microsystems 	    aggdesc->dtagd_rec[REC_AGG].dtrd_size);
29215db2897SKrishnendu Sadhukhan - Sun Microsystems 
29315db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_update_sobj(pid, tid, stype, wchan, stat_type, agg_value);
29415db2897SKrishnendu Sadhukhan - Sun Microsystems 
29515db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
29615db2897SKrishnendu Sadhukhan - Sun Microsystems }
29715db2897SKrishnendu Sadhukhan - Sun Microsystems 
29815db2897SKrishnendu Sadhukhan - Sun Microsystems /*
29915db2897SKrishnendu Sadhukhan - Sun Microsystems  * Callback to process various aggregations in the snapshot. Called by
30015db2897SKrishnendu Sadhukhan - Sun Microsystems  * different aggwalk_* functions.
30115db2897SKrishnendu Sadhukhan - Sun Microsystems  */
30215db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
30315db2897SKrishnendu Sadhukhan - Sun Microsystems static int
30415db2897SKrishnendu Sadhukhan - Sun Microsystems aggwalk(const dtrace_aggdata_t *data, void *arg)
30515db2897SKrishnendu Sadhukhan - Sun Microsystems {
30615db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *tmp;
30715db2897SKrishnendu Sadhukhan - Sun Microsystems 	char buffer[32];
30815db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_type_t stat_type;
30915db2897SKrishnendu Sadhukhan - Sun Microsystems 	int (*func)(const dtrace_aggdata_t *, lt_stat_type_t);
31015db2897SKrishnendu Sadhukhan - Sun Microsystems 
31115db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) strncpy(buffer, data->dtada_desc->dtagd_name, sizeof (buffer));
31215db2897SKrishnendu Sadhukhan - Sun Microsystems 	buffer[sizeof (buffer) - 1] = '\0';
31315db2897SKrishnendu Sadhukhan - Sun Microsystems 	tmp = strtok(buffer, "_");
31415db2897SKrishnendu Sadhukhan - Sun Microsystems 
31515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tmp == NULL || strcmp(tmp, "lt") != 0) {
31615db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto done;
31715db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
31815db2897SKrishnendu Sadhukhan - Sun Microsystems 
31915db2897SKrishnendu Sadhukhan - Sun Microsystems 	tmp = strtok(NULL, "_");
32015db2897SKrishnendu Sadhukhan - Sun Microsystems 
32115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tmp == NULL) {
32215db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto done;
32315db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "call") == 0) {
32415db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = aggwalk_call;
32515db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "named") == 0) {
32615db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = aggwalk_named;
32715db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "sync") == 0) {
32815db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = aggwalk_sync;
32915db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else {
33015db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto done;
33115db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
33215db2897SKrishnendu Sadhukhan - Sun Microsystems 
33315db2897SKrishnendu Sadhukhan - Sun Microsystems 	tmp = strtok(NULL, "_");
33415db2897SKrishnendu Sadhukhan - Sun Microsystems 
33515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tmp == NULL) {
33615db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto done;
33715db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "count") == 0) {
33815db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_type = LT_STAT_COUNT;
33915db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "sum") == 0) {
34015db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_type = LT_STAT_SUM;
34115db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (strcmp(tmp, "max") == 0) {
34215db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_type = LT_STAT_MAX;
34315db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else {
34415db2897SKrishnendu Sadhukhan - Sun Microsystems 		goto done;
34515db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
34615db2897SKrishnendu Sadhukhan - Sun Microsystems 
34715db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) func(data, stat_type);
34815db2897SKrishnendu Sadhukhan - Sun Microsystems 
34915db2897SKrishnendu Sadhukhan - Sun Microsystems done:
35015db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* We have our data, so remove it from DTrace now */
35115db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (DTRACE_AGGWALK_REMOVE);
35215db2897SKrishnendu Sadhukhan - Sun Microsystems }
35315db2897SKrishnendu Sadhukhan - Sun Microsystems 
35415db2897SKrishnendu Sadhukhan - Sun Microsystems /*
35515db2897SKrishnendu Sadhukhan - Sun Microsystems  * Callback to handle event caused by DTrace dropping data.
35615db2897SKrishnendu Sadhukhan - Sun Microsystems  */
35715db2897SKrishnendu Sadhukhan - Sun Microsystems /*ARGSUSED*/
35815db2897SKrishnendu Sadhukhan - Sun Microsystems static int
35915db2897SKrishnendu Sadhukhan - Sun Microsystems drop_handler(const dtrace_dropdata_t *data, void *user)
36015db2897SKrishnendu Sadhukhan - Sun Microsystems {
36115db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_display_error("Drop: %s\n", data->dtdda_msg);
3621a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 	lt_drop_detected = B_TRUE;
36315db2897SKrishnendu Sadhukhan - Sun Microsystems 
36415db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Pretend nothing happened, so just continue */
36515db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (DTRACE_HANDLE_OK);
36615db2897SKrishnendu Sadhukhan - Sun Microsystems }
36715db2897SKrishnendu Sadhukhan - Sun Microsystems 
36815db2897SKrishnendu Sadhukhan - Sun Microsystems #ifndef EMBED_CONFIGS
36915db2897SKrishnendu Sadhukhan - Sun Microsystems /*
37015db2897SKrishnendu Sadhukhan - Sun Microsystems  * Copy the content from a "real" file into a temp file.
37115db2897SKrishnendu Sadhukhan - Sun Microsystems  */
37215db2897SKrishnendu Sadhukhan - Sun Microsystems static int
37315db2897SKrishnendu Sadhukhan - Sun Microsystems copy_tmp_file(const char *src, FILE *dst)
37415db2897SKrishnendu Sadhukhan - Sun Microsystems {
37515db2897SKrishnendu Sadhukhan - Sun Microsystems 	FILE *tmp = NULL;
37615db2897SKrishnendu Sadhukhan - Sun Microsystems 	char buffer[256];
37715db2897SKrishnendu Sadhukhan - Sun Microsystems 	int bytes;
37815db2897SKrishnendu Sadhukhan - Sun Microsystems 
37915db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((tmp = fopen(src, "r")) == NULL) {
38015db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
38115db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
38215db2897SKrishnendu Sadhukhan - Sun Microsystems 
38315db2897SKrishnendu Sadhukhan - Sun Microsystems 	while ((bytes = fread(buffer, 1, sizeof (buffer), tmp)) > 0) {
38415db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (fwrite(buffer, bytes, 1, dst) != 1) {
38515db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (-1);
38615db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
38715db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
38815db2897SKrishnendu Sadhukhan - Sun Microsystems 
38915db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) fclose(tmp);
39015db2897SKrishnendu Sadhukhan - Sun Microsystems 
39115db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
39215db2897SKrishnendu Sadhukhan - Sun Microsystems }
39315db2897SKrishnendu Sadhukhan - Sun Microsystems #endif
39415db2897SKrishnendu Sadhukhan - Sun Microsystems 
39515db2897SKrishnendu Sadhukhan - Sun Microsystems /*
39615db2897SKrishnendu Sadhukhan - Sun Microsystems  * DTrace initialization. D script starts running when this function returns.
39715db2897SKrishnendu Sadhukhan - Sun Microsystems  */
39815db2897SKrishnendu Sadhukhan - Sun Microsystems int
39915db2897SKrishnendu Sadhukhan - Sun Microsystems lt_dtrace_init(void)
40015db2897SKrishnendu Sadhukhan - Sun Microsystems {
40115db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_prog_t *prog;
40215db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_proginfo_t info;
40315db2897SKrishnendu Sadhukhan - Sun Microsystems 	int err;
40415db2897SKrishnendu Sadhukhan - Sun Microsystems 	FILE *fp_script = NULL;
405*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 	char tmp[64];
40615db2897SKrishnendu Sadhukhan - Sun Microsystems 
40715db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_self = getpid();
40815db2897SKrishnendu Sadhukhan - Sun Microsystems 
40915db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
41015db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Cannot open dtrace library: %s\n",
41115db2897SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(NULL, err));
41215db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
41315db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
41415db2897SKrishnendu Sadhukhan - Sun Microsystems 
41515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_handle_drop(g_dtp, &drop_handler, NULL) == -1) {
41615db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Cannot install DTrace handle: %s\n",
41715db2897SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(NULL, err));
41815db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
41915db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
42015db2897SKrishnendu Sadhukhan - Sun Microsystems 
42115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_enable_filter) {
42215db2897SKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define",
42315db2897SKrishnendu Sadhukhan - Sun Microsystems 		    "ENABLE_FILTER")) != 0) {
42415db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
42515db2897SKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option ENABLE_FILTER.\n");
42615db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (err);
42715db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
42815db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
42915db2897SKrishnendu Sadhukhan - Sun Microsystems 
43015db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_trace_syncobj) {
43115db2897SKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define",
43215db2897SKrishnendu Sadhukhan - Sun Microsystems 		    "ENABLE_SYNCOBJ")) != 0) {
43315db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
43415db2897SKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option ENABLE_SYNCOBJ.\n");
43515db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (err);
43615db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
43715db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
43815db2897SKrishnendu Sadhukhan - Sun Microsystems 
43915db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_trace_sched) {
44015db2897SKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define",
44115db2897SKrishnendu Sadhukhan - Sun Microsystems 		    "ENABLE_SCHED")) != 0) {
44215db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
443*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option ENABLE_SCHED.\n");
444*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			return (err);
445*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		}
446*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 	}
447*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 
448*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_trace_pid != 0) {
449*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		(void) snprintf(tmp, sizeof (tmp), "TRACE_PID=%u",
450*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		    g_config.lt_cfg_trace_pid);
451*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define", tmp)) != 0) {
452*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
453*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option TRACE_PID.\n");
454*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			return (err);
455*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		}
456*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 	}
457*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 
458*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_trace_pgid != 0) {
459*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		(void) snprintf(tmp, sizeof (tmp), "TRACE_PGID=%u",
460*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		    g_config.lt_cfg_trace_pgid);
461*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define", tmp)) != 0) {
462*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
463*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option TRACE_PGID.\n");
46415db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (err);
46515db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
46615db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
46715db2897SKrishnendu Sadhukhan - Sun Microsystems 
46815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (g_config.lt_cfg_low_overhead_mode) {
46915db2897SKrishnendu Sadhukhan - Sun Microsystems 		if ((err = dtrace_setopt(g_dtp, "define",
47015db2897SKrishnendu Sadhukhan - Sun Microsystems 		    "ENABLE_LOW_OVERHEAD")) != 0) {
47115db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_display_error(
472*a9c12afdSKrishnendu Sadhukhan - Sun Microsystems 			    "Failed to set option ENABLE_LOW_OVERHEAD.\n");
47315db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (err);
47415db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
47515db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
47615db2897SKrishnendu Sadhukhan - Sun Microsystems 
47715db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Create a temp file; libdtrace needs it for cpp(1) */
47815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((fp_script = tmpfile()) == NULL) {
47915db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Cannot create tmp file\n");
48015db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
48115db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
48215db2897SKrishnendu Sadhukhan - Sun Microsystems 
48315db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Copy the main D script into the temp file */
48415db2897SKrishnendu Sadhukhan - Sun Microsystems #ifdef EMBED_CONFIGS
48515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (fwrite(&latencytop_d_start,
48615db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (size_t)(&latencytop_d_end - &latencytop_d_start), 1, fp_script)
48715db2897SKrishnendu Sadhukhan - Sun Microsystems 	    != 1) {
48815db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Could not copy D script, fwrite() failed\n");
48915db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fclose(fp_script);
49015db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
49115db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
49215db2897SKrishnendu Sadhukhan - Sun Microsystems #else
49315db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (copy_tmp_file(DEFAULT_D_SCRIPT_NAME, fp_script) != 0) {
49415db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Cannot open script file %s\n",
49515db2897SKrishnendu Sadhukhan - Sun Microsystems 		    DEFAULT_D_SCRIPT_NAME);
49615db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fclose(fp_script);
49715db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
49815db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
49915db2897SKrishnendu Sadhukhan - Sun Microsystems #endif	/* EMBED_CONFIGS */
50015db2897SKrishnendu Sadhukhan - Sun Microsystems 
50115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (lt_table_append_trans(fp_script) != 0) {
50215db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fclose(fp_script);
50315db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
50415db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
50515db2897SKrishnendu Sadhukhan - Sun Microsystems 
50615db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) fseek(fp_script, 0, SEEK_SET);
50715db2897SKrishnendu Sadhukhan - Sun Microsystems 
50815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if ((prog = dtrace_program_fcompile(g_dtp, fp_script,
50915db2897SKrishnendu Sadhukhan - Sun Microsystems 	    DTRACE_C_CPP, 0, NULL)) == NULL) {
51015db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed to compile D script.\n");
51115db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) fclose(fp_script);
51215db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (dtrace_errno(g_dtp));
51315db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
51415db2897SKrishnendu Sadhukhan - Sun Microsystems 
51515db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) fclose(fp_script);
51615db2897SKrishnendu Sadhukhan - Sun Microsystems 
51715db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* Execute the D script */
51815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_program_exec(g_dtp, prog, &info) == -1) {
51915db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed to enable probes.\n");
52015db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (dtrace_errno(g_dtp));
52115db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
52215db2897SKrishnendu Sadhukhan - Sun Microsystems 
52315db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_go(g_dtp) != 0) {
52415db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed to run D script.\n");
52515db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (dtrace_errno(g_dtp));
52615db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
52715db2897SKrishnendu Sadhukhan - Sun Microsystems 
52815db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
52915db2897SKrishnendu Sadhukhan - Sun Microsystems }
53015db2897SKrishnendu Sadhukhan - Sun Microsystems 
53115db2897SKrishnendu Sadhukhan - Sun Microsystems /*
53215db2897SKrishnendu Sadhukhan - Sun Microsystems  * Worker function to move aggregate data to user space. Called periodically
53315db2897SKrishnendu Sadhukhan - Sun Microsystems  * to prevent the kernel from running out of memory.
53415db2897SKrishnendu Sadhukhan - Sun Microsystems  */
53515db2897SKrishnendu Sadhukhan - Sun Microsystems int
53615db2897SKrishnendu Sadhukhan - Sun Microsystems lt_dtrace_work(int force)
53715db2897SKrishnendu Sadhukhan - Sun Microsystems {
53815db2897SKrishnendu Sadhukhan - Sun Microsystems 	static uint64_t last_snap = 0;
53915db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t now = lt_millisecond();
54015db2897SKrishnendu Sadhukhan - Sun Microsystems 
54115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (!force && now - last_snap < g_config.lt_cfg_snap_interval) {
54215db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (last_snap + g_config.lt_cfg_snap_interval - now);
54315db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
54415db2897SKrishnendu Sadhukhan - Sun Microsystems 
54515db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_status(g_dtp) == -1) {
54615db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed when getting status: %s\n",
54715db2897SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
54815db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
54915db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
55015db2897SKrishnendu Sadhukhan - Sun Microsystems 
55115db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_aggregate_snap(g_dtp) != 0) {
55215db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed to snap aggregate: %s\n",
55315db2897SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
55415db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
55515db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
55615db2897SKrishnendu Sadhukhan - Sun Microsystems 
55715db2897SKrishnendu Sadhukhan - Sun Microsystems 	last_snap = now;
55815db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
55915db2897SKrishnendu Sadhukhan - Sun Microsystems }
56015db2897SKrishnendu Sadhukhan - Sun Microsystems 
56115db2897SKrishnendu Sadhukhan - Sun Microsystems /*
56215db2897SKrishnendu Sadhukhan - Sun Microsystems  * Walk through dtrace aggregator and collect data for latencytop to display.
56315db2897SKrishnendu Sadhukhan - Sun Microsystems  * Called immediately before UI update.
56415db2897SKrishnendu Sadhukhan - Sun Microsystems  */
56515db2897SKrishnendu Sadhukhan - Sun Microsystems int
56615db2897SKrishnendu Sadhukhan - Sun Microsystems lt_dtrace_collect(void)
56715db2897SKrishnendu Sadhukhan - Sun Microsystems {
56815db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (lt_dtrace_work(1) != 0) {
56915db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
57015db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
57115db2897SKrishnendu Sadhukhan - Sun Microsystems 
57215db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_aggregate_walk(g_dtp, aggwalk, NULL) != 0) {
57315db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("Failed to sort aggregate: %s\n",
57415db2897SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
57515db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
57615db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
57715db2897SKrishnendu Sadhukhan - Sun Microsystems 
57815db2897SKrishnendu Sadhukhan - Sun Microsystems 	/*
57915db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * Probably we don't need to clear again, because we have removed
58015db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * everything. Paranoid ?
58115db2897SKrishnendu Sadhukhan - Sun Microsystems 	 */
58215db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_aggregate_clear(g_dtp);
58315db2897SKrishnendu Sadhukhan - Sun Microsystems 
58415db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (0);
58515db2897SKrishnendu Sadhukhan - Sun Microsystems }
58615db2897SKrishnendu Sadhukhan - Sun Microsystems 
58715db2897SKrishnendu Sadhukhan - Sun Microsystems /*
58815db2897SKrishnendu Sadhukhan - Sun Microsystems  * dtrace clean up.
58915db2897SKrishnendu Sadhukhan - Sun Microsystems  */
5901a1f79f5SKrishnendu Sadhukhan - Sun Microsystems int
59115db2897SKrishnendu Sadhukhan - Sun Microsystems lt_dtrace_deinit(void)
59215db2897SKrishnendu Sadhukhan - Sun Microsystems {
5931a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 	int ret = 0;
5941a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 
5951a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 	if (dtrace_stop(g_dtp) != 0) {
5961a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 		lt_display_error("dtrace_stop failed: %s\n",
5971a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 		    dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
5981a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 		ret = -1;
5991a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 	}
6001a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 
60115db2897SKrishnendu Sadhukhan - Sun Microsystems 	dtrace_close(g_dtp);
6021a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 
6031a1f79f5SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
60415db2897SKrishnendu Sadhukhan - Sun Microsystems }
605