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; }
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; }
/* * 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; }