root/sys/cddl/dev/dtrace/dtrace_anon.c
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * DTrace Anonymous Enabling Functions
 */
static void
dtrace_anon_init(void *dummy)
{
        dtrace_state_t *state = NULL;
        dtrace_enabling_t *enab;

        mutex_enter(&cpu_lock);
        mutex_enter(&dtrace_provider_lock);
        mutex_enter(&dtrace_lock);

        dtrace_anon_property();

        mutex_exit(&cpu_lock);

        /*
         * If there are already providers, we must ask them to provide their
         * probes, and then match any anonymous enabling against them.  Note
         * that there should be no other retained enablings at this time:
         * the only retained enablings at this time should be the anonymous
         * enabling.
         */
        if (dtrace_anon.dta_enabling != NULL) {
                ASSERT(dtrace_retained == dtrace_anon.dta_enabling);

                dtrace_enabling_provide(NULL);
                state = dtrace_anon.dta_state;

                /*
                 * We couldn't hold cpu_lock across the above call to
                 * dtrace_enabling_provide(), but we must hold it to actually
                 * enable the probes.  We have to drop all of our locks, pick
                 * up cpu_lock, and regain our locks before matching the
                 * retained anonymous enabling.
                 */
                mutex_exit(&dtrace_lock);
                mutex_exit(&dtrace_provider_lock);

                mutex_enter(&cpu_lock);
                mutex_enter(&dtrace_provider_lock);
                mutex_enter(&dtrace_lock);

                if ((enab = dtrace_anon.dta_enabling) != NULL)
                        (void) dtrace_enabling_match(enab, NULL);

                mutex_exit(&cpu_lock);
        }

        mutex_exit(&dtrace_provider_lock);
        mutex_exit(&dtrace_lock);

        if (state != NULL) {
                /*
                 * If we created any anonymous state, set it going now.
                 */
                (void) dtrace_state_go(state, &dtrace_anon.dta_beganon);
        }
}