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; }
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); }
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; }
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; }