Beispiel #1
0
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
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #4
0
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));
}
Beispiel #5
0
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);
	}
}
Beispiel #6
0
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);
	}
}
Beispiel #7
0
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;
}