micke wrote:
In OpenSolaris, when a real-time thread gets blocked it calls rt_yield(..) correct? or is 
there any other/more function that a thread "calls" when it gets blocked and 
put on a sleep queue?

Follow something like cv_wait code to work this out:

void
cv_wait(kcondvar_t *cvp, kmutex_t *mp)
{
        if (panicstr)
                return;

        ASSERT(curthread->t_schedflag & TS_DONT_SWAP);
        thread_lock(curthread);                 /* lock the thread */
        cv_block((condvar_impl_t *)cvp);
        ...
}

So we lock the current thread and call cv_block:

static void
cv_block(condvar_impl_t *cvp)
{
        kthread_t *t = curthread;
        klwp_t *lwp = ttolwp(t);
        sleepq_head_t *sqh;

        ASSERT(THREAD_LOCK_HELD(t));
        ASSERT(t != CPU->cpu_idle_thread);
        ASSERT(CPU_ON_INTR(CPU) == 0);
        ASSERT(t->t_wchan0 == NULL && t->t_wchan == NULL);
        ASSERT(t->t_state == TS_ONPROC);

        t->t_schedflag &= ~TS_SIGNALLED;
        CL_SLEEP(t);                    /* assign kernel priority */
        t->t_wchan = (caddr_t)cvp;
        t->t_sobj_ops = &cv_sobj_ops;
        DTRACE_SCHED(sleep);

        /*
         * The check for t_intr is to avoid doing the
         * account for an interrupt thread on the still-pinned
         * lwp's statistics.
         */
        if (lwp != NULL && t->t_intr == NULL) {
                lwp->lwp_ru.nvcsw++;
                (void) new_mstate(t, LMS_SLEEP);
        }

        sqh = SQHASH(cvp);
        disp_lock_enter_high(&sqh->sq_lock);
        if (cvp->cv_waiters < CV_MAX_WAITERS)
                cvp->cv_waiters++;
        ASSERT(cvp->cv_waiters <= CV_MAX_WAITERS);
        THREAD_SLEEP(t, &sqh->sq_lock);
        sleepq_insert(&sqh->sq_queue, t);
        /*
         * THREAD_SLEEP() moves curthread->t_lockp to point to the
         * lock sqh->sq_lock. This lock is later released by the caller
         * when it calls thread_unlock() on curthread.
         */
}

The CL_SLEEP for a realtime thread is a null operation (see disp/rt.c).
We compute a sleep queue hash for this cv, look that hash, transition
the thread state to TS_SLEEP, and then call sleepq_insert() to lob the
thread onto the sleep queue.  Returning to the caller cv_wait we then
have:

        thread_unlock_nopreempt(curthread);     /* unlock the waiters field */
        mutex_exit(mp);
        swtch();
        mutex_enter(mp);
}

So we unlock the thread and then call swtch() to run a new thread.

Cheers

Gavin

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to