Ejemplo n.º 1
0
int
ssx_sleep_absolute(SsxTimebase time)
{
    SsxMachineContext ctx;
    SsxThread *current;

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_UNLESS_THREAD_CONTEXT();
    }

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    current = (SsxThread *)__ssx_current_thread;

    current->timer.timeout = time;
    __ssx_timer_schedule(&(current->timer));

    current->flags |= SSX_THREAD_FLAG_TIMER_PEND;

    SSX_TRACE_THREAD_SLEEP(current->priority);

    __ssx_thread_queue_delete(&__ssx_run_queue, current->priority);
    __ssx_schedule();

    current->flags &= ~(SSX_THREAD_FLAG_TIMER_PEND | SSX_THREAD_FLAG_TIMED_OUT);

    ssx_critical_section_exit(&ctx);

    return SSX_OK;
}
Ejemplo n.º 2
0
int
ssx_thread_suspend(SsxThread *thread)
{
    SsxMachineContext ctx;

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
        SSX_ERROR_IF((thread == 0), SSX_INVALID_THREAD_AT_SUSPEND1);
    }

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_IF_CRITICAL(!__ssx_thread_is_active(thread),
                              SSX_INVALID_THREAD_AT_SUSPEND2,
                              &ctx);
    }

    if (__ssx_thread_is_mapped(thread)) {

        SSX_TRACE_THREAD_SUSPENDED(thread->priority);
        __ssx_thread_unmap(thread);
        __ssx_schedule();
    }

    ssx_critical_section_exit(&ctx);

    return SSX_OK;
}
Ejemplo n.º 3
0
int
ssx_thread_resume(SsxThread *thread)
{
    SsxMachineContext ctx;

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
        SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_RESUME1);
    }

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_IF_CRITICAL(!__ssx_thread_is_active(thread),
                              SSX_INVALID_THREAD_AT_RESUME2,
                              &ctx);
    }

    if (!__ssx_thread_is_mapped(thread)) {

        if (SSX_ERROR_CHECK_API) {
            SSX_ERROR_IF_CRITICAL(__ssx_priority_map[thread->priority] != 0,
                                  SSX_PRIORITY_IN_USE_AT_RESUME,
                                  &ctx);
        }
        __ssx_thread_map(thread);
        __ssx_schedule();
    }

    ssx_critical_section_exit(&ctx);

    return SSX_OK;
}
Ejemplo n.º 4
0
void
__ssx_thread_timeout(void *arg)
{
    SsxThread *thread = (SsxThread *)arg;

    switch (thread->state) {

    case SSX_THREAD_STATE_MAPPED:
        if (!__ssx_thread_is_runnable(thread)) {
            thread->flags |= SSX_THREAD_FLAG_TIMED_OUT;
            __ssx_thread_queue_insert(&__ssx_run_queue, thread->priority);
            __ssx_schedule();
        }
        break;

    case SSX_THREAD_STATE_SUSPENDED_RUNNABLE:
        break;

    case SSX_THREAD_STATE_SUSPENDED_BLOCKED:
        thread->flags |= SSX_THREAD_FLAG_TIMED_OUT;
        thread->state = SSX_THREAD_STATE_SUSPENDED_RUNNABLE;
        break;

    default:
        SSX_PANIC(SSX_THREAD_TIMEOUT_STATE);
    }
}
Ejemplo n.º 5
0
void
__ssx_thread_delete(SsxThread *thread, SsxThreadState final_state)
{
    SsxMachineContext ctx;
    int mapped;

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    mapped = __ssx_thread_is_mapped(thread);

    if (mapped) {
        __ssx_thread_unmap(thread);
    }

    __ssx_timer_cancel(&(thread->timer));
    thread->state = final_state;

    if (mapped) {

        if (SSX_KERNEL_TRACE_ENABLE) {
            if (final_state == SSX_THREAD_STATE_DELETED) {
                SSX_TRACE_THREAD_DELETED(thread->priority);
            } else {
                SSX_TRACE_THREAD_COMPLETED(thread->priority);
            }
        }                
    
        if (thread == __ssx_current_thread) {
            __ssx_current_thread = 0;
        }
        __ssx_schedule();
    }

    ssx_critical_section_exit(&ctx);
}
Ejemplo n.º 6
0
int
ssx_thread_priority_swap(SsxThread* thread_a, SsxThread* thread_b)
{
    SsxMachineContext ctx;
    SsxThreadPriority priority_a, priority_b;
    int mapped_a, mapped_b;

    if (SSX_ERROR_CHECK_API) {
        SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
        SSX_ERROR_IF((thread_a == 0) ||  (thread_b == 0), 
                       SSX_INVALID_THREAD_AT_SWAP1);
    }

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    if (thread_a != thread_b) {

        mapped_a = __ssx_thread_is_mapped(thread_a);
        mapped_b = __ssx_thread_is_mapped(thread_b);
        priority_a = thread_a->priority;
        priority_b = thread_b->priority;

        if (SSX_ERROR_CHECK_API) {
            int priority_in_use;
            SSX_ERROR_IF_CRITICAL((priority_a > SSX_THREADS) ||
                                  (priority_b > SSX_THREADS),
                                  SSX_INVALID_THREAD_AT_SWAP2,
                                  &ctx);
            priority_in_use = 
                (mapped_a && !mapped_b &&
                 (__ssx_thread_at_priority(priority_b) != 0)) ||
                (!mapped_a && mapped_b && 
                 (__ssx_thread_at_priority(priority_a) != 0));
            SSX_ERROR_IF_CRITICAL(priority_in_use, 
                                  SSX_PRIORITY_IN_USE_AT_SWAP, &ctx); 
        }

        if (mapped_a) {
            __ssx_thread_unmap(thread_a);
        }
        if (mapped_b) {
            __ssx_thread_unmap(thread_b);
        }            
        thread_a->priority = priority_b;
        thread_b->priority = priority_a;
        if (mapped_a) {
            __ssx_thread_map(thread_a);
        }
        if (mapped_b) {
            __ssx_thread_map(thread_b);
        }
        __ssx_schedule();
    }

    ssx_critical_section_exit(&ctx);

    return SSX_OK;
}
Ejemplo n.º 7
0
int
ssx_thread_priority_change(SsxThread*         thread,
                           SsxThreadPriority new_priority,
                           SsxThreadPriority* old_priority)
{
    SsxMachineContext ctx;
    SsxThreadPriority priority;

    if (SSX_ERROR_CHECK_API)
    {
        SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
        SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_CHANGE);
        SSX_ERROR_IF(new_priority > SSX_THREADS,
                     SSX_INVALID_ARGUMENT_THREAD_CHANGE);
    }

    ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);

    priority = thread->priority;

    if (priority != new_priority)
    {

        if (!__ssx_thread_is_mapped(thread))
        {

            thread->priority = new_priority;

        }
        else
        {

            if (SSX_ERROR_CHECK_API)
            {
                SSX_ERROR_IF_CRITICAL(__ssx_priority_map[new_priority] != 0,
                                      SSX_PRIORITY_IN_USE_AT_CHANGE,
                                      &ctx);
            }

            __ssx_thread_unmap(thread);
            thread->priority = new_priority;
            __ssx_thread_map(thread);
            __ssx_schedule();
        }
    }

    if (old_priority)
    {
        *old_priority = priority;
    }

    ssx_critical_section_exit(&ctx);

    return SSX_OK;
}