/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Routines to support shuttle synchronization objects
*/
#include <sys/schedctl.h>
/*
* Place the thread in question on the run q.
*/
static void
{
ASSERT(THREAD_LOCK_HELD(t));
/* Waiting on a shuttle */
t->t_flag &= ~T_WAKEABLE;
t->t_sobj_ops = NULL;
CL_SETRUN(t);
}
static kthread_t *
{
return (NULL);
}
/*ARGSUSED*/
static void
{
ASSERT(THREAD_LOCK_HELD(t));
*t_prip = p;
}
};
/*
* Mark the current thread as sleeping on a shuttle object, and
* resume the specified thread. The 't' thread must be marked as ONPROC.
*
* No locks other than 'l' should be held at this point.
*/
void
{
}
/*
* setting cpu_dispthread before changing thread state
* so that kernel preemption will be deferred to after swtch_to()
*/
cp->cpu_dispthread = t;
/*
* Set the wchan0 field so that /proc won't just do a setrun
* on this thread when trying to stop a process. Instead,
* /proc will mark the thread as VSTOPPED similar to threads
* that are blocked on user level condition variables.
*/
/*
* Update ustate records (there is no waitrq obviously)
*/
thread_lock_high(t);
t->t_flag &= ~T_WAKEABLE;
t->t_sobj_ops = NULL;
/*
* Make sure we end up on the right CPU if we are dealing with bound
* CPU's or processor partitions.
*/
aston(t);
}
/*
* We re-assign t_disp_queue and t_lockp of 't' here because
* 't' could have been preempted.
*/
thread_onproc(t, cp);
}
/*
* We can't call thread_unlock_high() here because t's thread lock
* could have changed by thread_onproc() call above to point to
* CPU->cpu_thread_lock.
*/
mutex_exit(l);
/*
* Make sure we didn't receive any important events while
* we weren't looking
*/
swtch_to(t);
/*
* Caller must check for ISSIG/lwp_sysabort conditions
* and clear lwp->lwp_asleep/lwp->lwp_sysabort
*/
}
/*
* Mark the current thread as sleeping on a shuttle object, and
* switch to a new thread.
* No locks other than 'l' should be held at this point.
*/
void
{
mutex_exit(l);
swtch();
/*
* Caller must check for ISSIG/lwp_sysabort conditions
* and clear lwp->lwp_asleep/lwp->lwp_sysabort
*/
}
/*
* Mark the specified thread as once again sleeping on a shuttle object. This
* routine is called to put a server thread -- one that was dequeued but for
* which shuttle_resume() was _not_ called -- back to sleep on a shuttle
* object. Because we don't hit the sched:::wakeup DTrace probe until
* shuttle_resume(), we do _not_ have a sched:::sleep probe here.
*/
void
{
thread_lock(t);
}
t->t_flag |= T_WAKEABLE;
t->t_sobj_ops = &shuttle_sobj_ops;
CL_INACTIVE(t);
THREAD_SLEEP(t, &shuttle_lock);
setrun(t);
}