void stretch_window(void) { int dx, dy; int x0, x1, y0, y1; SETMOUSEICON(&mouse_box); move_mouse(screen, mouse, &mousex, &mousey, 0); SETMOUSEICON(DEFAULT_MOUSE_CURSOR); x0 = ACTIVE(x0); y0 = ACTIVE(y0); x1 = x0 + BIT_WIDE(ACTIVE(border)); y1 = y0 + BIT_HIGH(ACTIVE(border)); if (2 * (mousex - x0) < x1 - x0) x0 = x1; dx = mousex - x0; if (2 * (mousey - y0) < y1 - y0) y0 = y1; dy = mousey - y0; /* x0,y0 is corner farthest from mouse. x0+dx,y0+dx is mouse position */ get_rect(screen, mouse, x0, y0, &dx, &dy, 0); do_button(0); /* look for shape event here */ do_event(EVENT_SHAPE, active, E_MAIN); (void)shape(x0, y0, dx, dy); }
/* 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); } } #else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */ static void control_leave(struct sml_control *control) { unsigned int old; assert(IS_ACTIVE(load_relaxed(&control->state))); /* progress even phase to odd phase */ /* unlock; all updates so far must be released */ old = fetch_or(release, &control->state, INACTIVE_FLAG | 1); if (old == ACTIVE(PRESYNC1)) sync1_action(); else if (old == ACTIVE(PRESYNC2)) sync2_action(control); }
static struct sml_control * control_start(struct frame_stack_range *range) { struct sml_control *control; assert(tlv_get_or_init(current_control) == NULL); control = xmalloc(sizeof(struct sml_control)); #ifndef WITHOUT_MULTITHREAD atomic_init(&control->state, ACTIVE(ASYNC)); mutex_init(&control->inactive_wait_lock); cond_init(&control->inactive_wait_cond); #endif /* !WITHOUT_MULTITHREAD */ control->frame_stack = range; range->next = NULL; control->thread_local_heap = NULL; control->exn_object = NULL; tlv_set(current_control, control); control_register(control); /* thread local heap is allocated after the control is set up. */ control->thread_local_heap = sml_heap_mutator_init(); return control; }
/* 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); } #else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */ static void control_enter(struct sml_control *control) { activate(control); } #endif /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */ SML_PRIMITIVE void sml_leave() { struct sml_control *control = tlv_get(current_control); assert(control->frame_stack->top == NULL); control->frame_stack->top = CALLER_FRAME_END_ADDRESS(); control_leave(control); } SML_PRIMITIVE void sml_enter() { struct sml_control *control = tlv_get(current_control); control_enter(control); assert(control->frame_stack->top == CALLER_FRAME_END_ADDRESS()); control->frame_stack->top = NULL; } void * sml_leave_internal(void *frame_pointer) { struct sml_control *control = tlv_get(current_control); void *old_frame_top; old_frame_top = control->frame_stack->top; if (!old_frame_top) control->frame_stack->top = frame_pointer; control_leave(control); return old_frame_top; } void sml_enter_internal(void *old_frame_top) { struct sml_control *control = tlv_get(current_control); control_enter(control); control->frame_stack->top = old_frame_top; } #if defined WITHOUT_MULTITHREAD void sml_check_internal(void *frame_pointer ATTR_UNUSED) { } #elif defined WITHOUT_CONCURRENCY 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; } } #else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */ void sml_check_internal(void *frame_pointer) { struct sml_control *control = tlv_get(current_control); unsigned int state = load_relaxed(&control->state); void *old_frame_top; assert(IS_ACTIVE(state)); if (state == ACTIVE(PRESYNC1)) { store_relaxed(&control->state, ACTIVE(SYNC1)); sync1_action(); } else if (state == ACTIVE(PRESYNC2)) { store_relaxed(&control->state, ACTIVE(SYNC2)); old_frame_top = control->frame_stack->top; if (!old_frame_top) control->frame_stack->top = frame_pointer; sync2_action(control); control->frame_stack->top = old_frame_top; } }
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); } }
/* do nothing if another thread stops the world */ while (load_relaxed(&stop_the_world_flag)) cond_wait(&stop_the_world_cond, &stop_the_world_lock); mutex_unlock(&stop_the_world_lock); return 0; } store_relaxed(&stop_the_world_flag, 1); mutex_unlock(&stop_the_world_lock); return 1; } void sml_run_the_world() { mutex_lock(&stop_the_world_lock); store_relaxed(&stop_the_world_flag, 0); cond_broadcast(&stop_the_world_cond); mutex_unlock(&stop_the_world_lock); } #endif /* !defined WITHOUT_MULTITHREAD && defined WITHOUT_CONCURRENCY */ #if defined WITHOUT_MULTITHREAD static void control_register(struct sml_control *control ATTR_UNUSED) { } #else /* !WITHOUT_MULTITHREAD */ static void control_register(struct sml_control *control) { mutex_lock(&control_blocks_lock); atomic_init(&control->state, ACTIVE(new_thread_phase)); control->prev = control_blocks; control->next = NULL; if (control->prev) control->prev->next = control; control_blocks = control; mutex_unlock(&control_blocks_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; } }
/*{{{ redraw -- redraw screen, restore contents of saved windows*/ int redraw() { register WINDOW *win; #ifdef DEBUG dprintf(b)(stderr,"\r\n\tREDRAW\r\n"); #endif for(win=active;win != (WINDOW *) 0;win=W(next)) { if (W(flags)&W_ACTIVE) { save_win(win); do_event(EVENT_REDRAW,win,E_MAIN); } } erase_win(screen); if (active) { for(win=ACTIVE(prev);win != active;win=W(prev)) { restore_win(win); border(win,BLK_BDR,WH_BDR); } restore_win(active); border(active,BLK_BDR,WH_BDR); } }
/*{{{ shape -- reshape a window to specified dimensions*/ int shape(int x, int y, int dx, int dy) { int sx, sy, w, h; WINDOW *win; if (dx > 0) { sx = x; w = dx; } else { sx = x + dx; w = -dx; } if (dy > 0) { sy = y; h = dy; } else { sy = y + dy; h = -dy; } if (sx < 0) sx = 0; if (sx + w >= BIT_WIDE(screen)) w = BIT_WIDE(screen) - sx; if (sy + h >= BIT_HIGH(screen)) h = BIT_HIGH(screen) - sy; if (w < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.wide * MIN_X || h < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.high * MIN_Y) return (-1); #ifdef MGR_ALIGN alignwin(screen, &sx, &w, ACTIVE(borderwid)); #endif /* remove current window position */ save_win(active); erase_win(ACTIVE(border)); clip_bad(active); /* invalidate clip lists */ /* redraw remaining windows */ repair(active); /* adjust window state */ ACTIVE(x0) = sx; ACTIVE(y0) = sy; bit_destroy(ACTIVE(window)); bit_destroy(ACTIVE(border)); ACTIVE(border) = bit_create(screen, sx, sy, w, h); ACTIVE(window) = bit_create(ACTIVE(border), ACTIVE(borderwid), ACTIVE(borderwid), w - ACTIVE(borderwid) * 2, h - ACTIVE(borderwid) * 2); for (win = ACTIVE(next); win != (WINDOW *)0; win = W(next)) { if (W(flags) & W_ACTIVE && intersect(active, win)) save_win(win); } CLEAR(ACTIVE(window), PUTOP(BIT_CLR, ACTIVE(style))); border(active, BORDER_THIN); bit_blit(ACTIVE(border), 0, 0, BIT_WIDE(ACTIVE(save)) - ACTIVE(borderwid), BIT_HIGH(ACTIVE(save)) - ACTIVE(borderwid), BIT_SRC, ACTIVE(save), 0, 0); /* make sure character cursor is in a good spot */ if (ACTIVE(x) > BIT_WIDE(ACTIVE(window))) { ACTIVE(x) = 0; ACTIVE(y) += ((int)(ACTIVE(font)->head.high)); } if (ACTIVE(y) > BIT_HIGH(ACTIVE(window))) { #ifdef WIERD ACTIVE(y) = BIT_HIGH(ACTIVE(window)); scroll(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)), ((int)(ACTIVE(font)->head.high)), SWAPCOLOR(ACTIVE(style))); bit_blit(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high)), BIT_WIDE(ACTIVE(save)), ((int)(ACTIVE(font)->head.high)), BIT_SRC, ACTIVE(save), ACTIVE(borderwid), BIT_HIGH(ACTIVE(save)) - ((int)(ACTIVE(font)->head.high)) - ACTIVE(borderwid)); #else ACTIVE(y) = BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high)); #endif } bit_destroy(ACTIVE(save)); ACTIVE(save) = (BITMAP *)0; /* invalidate clip lists */ clip_bad(active); un_covered(); set_size(active); return (0); }