static void control_enter(struct sml_control *control) { unsigned int old; /* lock; all updates so far must be acquired */ old = INACTIVE(ASYNC); if (cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC))) return; mutex_lock(&control->inactive_wait_lock); pthread_cleanup_push(cleanup_mutex_unlock, &control->inactive_wait_lock); old = INACTIVE(ASYNC); while (!cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC))) { cond_wait(&control->inactive_wait_cond, &control->inactive_wait_lock); old = INACTIVE(ASYNC); } pthread_cleanup_pop(1); }
static void control_leave(struct sml_control *control) { assert(load_relaxed(&control->state) == ACTIVE(ASYNC)); /* unlock; all updates so far must be released */ store_release(&control->state, INACTIVE(ASYNC)); if (load_relaxed(&stop_the_world_flag)) { mutex_lock(&control->inactive_wait_lock); cond_signal(&control->inactive_wait_cond); mutex_unlock(&control->inactive_wait_lock); } }
void imx233_pwm_setup(int channel, int period, int cdiv, int active, int active_state, int inactive, int inactive_state) { /* stop */ bool enable = imx233_pwm_is_enabled(channel); if(enable) imx233_pwm_enable(channel, false); /* setup pin */ imx233_pinctrl_setup_vpin(VPIN_PWM(channel), "pwm", PINCTRL_DRIVE_4mA, false); /* watch the order ! active THEN period * NOTE: the register value is period-1 */ HW_PWM_ACTIVEn(channel) = BF_OR2(PWM_ACTIVEn, ACTIVE(active), INACTIVE(inactive)); HW_PWM_PERIODn(channel) = BF_OR4(PWM_PERIODn, PERIOD(period - 1), ACTIVE_STATE(active_state), INACTIVE_STATE(inactive_state), CDIV(cdiv)); /* restore */ imx233_pwm_enable(channel, enable); }
void sml_check_internal(void *frame_pointer) { struct sml_control *control = tlv_get(current_control); void *old_frame_top; assert(load_relaxed(&control->state) == ACTIVE(ASYNC)); if (load_relaxed(&stop_the_world_flag)) { old_frame_top = control->frame_stack->top; if (!old_frame_top) control->frame_stack->top = frame_pointer; store_release(&control->state, INACTIVE(SYNC1)); mutex_lock(&control->inactive_wait_lock); cond_signal(&control->inactive_wait_cond); mutex_unlock(&control->inactive_wait_lock); control_enter(control); control->frame_stack->top = old_frame_top; } }