Exemplo n.º 1
0
int 
nk_rwlock_rd_unlock (nk_rwlock_t * l) 
{
    NK_PROFILE_ENTRY();
    DEBUG_PRINT("rwlock read unlock: %p\n", (void*)l);
    int flags = spin_lock_irq_save(&l->lock);
    --l->readers;
    spin_unlock_irq_restore(&l->lock, flags);
    NK_PROFILE_EXIT();
    return 0;
}
Exemplo n.º 2
0
uint8_t 
nk_rwlock_wr_lock_irq_save (nk_rwlock_t * l)
{
    int flags;
    NK_PROFILE_ENTRY();
    DEBUG_PRINT("rwlock write lock (irq): %p\n", (void*)l);

    while (1) {
        flags = spin_lock_irq_save(&l->lock);

        if (likely(l->readers == 0 )) {
            break;
        } else {
            spin_unlock_irq_restore(&l->lock, flags);
        }
    }

    NK_PROFILE_EXIT();
    return flags;
}
Exemplo n.º 3
0
/*
 * get_runnable_thread
 *
 * get the next thread in the specified thread's CPU
 *
 * NOTE: assumes that this thread *will* be run after this
 *
 *
 */
static nk_thread_t *
get_runnable_thread (uint32_t cpu)
{
    nk_thread_t * runnable   = NULL;
    nk_thread_queue_t * runq = NULL;
    nk_queue_entry_t * elm   = NULL;
    struct sys_info * sys = per_cpu_get(system);
    uint8_t flags;

    if (unlikely(cpu >= sys->num_cpus || !sys->cpus[cpu])) {
        ERROR_PRINT("Attempt to get thread on invalid CPU (%u)\n", cpu);
        return NULL;
    }

    runq = sys->cpus[cpu]->run_q;

    ASSERT(runq);

    if (nk_queue_empty(runq)) {
        return NULL;
    }

    flags = spin_lock_irq_save(&runq->lock);

    elm = nk_dequeue_first(runq);

    ASSERT(elm);

    runnable = container_of(elm, nk_thread_t, runq_node);

    if (!get_cur_thread()->is_idle && 
         get_cur_thread()->status == NK_THR_RUNNING) {

        /* the next thing is an idle thread, but do we have something else to run? */
        if (runnable->is_idle)  {

            if (!nk_queue_empty(runq)) {

                nk_thread_t * idle = runnable;
                elm = nk_dequeue_first(runq);

                ASSERT(elm);

                runnable = container_of(elm, nk_thread_t, runq_node);

                ASSERT(runnable);


                idle->status    = NK_THR_SUSPENDED;
                nk_enqueue_entry(runq, &(idle->runq_node));

                //nk_enqueue_thread_on_runq(idle, cpu);


            } else  {
                /* we put the idle thread back when it is the only thing on the queue */
                runnable->status = NK_THR_SUSPENDED;
                nk_enqueue_entry(runq, &(runnable->runq_node));
                //nk_enqueue_thread_on_runq(runnable, cpu);
                runnable  = NULL;
            }

        } else {
            /* all good, we switch to runnable */
        }

    } else {
        /* if we're the idle thread, we *ALWAYS* run the next thing */
    }

    if (runnable) {
        runnable->status = NK_THR_RUNNING;
    }

    spin_unlock_irq_restore(&runq->lock, flags);
    //irq_enable_restore(flags);
    return runnable;
}