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; }
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_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; }
int ssx_thread_info_get(SsxThread* thread, SsxThreadState* state, SsxThreadPriority* priority, int* runnable) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_INFO); } if (state) { *state = thread->state; } if (priority) { *priority = thread->priority; } if (runnable) { *runnable = ((thread->state == SSX_THREAD_STATE_MAPPED) && __ssx_thread_queue_member(&__ssx_run_queue, thread->priority)); } return SSX_OK; }
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; }
int ssx_start_threads(void) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF(__ssx_kernel_mode_thread(), SSX_ILLEGAL_CONTEXT_THREAD); } __ssx_call_ssx_start_threads(); return 0; }
int ssx_thread_delete(SsxThread *thread) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT(); SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_DELETE); } __ssx_thread_delete(thread, SSX_THREAD_STATE_DELETED); return SSX_OK; }
int ssx_thread_at_priority(SsxThreadPriority priority, SsxThread **thread) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF((priority > SSX_THREADS) || (thread == 0), SSX_INVALID_ARGUMENT_THREAD_PRIORITY); } *thread = __ssx_thread_at_priority(priority); return SSX_OK; }
int ssx_timer_schedule_absolute(SsxTimer *timer, SsxTimebase timeout, SsxInterval period) { SsxMachineContext ctx; ssx_critical_section_enter(SSX_NONCRITICAL, &ctx); if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_SCHEDULE); SSX_ERROR_IF(__ssx_kernel_context_critical_interrupt(), SSX_ILLEGAL_CONTEXT_TIMER); } timer->timeout = timeout; timer->period = period; __ssx_timer_schedule(timer); ssx_critical_section_exit(&ctx); return SSX_OK; }
int ssx_timer_info_get(SsxTimer *timer, SsxTimebase *timeout, int *active) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_INFO); } if (timeout) { *timeout = timer->timeout; } if (active) { *active = timer_active(timer); } return SSX_OK; }
int ssx_timer_cancel(SsxTimer *timer) { SsxMachineContext ctx; int rc = SSX_OK; if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT(); SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_CANCEL); } ssx_critical_section_enter(SSX_NONCRITICAL, &ctx); rc = __ssx_timer_cancel(timer); ssx_critical_section_exit(&ctx); return rc; }
static int _ssx_timer_create(SsxTimer* timer, SsxTimerCallback callback, void* arg, int options) { if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF((timer == 0), SSX_INVALID_TIMER_AT_CREATE); } ssx_deque_element_create((SsxDeque*)timer); timer->timeout = 0; timer->period = 0; timer->callback = callback; timer->arg = arg; timer->options = options; return SSX_OK; }
int gpe_pba_parms_create(GpePbaParms *parms, int slave, int write_ttype, int write_tsize, int read_ttype) { pba_slvctln_t *slvctl, *mask; pba_slvrst_t* slvrst; pba_slvrst_t* slvrst_in_progress; uint64_t all1 = 0xffffffffffffffffull; if (SSX_ERROR_CHECK_API) { SSX_ERROR_IF((parms == 0), GPE_INVALID_OBJECT); SSX_ERROR_IF((slave < 0) || (slave >= PBA_SLAVES), GPE_INVALID_ARGUMENT); } parms->slave_id = slave; slvctl = &(parms->slvctl); mask = &(parms->mask); slvrst = &(parms->slvrst); slvrst_in_progress = &(parms->slvrst_in_progress); parms->slvctl_address = PBA_SLVCTLN(slave); slvrst->value = 0; slvrst->fields.set = PBA_SLVRST_SET(slave); slvrst_in_progress->value = 0; slvrst_in_progress->fields.in_prog = PBA_SLVRST_IN_PROG(slave); slvctl->value = 0; mask->value = 0; slvctl->fields.enable = 1; mask->fields.enable = all1; slvctl->fields.write_ttype = write_ttype; mask->fields.write_ttype = all1; slvctl->fields.write_tsize = write_tsize; mask->fields.write_tsize = all1; slvctl->fields.read_ttype = read_ttype; mask->fields.read_ttype = all1; if (read_ttype == PBA_READ_TTYPE_CI_PR_RD) { slvctl->fields.buf_invalidate_ctl = 1; mask->fields.buf_invalidate_ctl = all1; slvctl->fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE; mask->fields.read_prefetch_ctl = all1; } else { slvctl->fields.buf_invalidate_ctl = 0; mask->fields.buf_invalidate_ctl = all1; } mask->value = ~(mask->value); return 0; }