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 ); }
int E_init(void) { int i,ret; Time_queue = NULL; ret = Mem_init_object(TIME_EVENT, sizeof(time_event), 100,0); if (ret < 0) { Alarm(EXIT, "E_Init: Failure to Initialize TIME_EVENT memory objects\n"); } for ( i=0; i < NUM_PRIORITY; i++ ) { Fd_queue[i].num_fds = 0; Fd_queue[i].num_active_fds = 0; } for ( i=0; i < NUM_FDTYPES; i++ ) { FD_ZERO( &Fd_mask[i] ); } Active_priority = LOW_PRIORITY; E_get_time(); Alarm( EVENTS, "E_init: went ok\n"); return( 0 ); }
void Stat_init() { int16 dummy_port = 0; Start_time = E_get_time(); Report_channel = DL_init_channel( SEND_CHANNEL, dummy_port, 0, Conf_my().id ); Report_scat.num_elements = 2; Report_scat.elements[0].len = sizeof( packet_header ); Report_scat.elements[0].buf = (char *)&Pack; Report_scat.elements[1].len = sizeof( status ); Report_scat.elements[1].buf = (char *)&GlobalStatus; Pack.type = STATUS_TYPE; Pack.type = Set_endian( Pack.type ); Pack.data_len = sizeof( status ); Pack.proc_id = Conf_my().id; GlobalStatus.major_version = SP_MAJOR_VERSION; GlobalStatus.minor_version = SP_MINOR_VERSION; GlobalStatus.patch_version = SP_PATCH_VERSION; Alarm( STATUS, "Stat_init: went ok\n" ); }
void Alarmp( int16 priority, int32 mask, char *message, ...) { /* log event if in mask and of higher priority, or if FATAL event, always log */ if ( (( Alarm_type_mask & mask ) && (Alarm_cur_priority <= priority)) || (priority == SPLOG_FATAL) ) { va_list ap; if ( Alarm_timestamp_format && (priority != SPLOG_PRINT_NODATE) ) { char timestamp[42]; struct tm *tm_now; time_t time_now; size_t length; time_now = time(NULL); tm_now = localtime(&time_now); length = strftime(timestamp, 40, Alarm_timestamp_format, tm_now); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); if ( Alarm_precise_timestamp ) { sp_time precise_now; precise_now = E_get_time(); length = sprintf (timestamp, " (%lu us): ", precise_now.usec); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); } } va_start(ap,message); vprintf(message, ap); va_end(ap); } if ( ( EXIT & mask ) || (priority == SPLOG_FATAL) ) { printf("Exit caused by Alarm(EXIT)\n"); exit( 0 ); } }
void Alarm( int16 priority, int32 mask, char *message, void *ptr1, void *ptr2, void *ptr3, void *ptr4, void *ptr5, void *ptr6, void *ptr7, void *ptr8, void *ptr9, void *ptr10, void*ptr11, void *ptr12, void *ptr13, void *ptr14, void *ptr15, void *ptr16, void *ptr17, void *ptr18, void *ptr19, void *ptr20) { if ( ( Alarm_type_mask & mask ) && (Alarm_cur_priority < priority) ) { if ( Alarm_timestamp_format ) { char timestamp[42]; struct tm *tm_now; time_t time_now; size_t length; time_now = time(NULL); tm_now = localtime(&time_now); length = strftime(timestamp, 40, Alarm_timestamp_format, tm_now); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); if ( Alarm_precise_timestamp ) { sp_time precise_now; precise_now = E_get_time(); length = sprintf (timestamp, " (%lu us): ", precise_now.usec); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); } } printf(message, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ptr9, ptr10, ptr11, ptr12, ptr13, ptr14, ptr15, ptr16, ptr17, ptr18, ptr19, ptr20 ); } if ( EXIT & mask ) { printf("Exit caused by Alarm(EXIT)\n"); exit( 0 ); } }
/* For backwards compatibility while moving all Alarm calls over, this provides * the old interface and logs them as WARNING events. */ void Alarm( int32 mask, char *message, ...) { if ( ( Alarm_type_mask & mask ) && (Alarm_cur_priority <= SPLOG_WARNING) ) { va_list ap; if ( Alarm_timestamp_format ) { char timestamp[42]; struct tm *tm_now; time_t time_now; size_t length; time_now = time(NULL); tm_now = localtime(&time_now); length = strftime(timestamp, 40, Alarm_timestamp_format, tm_now); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); if ( Alarm_precise_timestamp ) { sp_time precise_now; precise_now = E_get_time(); length = sprintf (timestamp, " (%lu us): ", precise_now.usec); timestamp[length] = ' '; fwrite(timestamp, length+1, sizeof(char), stdout); } } va_start(ap,message); vprintf(message, ap); va_end(ap); } if ( EXIT & mask ) { printf("Exit caused by Alarm(EXIT)\n"); exit( 0 ); } }
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; }
int E_queue( void (* func)( int code, void *data ), int code, void *data, sp_time delta_time ) { time_event *t_pre; time_event *t_post; time_event *t_e; int inserted; int deleted; int compare; t_e = new( TIME_EVENT ); t_e->t = E_add_time( E_get_time(), delta_time ); t_e->func = func; t_e->code = code; t_e->data = data; deleted = 0; inserted = 0; if( Time_queue != NULL ) { if( Time_queue->func == t_e->func && Time_queue->data == t_e->data && Time_queue->code == t_e->code ) { t_pre = Time_queue; Time_queue = Time_queue->next; dispose( t_pre ); deleted = 1; Alarm( EVENTS, "E_queue: dequeued a (first) simillar event\n" ); } } if( Time_queue == NULL ) { t_e->next = NULL; Time_queue = t_e; Alarm( EVENTS, "E_queue: (only) event queued func 0x%x code %d data 0x%x in future (%u:%u)\n",t_e->func,t_e->code, t_e->data, delta_time.sec, delta_time.usec ); return( 0 ); }else{ compare = E_compare_time ( t_e->t, Time_queue->t ); if( compare < 0 ) { t_e->next = Time_queue; Time_queue = t_e; inserted = 1; Alarm( EVENTS, "E_queue: (first) event queued func 0x%x code %d data 0x%x in future (%u:%u)\n",t_e->func,t_e->code, t_e->data, delta_time.sec,delta_time.usec ); } } t_pre = Time_queue ; t_post = Time_queue->next; while ( t_post != NULL && ( !inserted || !deleted ) ) { if( t_post->func == t_e->func && t_post->data == t_e->data && t_post->code == t_e->code ) { t_pre->next = t_post->next; dispose( t_post ); t_post = t_pre->next; deleted = 1; Alarm( EVENTS, "E_queue: dequeued a simillar event\n" ); continue; } if ( !inserted ) { compare = E_compare_time ( t_e->t, t_post->t ); if( compare < 0 ) { t_pre->next = t_e; t_e->next = t_post; inserted = 1; Alarm( EVENTS, "E_queue: event queued for func 0x%x code %d data 0x%x in future (%u:%u)\n",t_e->func,t_e->code, t_e->data, delta_time.sec, delta_time.usec ); } } t_pre = t_post; t_post = t_post->next; } if( !inserted ) { t_pre->next = t_e; t_e->next = NULL; Alarm( EVENTS, "E_queue: (last) event queued func 0x%x code %d data 0x%x in future (%u:%u)\n",t_e->func,t_e->code, t_e->data, delta_time.sec,delta_time.usec ); } return( 0 ); }