void Stat_handle_message( sys_scatter *scat ) { sp_time now; sp_time delta; packet_header *pack_ptr; proc p; int ret; pack_ptr = (packet_header *)scat->elements[0].buf; if( ! ( pack_ptr->memb_id.proc_id == 15051963 && Conf_id_in_conf( Conf_ref(), pack_ptr->proc_id ) != -1 ) ) { Alarm( STATUS, "Stat_handle_message: Illegal monitor request\n"); return; } now = E_get_time(); delta = E_sub_time( now, Start_time ); GlobalStatus.sec = delta.sec; DL_send( Report_channel, pack_ptr->proc_id, pack_ptr->seq, &Report_scat ); ret = Conf_proc_by_id( pack_ptr->proc_id, &p ); if( ret < 0 ) Alarm( STATUS, "Stat_handle_message: sent status to Monitor at %d\n", pack_ptr->proc_id ); else Alarm( STATUS, "Stat_handle_message: sent status to Monitor at %s\n", p.name ); }
void E_handle_events(void) { static int Round_robin = 0; static const sp_time long_timeout = { 10000, 0}; /* liyu: 1w seconds? this is really bizzar! */ static const sp_time zero_sec = { 0, 0}; #ifdef BADCLOCK static const sp_time mili_sec = { 0, 1000}; int clock_sync; #endif int num_set; int treated; int fd; int fd_type; int i,j; sp_time timeout; struct timeval sel_timeout, wait_timeout; fd_set current_mask[NUM_FDTYPES]; time_event *temp_ptr; int first=1; #ifdef TESTTIME sp_time tmp_late,start,stop,req_time; /* DEBUGGING */ #endif #ifdef BADCLOCK clock_sync = 0; #endif for( Exit_events = 0 ; !Exit_events ; ) { Alarm( EVENTS, "E_handle_events: next event \n"); /* Handle time events */ timeout = long_timeout; #ifdef TESTTIME start = E_get_time(); #endif while( Time_queue != NULL ) { #ifdef BADCLOCK if ( clock_sync >= 0 ) { E_get_time(); clock_sync = -20; } #else E_get_time(); #endif if ( !first && E_compare_time( Now, Time_queue->t ) >= 0 ) { #ifdef TESTTIME tmp_late = E_sub_time( Now, Time_queue->t ); #endif temp_ptr = Time_queue; Time_queue = Time_queue->next; Alarm( EVENTS, "E_handle_events: exec time event \n"); #ifdef TESTTIME Alarm( DEBUG, "Events: TimeEv is %d %d late\n",tmp_late.sec, tmp_late.usec); #endif temp_ptr->func( temp_ptr->code, temp_ptr->data ); dispose( temp_ptr ); #ifdef BADCLOCK Now = E_add_time( Now, mili_sec ); clock_sync++; #else E_get_time(); #endif if (Exit_events) goto end_handler; }else{ timeout = E_sub_time( Time_queue->t, Now ); break; } } if (timeout.sec < 0 ) timeout.sec = timeout.usec = 0; /* this can happen until first is unset */ #ifdef TESTTIME stop = E_get_time(); tmp_late = E_sub_time(stop, start); Alarm(DEBUG, "Events: TimeEv's took %d %d to handle\n", tmp_late.sec, tmp_late.usec); #endif /* Handle fd events */ for( i=0; i < NUM_FDTYPES; i++ ) { current_mask[i] = Fd_mask[i]; } Alarm( EVENTS, "E_handle_events: poll select\n"); #ifdef TESTTIME req_time = zero_sec; #endif wait_timeout.tv_sec = zero_sec.sec; wait_timeout.tv_usec = zero_sec.usec; num_set = select( FD_SETSIZE, ¤t_mask[READ_FD], ¤t_mask[WRITE_FD], ¤t_mask[EXCEPT_FD], &wait_timeout ); if (num_set == 0 && !Exit_events) { #ifdef BADCLOCK clock_sync = 0; #endif for( i=0; i < NUM_FDTYPES; i++ ) { current_mask[i] = Fd_mask[i]; } Alarm( EVENTS, "E_handle_events: select with timeout (%d, %d)\n", timeout.sec,timeout.usec ); #ifdef TESTTIME req_time = E_add_time(req_time, timeout); #endif sel_timeout.tv_sec = timeout.sec; sel_timeout.tv_usec = timeout.usec; num_set = select( FD_SETSIZE, ¤t_mask[READ_FD], ¤t_mask[WRITE_FD], ¤t_mask[EXCEPT_FD], &sel_timeout ); } #ifdef TESTTIME start = E_get_time(); tmp_late = E_sub_time(start, stop); Alarm( DEBUG, "Events: Waiting for fd or timout took %d %d asked for %d %d\n", tmp_late.sec, tmp_late.usec, req_time.sec, req_time.usec); #endif /* Handle all high and medium priority fd events */ for( i=NUM_PRIORITY-1,treated=0; i > LOW_PRIORITY && num_set > 0 && !treated; i-- ) { for( j=0; j < Fd_queue[i].num_fds && num_set > 0; j++ ) { fd = Fd_queue[i].events[j].fd; fd_type = Fd_queue[i].events[j].fd_type; if( FD_ISSET( fd, ¤t_mask[fd_type] ) ) { Alarm( EVENTS, "E_handle_events: exec handler for fd %d, fd_type %d, priority %d\n", fd, fd_type, i ); Fd_queue[i].events[j].func( Fd_queue[i].events[j].fd, Fd_queue[i].events[j].code, Fd_queue[i].events[j].data ); treated = 1; num_set--; #ifdef BADCLOCK Now = E_add_time( Now, mili_sec ); clock_sync++; #else E_get_time(); #endif if (Exit_events) goto end_handler; } } } /* Don't handle timed events until all non-low-priority fd events have been handled * FIXME: This may or may not be right. If continual high priority events occur, then * timed events will starve, I'm not sure if that is better then what we have. We * could also set first=0 no matter what after trying the high events once, then * they will get a shot first, but after that timed events will also be handled. */ if (!treated) first = 0; #ifdef TESTTIME stop = E_get_time(); tmp_late = E_sub_time(stop, start); Alarm(DEBUG, "Events: High & Med took %d %d time to handle\n", tmp_late.sec, tmp_late.usec); #endif /* Handle one low priority fd event. However, verify that Active_priority still allows LOW_PRIORITY events. Active_priority can change because of calls to E_set_threshold() during the current select loop. */ for( i=0; i < Fd_queue[LOW_PRIORITY].num_fds && num_set > 0 && Active_priority == LOW_PRIORITY; i++ ) { j = ( i + Round_robin ) % Fd_queue[LOW_PRIORITY].num_fds; fd = Fd_queue[LOW_PRIORITY].events[j].fd; fd_type = Fd_queue[LOW_PRIORITY].events[j].fd_type; if( FD_ISSET( fd, ¤t_mask[fd_type] ) ) { Round_robin = ( j + 1 ) % Fd_queue[LOW_PRIORITY].num_fds; Alarm( EVENTS , "E_handle_events: exec ext fd event \n"); Fd_queue[LOW_PRIORITY].events[j].func( Fd_queue[LOW_PRIORITY].events[j].fd, Fd_queue[LOW_PRIORITY].events[j].code, Fd_queue[LOW_PRIORITY].events[j].data ); num_set--; #ifdef BADCLOCK Now = E_add_time( Now, mili_sec ); clock_sync++; #else E_get_time(); #endif if (Exit_events) goto end_handler; break; } } #ifdef TESTTIME start = E_get_time(); tmp_late = E_sub_time(start, stop); Alarm(DEBUG, "Events: Low priority took %d %d to handle\n", tmp_late.sec, tmp_late.usec); #endif } end_handler: /* Clean up data structures for exit OR restart of handler loop */ /* Actually nothing needs to be cleaned up to allow E_handle_events() * to be called again. The events are still registered (or not registered) * and the only state for the actual events loop is Exit_events which is reset * in the for loop. */ return; }