void mtx_unlock(mtx_t * mtx) { if (MTX_OPT(mtx, MTX_OPT_SLEEP) && (current_thread->wait_tim >= 0)) { timers_release(current_thread->wait_tim); current_thread->wait_tim = -1; } #ifdef configLOCK_DEBUG mtx->mtx_ldebug = NULL; #endif if (mtx->mtx_type == MTX_TYPE_TICKET) atomic_inc(&mtx->ticket.dequeue); mtx->mtx_lock = 0; if (MTX_OPT(mtx, MTX_OPT_DINT)) set_interrupt_state(cpu_istate); /* Restore priority ceiling. */ priceil_restore(mtx); #ifdef configMP cpu_sev(); /* Wakeup cores possibly waiting for lock. */ #endif }
int _mtx_trylock(mtx_t * mtx, char * whr) #endif { int ticket; int retval; if (MTX_OPT(mtx, MTX_OPT_DINT)) { cpu_istate = get_interrupt_state(); disable_interrupt(); } switch (mtx->mtx_type) { case MTX_TYPE_SPIN: retval = test_and_set((int *)(&mtx->mtx_lock)); break; case MTX_TYPE_TICKET: ticket = atomic_inc(&mtx->ticket.queue); if (atomic_read(&mtx->ticket.dequeue) == ticket) { mtx->mtx_lock = 1; return 0; /* Got it */ } else { atomic_dec(&mtx->ticket.queue); if (MTX_OPT(mtx, MTX_OPT_DINT)) set_interrupt_state(cpu_istate); return 1; /* No luck */ } break; default: MTX_TYPE_NOTSUP(); if (MTX_OPT(mtx, MTX_OPT_DINT)) set_interrupt_state(cpu_istate); return -ENOTSUP; } /* Handle priority ceiling. */ priceil_set(mtx); #ifdef configLOCK_DEBUG mtx->mtx_ldebug = whr; #endif return retval; }
/* * mono_thread_info_prepare_interrupt: * * The state of the thread info interrupt token is set to 'interrupted' which means that : * - if the thread calls one of the WaitFor functions, the function will return with * WAIT_IO_COMPLETION instead of waiting * - if the thread was waiting when this function was called, the wait will be broken * * It is possible that the wait functions return WAIT_IO_COMPLETION, but the target thread * didn't receive the interrupt signal yet, in this case it should call the wait function * again. This essentially means that the target thread will busy wait until it is ready to * process the interruption. */ MonoThreadInfoInterruptToken* mono_thread_info_prepare_interrupt (MonoThreadInfo *info) { MonoThreadInfoInterruptToken *token; token = set_interrupt_state (info); THREADS_INTERRUPT_DEBUG ("interrupt prepare tid %p token %p\n", mono_thread_info_get_tid (info), token); return token; }
void mono_thread_info_self_interrupt (void) { MonoThreadInfo *info; MonoThreadInfoInterruptToken *token; info = mono_thread_info_current (); g_assert (info); token = set_interrupt_state (info); g_assert (!token); THREADS_INTERRUPT_DEBUG ("interrupt self tid %p\n", mono_thread_info_get_tid (info)); }
int tms5220_status_read(void) { if (RDB_flag) { /* if last command was read, return data register */ RDB_flag = FALSE; return(data_register); } else { /* read status */ /* clear the interrupt pin */ set_interrupt_state(0); if (DEBUG_5220) logerror("Status read: TS=%d BL=%d BE=%d\n", talk_status, buffer_low, buffer_empty); return (talk_status << 7) | (buffer_low << 6) | (buffer_empty << 5); } }
int tms5220_status_read(void *chip) { struct tms5220 *tms = chip; if (tms->RDB_flag) { /* if last command was read, return data register */ tms->RDB_flag = FALSE; return(tms->data_register); } else { /* read status */ /* clear the interrupt pin */ set_interrupt_state(tms, 0); if (DEBUG_5220) logerror("Status read: TS=%d BL=%d BE=%d\n", tms->talk_status, tms->buffer_low, tms->buffer_empty); return (tms->talk_status << 7) | (tms->buffer_low << 6) | (tms->buffer_empty << 5); } }
int _mtx_lock(mtx_t * mtx, char * whr) #endif { int ticket; const int sleep_mode = MTX_OPT(mtx, MTX_OPT_SLEEP); #ifdef configLOCK_DEBUG unsigned deadlock_cnt = 0; #endif if (mtx->mtx_type == MTX_TYPE_TICKET) { ticket = atomic_inc(&mtx->ticket.queue); } if (MTX_OPT(mtx, MTX_OPT_DINT)) { cpu_istate = get_interrupt_state(); disable_interrupt(); } while (1) { #ifdef configLOCK_DEBUG /* * TODO Deadlock detection threshold should depend on lock type and * current priorities. */ if (++deadlock_cnt >= configSCHED_HZ * (configKLOCK_DLTHRES + 1)) { char * lwhr = (mtx->mtx_ldebug) ? mtx->mtx_ldebug : "?"; KERROR(KERROR_DEBUG, "Deadlock detected:\n%s WAITING\n%s LOCKED\n", whr, lwhr); deadlock_cnt = 0; } #endif if (sleep_mode && (current_thread->wait_tim == -2)) return -EWOULDBLOCK; switch (mtx->mtx_type) { case MTX_TYPE_SPIN: if (!test_and_set((int *)(&mtx->mtx_lock))) goto out; break; case MTX_TYPE_TICKET: if (atomic_read(&mtx->ticket.dequeue) == ticket) { mtx->mtx_lock = 1; goto out; } thread_yield(THREAD_YIELD_LAZY); break; default: MTX_TYPE_NOTSUP(); if (MTX_OPT(mtx, MTX_OPT_DINT)) set_interrupt_state(cpu_istate); return -ENOTSUP; } #ifdef configMP cpu_wfe(); /* Sleep until event. */ #endif } out: /* Handle priority ceiling. */ priceil_set(mtx); #ifdef configLOCK_DEBUG mtx->mtx_ldebug = whr; #endif return 0; }