static int prd_msg_handle_init(struct opal_prd_msg *msg) { struct proc_chip *chip; lock(&ipoll_lock); for_each_chip(chip) { __ipoll_update_mask(chip->id, false, msg->init.ipoll); } unlock(&ipoll_lock); /* we're transitioning from inactive to active; send any pending tmgt * interrupts */ lock(&events_lock); prd_active = true; if (!prd_msg_inuse) send_pending_events(); unlock(&events_lock); return OPAL_SUCCESS; }
static void prd_msg_consumed(void *data) { struct opal_prd_msg *msg = data; uint32_t proc; uint8_t event = 0; lock(&events_lock); switch (msg->type) { case OPAL_PRD_MSG_TYPE_ATTN: proc = msg->attn.proc; /* If other ipoll events have been received in the time * between prd_msg creation and consumption, we'll need to * raise a separate ATTN message for those. So, we only * clear the event if we don't have any further ipoll_status * bits. */ ipoll_status[proc] &= ~msg->attn.ipoll_status; if (!ipoll_status[proc]) event = EVENT_ATTN; break; case OPAL_PRD_MSG_TYPE_OCC_ERROR: proc = msg->occ_error.chip; event = EVENT_OCC_ERROR; break; case OPAL_PRD_MSG_TYPE_OCC_RESET: proc = msg->occ_reset.chip; event = EVENT_OCC_RESET; break; default: return; } events[proc] &= ~event; prd_msg_inuse = false; send_pending_events(); unlock(&events_lock); }
static void __prd_event(uint32_t proc, uint8_t event) { events[proc] |= event; if (!prd_msg_inuse) send_pending_events(); }
Bool prima_one_loop_round( Bool wait, Bool careOfApplication) { XEvent ev, next_event; fd_set read_set, write_set, excpt_set; struct timeval timeout; int r, i, queued_events; PTimerSysData timer; if ( guts. applicationClose) return false; if (( queued_events = XEventsQueued( DISP, QueuedAlready))) { goto FetchAndProcess; } read_set = guts.read_set; write_set = guts.write_set; excpt_set = guts.excpt_set; if ( guts. oldest) { gettimeofday( &timeout, nil); if ( guts. oldest-> when. tv_sec < timeout. tv_sec || ( guts. oldest-> when. tv_sec == timeout. tv_sec && guts. oldest-> when. tv_usec <= timeout. tv_usec)) { timer = guts. oldest; apc_timer_start( timer-> who); if ( timer-> who == CURSOR_TIMER) { prima_cursor_tick(); } else if ( timer-> who == MENU_TIMER) { apc_timer_stop( MENU_TIMER); if ( guts. currentMenu) { XEvent ev; ev. type = MenuTimerMessage; prima_handle_menu_event( &ev, M(guts. currentMenu)-> w-> w, guts. currentMenu); } } else if ( timer-> who == MENU_UNFOCUS_TIMER) { prima_end_menu(); } else { prima_simple_message( timer-> who, cmTimer, false); } gettimeofday( &timeout, nil); } if ( guts. oldest && wait) { if ( guts. oldest-> when. tv_sec < timeout. tv_sec) { timeout. tv_sec = 0; timeout. tv_usec = 0; } else { timeout. tv_sec = guts. oldest-> when. tv_sec - timeout. tv_sec; if ( guts. oldest-> when. tv_usec < timeout. tv_usec) { if ( timeout. tv_sec == 0) { timeout. tv_sec = 0; timeout. tv_usec = 0; } else { timeout. tv_sec--; timeout. tv_usec = 1000000 - (timeout. tv_usec - guts. oldest-> when. tv_usec); } } else { timeout. tv_usec = guts. oldest-> when. tv_usec - timeout. tv_usec; } } if ( timeout. tv_sec > 0 || timeout. tv_usec > 200000) { timeout. tv_sec = 0; timeout. tv_usec = 200000; } } else { timeout. tv_sec = 0; if ( wait) timeout. tv_usec = 200000; else timeout. tv_usec = 0; } } else { timeout. tv_sec = 0; if ( wait) timeout. tv_usec = 200000; else timeout. tv_usec = 0; } if (( r = select( guts.max_fd+1, &read_set, &write_set, &excpt_set, &timeout)) > 0 && FD_ISSET( guts.connection, &read_set)) { if (( queued_events = XEventsQueued( DISP, QueuedAfterFlush)) <= 0) { /* just like tcl/perl tk do, to avoid an infinite loop */ RETSIGTYPE oldHandler = signal( SIGPIPE, SIG_IGN); XNoOp( DISP); XFlush( DISP); (void) signal( SIGPIPE, oldHandler); } FetchAndProcess: if ( queued_events && ( application || !careOfApplication)) { XNextEvent( DISP, &ev); XCHECKPOINT; queued_events--; while ( queued_events > 0) { if (!application && careOfApplication) return false; XNextEvent( DISP, &next_event); XCHECKPOINT; prima_handle_event( &ev, &next_event); guts. total_events++; queued_events = XEventsQueued( DISP, QueuedAlready); memcpy( &ev, &next_event, sizeof( XEvent)); } if (!application && careOfApplication) return false; guts. total_events++; prima_handle_event( &ev, nil); } XNoOp( DISP); XFlush( DISP); } else if ( r < 0) { list_first_that( guts.files, (void*)purge_invalid_watchers, nil); } else { if ( r > 0) { for ( i = 0; i < guts.files->count; i++) { PFile f = (PFile)list_at( guts.files,i); if ( FD_ISSET( f->fd, &read_set) && (f->eventMask & feRead)) { prima_simple_message((Handle)f, cmFileRead, false); break; } else if ( FD_ISSET( f->fd, &write_set) && (f->eventMask & feWrite)) { prima_simple_message((Handle)f, cmFileWrite, false); break; } else if ( FD_ISSET( f->fd, &excpt_set) && (f->eventMask & feException)) { prima_simple_message((Handle)f, cmFileException, false); break; } } } else { XNoOp( DISP); XFlush( DISP); } } send_pending_events(); perform_pending_paints(); kill_zombies(); return application != nilHandle; }