1179237Sjb/*
2179237Sjb * CDDL HEADER START
3179237Sjb *
4179237Sjb * The contents of this file are subject to the terms of the
5179237Sjb * Common Development and Distribution License (the "License").
6179237Sjb * You may not use this file except in compliance with the License.
7179237Sjb *
8179237Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9179237Sjb * or http://www.opensolaris.org/os/licensing.
10179237Sjb * See the License for the specific language governing permissions
11179237Sjb * and limitations under the License.
12179237Sjb *
13179237Sjb * When distributing Covered Code, include this CDDL HEADER in each
14179237Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15179237Sjb * If applicable, add the following below this CDDL HEADER, with the
16179237Sjb * fields enclosed by brackets "[]" replaced with your own identifying
17179237Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
18179237Sjb *
19179237Sjb * CDDL HEADER END
20179237Sjb *
21179237Sjb * $FreeBSD$
22179237Sjb */
23179237Sjb
24179237Sjb/*
25179237Sjb * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26179237Sjb * Use is subject to license terms.
27179237Sjb */
28179237Sjb
29179237Sjbvoid
30179237Sjbdtrace_vtime_enable(void)
31179237Sjb{
32179237Sjb	dtrace_vtime_state_t state, nstate = 0;
33179237Sjb
34179237Sjb	do {
35179237Sjb		state = dtrace_vtime_active;
36179237Sjb
37179237Sjb		switch (state) {
38179237Sjb		case DTRACE_VTIME_INACTIVE:
39179237Sjb			nstate = DTRACE_VTIME_ACTIVE;
40179237Sjb			break;
41179237Sjb
42179237Sjb		case DTRACE_VTIME_INACTIVE_TNF:
43179237Sjb			nstate = DTRACE_VTIME_ACTIVE_TNF;
44179237Sjb			break;
45179237Sjb
46179237Sjb		case DTRACE_VTIME_ACTIVE:
47179237Sjb		case DTRACE_VTIME_ACTIVE_TNF:
48179237Sjb			panic("DTrace virtual time already enabled");
49179237Sjb			/*NOTREACHED*/
50179237Sjb		}
51179237Sjb
52179237Sjb	} while	(dtrace_cas32((uint32_t *)&dtrace_vtime_active,
53179237Sjb	    state, nstate) != state);
54179237Sjb}
55179237Sjb
56179237Sjbvoid
57179237Sjbdtrace_vtime_disable(void)
58179237Sjb{
59179237Sjb	dtrace_vtime_state_t state, nstate = 0;
60179237Sjb
61179237Sjb	do {
62179237Sjb		state = dtrace_vtime_active;
63179237Sjb
64179237Sjb		switch (state) {
65179237Sjb		case DTRACE_VTIME_ACTIVE:
66179237Sjb			nstate = DTRACE_VTIME_INACTIVE;
67179237Sjb			break;
68179237Sjb
69179237Sjb		case DTRACE_VTIME_ACTIVE_TNF:
70179237Sjb			nstate = DTRACE_VTIME_INACTIVE_TNF;
71179237Sjb			break;
72179237Sjb
73179237Sjb		case DTRACE_VTIME_INACTIVE:
74179237Sjb		case DTRACE_VTIME_INACTIVE_TNF:
75179237Sjb			panic("DTrace virtual time already disabled");
76179237Sjb			/*NOTREACHED*/
77179237Sjb		}
78179237Sjb
79179237Sjb	} while	(dtrace_cas32((uint32_t *)&dtrace_vtime_active,
80179237Sjb	    state, nstate) != state);
81179237Sjb}
82179237Sjb
83179237Sjbvoid
84179237Sjbdtrace_vtime_switch(kthread_t *next)
85179237Sjb{
86179237Sjb	dtrace_icookie_t cookie;
87179237Sjb	hrtime_t ts;
88179237Sjb
89179237Sjb	cookie = dtrace_interrupt_disable();
90179237Sjb	ts = dtrace_gethrtime();
91179237Sjb
92179237Sjb	if (curthread->t_dtrace_start != 0) {
93179237Sjb		curthread->t_dtrace_vtime += ts - curthread->t_dtrace_start;
94179237Sjb		curthread->t_dtrace_start = 0;
95179237Sjb	}
96179237Sjb
97179237Sjb	if (next != NULL)
98179237Sjb		next->t_dtrace_start = ts;
99179237Sjb
100179237Sjb	dtrace_interrupt_enable(cookie);
101179237Sjb}
102