예제 #1
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;
}
예제 #2
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);
}
예제 #3
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;
}
예제 #4
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;
}