int switch_event_recv_echoreply( struct switch_info *sw_info, buffer *buf ) { if ( buf->length != sizeof( struct ofp_header ) + sizeof( echo_body ) ) { return 0; } struct ofp_header *header = buf->data; if ( ntohl( header->xid ) != sw_info->echo_request_xid ) { return 0; } echo_body *body = ( echo_body * ) ( header + 1 ); if ( ntohll( body->datapath_id ) != sw_info->datapath_id ) { return 0; } switch_unset_timeout( echo_reply_timeout, NULL ); struct timespec now, tim; clock_gettime( CLOCK_MONOTONIC, &now ); tim.tv_sec = ( time_t ) ntohl( body->sec ); tim.tv_nsec = ( long ) ntohl( body->nsec ); SUB_TIMESPEC( &now, &tim, &tim ); if ( tim.tv_sec > 0 || tim.tv_nsec > ( ( long ) WARNING_ECHO_RTT * 1000000 ) ) { warn( "echo round-trip time is greater then %ld ms ( round-trip time = %" PRId64 ".%09ld ).", ( long ) WARNING_ECHO_RTT, ( int64_t ) tim.tv_sec, tim.tv_nsec ); } return 0; }
int switch_event_recv_echoreply( struct switch_info *sw_info, buffer *buf ) { if ( buf->length != sizeof( struct ofp_header ) + sizeof( echo_body ) ) { return 0; } struct ofp_header *header = buf->data; if ( ntohl( header->xid ) != sw_info->echo_request_xid ) { return 0; } echo_body *body = ( echo_body * ) ( header + 1 ); if ( ntohll( body->datapath_id ) != sw_info->datapath_id ) { return 0; } switch_unset_timeout( echo_reply_timeout, NULL ); struct timespec now, tim; clock_gettime( CLOCK_MONOTONIC, &now ); tim.tv_sec = ( time_t ) ntohl( body->sec ); tim.tv_nsec = ( long ) ntohl( body->nsec ); SUB_TIMESPEC( &now, &tim, &tim ); info( "echo round-trip time %u.%09u.", ( uint32_t ) tim.tv_sec, ( uint32_t ) tim.tv_nsec ); return 0; }
static void _execute_timer_events( int *next_timeout_usec ) { assert( next_timeout_usec != NULL ); timer_read_begin(); struct timer_info *timer = get_timer_info(); timer_read_end(); assert( timer != NULL ); debug( "Executing timer events ( timer_callbacks = %p ).", timer->timer_callbacks ); struct timespec now = { 0, 0 }; assert( clock_gettime( CLOCK_MONOTONIC, &now ) == 0 ); assert( timer->timer_callbacks != NULL ); timer_callback_info *callback = NULL; dlist_element *element_next = NULL; for ( dlist_element *element = timer->timer_callbacks->next; element; element = element_next ) { element_next = element->next; callback = element->data; if ( callback->function != NULL ) { if ( TIMESPEC_LESS_THEN( &now, &callback->expires_at ) ) { break; } on_timer( callback, &now ); } delete_dlist_element( element ); if ( callback->function == NULL ) { xfree( callback ); } else { insert_timer_callback( timer, callback ); } } struct timespec max_timeout = { ( INT_MAX / 1000000 ), 0 }; struct timespec min_timeout = { 0, 0 }; if ( timer->timer_callbacks->next == NULL ) { TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec ); } else { callback = timer->timer_callbacks->next->data; if ( TIMESPEC_LESS_THEN( &callback->expires_at, &now ) ) { TIMESPEC_TO_MICROSECONDS( &min_timeout, next_timeout_usec ); } else { struct timespec timeout = { 0, 0 }; SUB_TIMESPEC( &callback->expires_at, &now, &timeout ); if ( TIMESPEC_LESS_THEN( &timeout, &max_timeout ) ) { TIMESPEC_TO_MICROSECONDS( &timeout, next_timeout_usec ); } else { TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec ); } } } }
/** * @brief Returns the age of a variable. * @param varname STRING * @return The age of the variable (TIME) */ void iec_ageOfVariable(BOOL EN, BOOL *ENO, param_ret_t *RET, UINT count, param_u_t *in) { TEST_EN STRING VARNAME = in++->STRINGvar; char *varname = strndup((char *)VARNAME.body, VARNAME.len); iec_variable_t *v = getVariable(getCurrentContext(), varname); free (varname); DT dt_null = {0,0}; if (!v) { RET->t = TIMEtype; RET->p.TIMEvar = dt_null; return; } TIME now; iec_gettimeofday (&now); SUB_TIMESPEC (now, v->lastModifiedTime); RET->t = TIMEtype; RET->p.TIMEvar = now; }