static void paint_thread(void *arg) { (void) arg; hal_set_current_thread_name("paint"); // +1 so that it is a bit higher than regular sys threads t_current_set_priority(PHANTOM_SYS_THREAD_PRIO+1); while(1) { //hal_sleep_msec(10); hal_sem_acquire( &paint_sem ); if( !paint_request ) continue; if( prev_paint_request < paint_request ) { #if 0 if( no_paint_msec < MAX_NO_PAINT ) { prev_paint_request = paint_request; no_paint_msec += 10; continue; } #endif } prev_paint_request = paint_request = 0; no_paint_msec = 0; do_paint_area(); } }
static void mouse_push_event_thread(void *arg) { (void) arg; t_current_set_name("MouEvents"); t_current_set_priority(PHANTOM_SYS_THREAD_PRIO); while(1) { hal_sem_acquire( &mouse_sem ); if(video_drv->mouse_redraw_cursor != NULL) video_drv->mouse_redraw_cursor(); //hal_mutex_lock( &mouse_mutex ); struct ui_event e, e1; while( get_buf(&e) ) { if( peek_buf( &e1 ) ) { // We already have one more event and buttons state is the same? // Throw away current event, use next one. if( e1.m.buttons == e.m.buttons ) continue; } ev_q_put_any( &e ); } //hal_mutex_unlock( &mouse_mutex ); } }
//! This thread delivers events from main Q to windows static void ev_push_thread() { t_current_set_name("UIEventQ"); // +1 so that it is a bit higher than regular sys threads t_current_set_priority(PHANTOM_SYS_THREAD_PRIO+1); #if EVENTS_ENABLED && 1 while(1) { ev_remove_extra_unused(); struct ui_event *e; hal_mutex_lock( &ev_main_q_mutex ); while(queue_empty(&ev_main_event_q)) hal_cond_wait( &ev_have_event, &ev_main_q_mutex ); if(queue_empty(&ev_main_event_q)) panic("out of events"); queue_remove_first(&ev_main_event_q, e, struct ui_event *, echain); ev_events_in_q--; hal_mutex_unlock( &ev_main_q_mutex ); SHOW_FLOW(8, "%p", e); // Deliver to 'em ev_push_event(e); // window code will return when done //return_unused_event(e); } #else while(1) { hal_sleep_msec(20000); } #endif }
static void deferred_refdec_thread(void *a) { t_current_set_name("RefDec"); t_current_set_priority( THREAD_PRIO_HIGH ); while(!stop) { hal_mutex_lock( &deferred_refdec_mutex ); // TODO timed wait hal_cond_wait( &start_refdec_cond, &deferred_refdec_mutex ); STAT_INC_CNT(DEFERRED_REFDEC_RUNS); // Decide where to switch put pointer int new_put_ptr = REFDEC_BUFFER_HALF + 1; // first one used to check low half overflow // Was in upper page? if( refdec_put_ptr >= REFDEC_BUFFER_HALF ) new_put_ptr = 0; //int last_pos = atomic_set( &refdec_put_ptr, new_put_ptr); int last_pos = ATOMIC_FETCH_AND_SET( &refdec_put_ptr, new_put_ptr); int start_pos = (last_pos >= REFDEC_BUFFER_HALF) ? REFDEC_BUFFER_HALF+1 : 0; // Check that all VM threads are either sleep or passed an bytecode instr boundary phantom_check_threads_pass_bytecode_instr_boundary(); int pos; for( pos = start_pos; pos < last_pos; pos++ ) { pvm_object_storage_t volatile *os; os = refdec_buffer[pos]; assert( os->_ah.refCount > 0); do_ref_dec_p((pvm_object_storage_t *)os); } hal_cond_broadcast( &end_refdec_cond ); hal_mutex_unlock( &deferred_refdec_mutex ); } }