static real _config_string_to_real( const char* str ) { unsigned int length = string_length( str ); unsigned int first_nonnumeric; unsigned int dot_position; if( length < 2 ) return string_to_real( str ); first_nonnumeric = string_find_first_not_of( str, "0123456789.", 0 ); if( ( first_nonnumeric == ( length - 1 ) ) && ( ( str[ first_nonnumeric ] == 'm' ) || ( str[ first_nonnumeric ] == 'M' ) ) ) { dot_position = string_find( str, '.', 0 ); if( dot_position != STRING_NPOS ) { if( string_find( str, '.', dot_position + 1 ) != STRING_NPOS ) return string_to_real( str ); //More than one dot } return string_to_real( str ) * ( REAL_C( 1024.0 ) * REAL_C( 1024.0 ) ); } if( ( first_nonnumeric == ( length - 1 ) ) && ( ( str[ first_nonnumeric ] == 'k' ) || ( str[ first_nonnumeric ] == 'K' ) ) ) { dot_position = string_find( str, '.', 0 ); if( dot_position != STRING_NPOS ) { if( string_find( str, '.', dot_position + 1 ) != STRING_NPOS ) return string_to_real( str ); //More than one dot } return string_to_real( str ) * REAL_C( 1024.0 ); } return string_to_real( str ); }
void config_set_bool( hash_t section, hash_t key, bool value ) { config_key_t* key_val = config_key( section, key, true ); if( !FOUNDATION_VALIDATE( key_val ) ) return; key_val->bval = value; key_val->ival = ( value ? 1 : 0 ); key_val->rval = ( value ? REAL_C( 1.0 ) : REAL_C( 0.0 ) ); if( key_val->expanded != key_val->sval ) string_deallocate( key_val->expanded ); if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) ) string_deallocate( key_val->sval ); key_val->sval = 0; key_val->expanded = 0; key_val->type = CONFIGVALUE_BOOL; }
DECLARE_TEST( math, exponentials ) { EXPECT_REALONE( math_exp( REAL_ZERO ) ); EXPECT_REALEQ( math_exp( REAL_ONE ), REAL_E ); EXPECT_REALONE( math_pow( REAL_ONE, REAL_ONE ) ); EXPECT_REALONE( math_pow( REAL_ONE, REAL_ZERO ) ); EXPECT_REALONE( math_pow( REAL_THREE, REAL_ZERO ) ); EXPECT_REALEQ( math_pow( REAL_SQRT2, REAL_TWO ), REAL_TWO ); EXPECT_REALEQ( math_logn( REAL_TWO ), REAL_LOGN2 ); EXPECT_REALEQ( math_logn( REAL_C( 10.0 ) ), REAL_LOGN10 ); EXPECT_REALONE( math_log2( REAL_TWO ) ); EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO ), REAL_TWO ); EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO * REAL_TWO * REAL_TWO ), REAL_C( 4.0 ) ); return 0; }
static NOINLINE void _expand_string_val( hash_t section, config_key_t* key ) { bool is_true; FOUNDATION_ASSERT( key->sval ); if( key->expanded != key->sval ) string_deallocate( key->expanded ); key->expanded = _expand_string( section, key->sval ); is_true = string_equal( key->expanded, "true" ); key->bval = ( string_equal( key->expanded, "false" ) || string_equal( key->expanded, "0" ) || !string_length( key->expanded ) ) ? false : true; key->ival = is_true ? 1 : _config_string_to_int( key->expanded ); key->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key->expanded ); }
static void blast_client_report_progress(blast_client_t* client, bool force) { int progress = (int)((real)((float64_t)((client->seq - array_size(client->pending)) * PACKET_CHUNK_SIZE) / (float64_t)client->readers[client->current]->size) * REAL_C(100.0)); if (force || (progress > (client->last_progress_percent + 5)) || (time_elapsed(client->last_progress) > 1.0f)) { if (client->packets_sent > 0) { real resend_rate = (real)((float64_t)client->packets_resent / (float64_t)client->packets_sent) * REAL_C(100.0); log_infof(HASH_BLAST, STRING_CONST("Progress: %.*s %d%% (resend rate %.2" PRIreal "%% %lld/%lld))"), STRING_FORMAT(client->readers[client->current]->name), progress, resend_rate, client->packets_resent, client->packets_sent); } client->last_progress = time_current(); client->last_progress_percent = progress; } }
void config_set_string( hash_t section, hash_t key, const char* value ) { config_key_t* key_val = config_key( section, key, true ); if( !FOUNDATION_VALIDATE( key_val ) ) return; if( key_val->expanded != key_val->sval ) string_deallocate( key_val->expanded ); if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) ) string_deallocate( key_val->sval ); key_val->sval = string_clone( value ); key_val->expanded = 0; key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_VAR : CONFIGVALUE_STRING ); if( key_val->type == CONFIGVALUE_STRING ) { bool is_true = string_equal( key_val->sval, "true" ); key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true; key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval ); key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval ); } }
void config_set_string_constant( hash_t section, hash_t key, const char* value ) { config_key_t* key_val = config_key( section, key, true ); if( !FOUNDATION_VALIDATE( key_val ) ) return; if( !FOUNDATION_VALIDATE( value ) ) return; if( key_val->expanded != key_val->sval ) string_deallocate( key_val->expanded ); if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) ) string_deallocate( key_val->sval ); //key_val->sval = (char*)value; memcpy( &key_val->sval, &value, sizeof( char* ) ); //Yeah yeah, we're storing a const pointer in a non-const var key_val->expanded = 0; key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_CONST_VAR : CONFIGVALUE_STRING_CONST ); if( key_val->type == CONFIGVALUE_STRING_CONST ) { bool is_true = string_equal( key_val->sval, "true" ); key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true; key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval ); key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval ); } }
DECLARE_TEST( math, comparison ) { real testreal, refreal; real onereal = REAL_ONE; real zeroreal = REAL_ZERO; testreal = REAL_C( 42.42 ); refreal = testreal; EXPECT_EQ( testreal, refreal ); EXPECT_TRUE( math_realeq( testreal, refreal, 0 ) ); EXPECT_TRUE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); testreal = math_realdec( testreal, 10 ); EXPECT_NE( testreal, refreal ); EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_TRUE( math_realeq( testreal, refreal, 10 ) ); EXPECT_TRUE( math_realeqns( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); testreal = math_realdec( testreal, 10 ); EXPECT_NE( testreal, refreal ); EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeq( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); testreal = math_realinc( testreal, 20 ); EXPECT_EQ( testreal, refreal ); EXPECT_TRUE( math_realeq( testreal, refreal, 0 ) ); EXPECT_TRUE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); testreal = math_realinc( testreal, 10 ); EXPECT_NE( testreal, refreal ); EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_TRUE( math_realeq( testreal, refreal, 10 ) ); EXPECT_TRUE( math_realeqns( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); testreal = math_realinc( testreal, 10 ); EXPECT_NE( testreal, refreal ); EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) ); EXPECT_FALSE( math_realeq( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realeqns( testreal, refreal, 10 ) ); EXPECT_FALSE( math_realzero( testreal ) ); EXPECT_FALSE( math_realone( testreal ) ); EXPECT_FALSE( math_realisnan( testreal ) ); EXPECT_FALSE( math_realisinf( testreal ) ); EXPECT_FALSE( math_realisuninitialized( testreal ) ); EXPECT_TRUE( math_realisfinite( testreal ) ); EXPECT_TRUE( math_realisnan( math_sqrt( REAL_C( -1.0 ) ) ) ); EXPECT_TRUE( math_realisinf( onereal / zeroreal ) ); EXPECT_TRUE( math_realisnan( -math_sqrt( REAL_C( -1.0 ) ) ) ); EXPECT_TRUE( math_realisinf( -onereal / zeroreal ) ); testreal = REAL_ONE / REAL_MAX; EXPECT_REALNE( testreal, REAL_ZERO ); EXPECT_TRUE( math_realisdenormalized( testreal ) ); EXPECT_REALZERO( math_realundenormalize( testreal ) ); EXPECT_FALSE( math_realisdenormalized( REAL_ONE ) ); EXPECT_REALONE( math_realundenormalize( REAL_ONE ) ); return 0; }
DECLARE_TEST( math, utility ) { int i; EXPECT_REALONE( math_abs( REAL_ONE ) ); EXPECT_REALONE( math_abs( -REAL_ONE ) ); EXPECT_REALZERO( math_abs( REAL_ZERO ) ); EXPECT_REALEQ( math_abs( REAL_MAX ), REAL_MAX ); EXPECT_REALEQ( math_abs( -REAL_MAX ), REAL_MAX ); EXPECT_REALEQ( math_abs( REAL_MIN ), REAL_MIN ); EXPECT_REALEQ( math_abs( -REAL_MIN ), REAL_MIN ); EXPECT_REALZERO( math_mod( REAL_ZERO, REAL_ONE ) ); EXPECT_REALZERO( math_mod( REAL_ONE, REAL_ONE ) ); EXPECT_REALZERO( math_mod( REAL_MAX, REAL_ONE ) ); EXPECT_REALONE( math_mod( REAL_THREE, REAL_TWO ) ); EXPECT_REALONE( -math_mod( -REAL_THREE, -REAL_TWO ) ); EXPECT_EQ( math_floor( REAL_ZERO ), 0 ); EXPECT_EQ( math_floor( REAL_C( 0.999 ) ), 0 ); EXPECT_EQ( math_floor( REAL_C( -0.1 ) ), -1 ); EXPECT_EQ( math_floor( REAL_C( 42.5 ) ), 42 ); EXPECT_EQ( math_ceil( REAL_ZERO ), 0 ); EXPECT_EQ( math_ceil( REAL_C( 0.999 ) ), 1 ); EXPECT_EQ( math_ceil( REAL_C( -0.1 ) ), 0 ); EXPECT_EQ( math_ceil( REAL_C( 42.5 ) ), 43 ); EXPECT_EQ( math_ceil( REAL_C( 42.45 ) ), 43 ); EXPECT_EQ( math_floor64( REAL_ZERO ), 0 ); EXPECT_EQ( math_floor64( REAL_C( 0.999 ) ), 0 ); EXPECT_EQ( math_floor64( REAL_C( -0.1 ) ), -1 ); EXPECT_EQ( math_floor64( REAL_C( 42.5 ) ), 42 ); EXPECT_EQ( math_ceil64( REAL_ZERO ), 0 ); EXPECT_EQ( math_ceil64( REAL_C( 0.999 ) ), 1 ); EXPECT_EQ( math_ceil64( REAL_C( -0.1 ) ), 0 ); EXPECT_EQ( math_ceil64( REAL_C( 42.5 ) ), 43 ); EXPECT_EQ( math_ceil64( REAL_C( 42.45 ) ), 43 ); EXPECT_EQ( math_round( REAL_ZERO ), 0 ); EXPECT_EQ( math_round( REAL_C( 0.999 ) ), 1 ); EXPECT_EQ( math_round( REAL_C( -0.1 ) ), 0 ); EXPECT_EQ( math_round( REAL_C( 42.5 ) ), 43 ); EXPECT_EQ( math_round( REAL_C( 42.45 ) ), 42 ); EXPECT_EQ( math_trunc( REAL_ZERO ), 0 ); EXPECT_EQ( math_trunc( REAL_C( 0.999 ) ), 0 ); EXPECT_EQ( math_trunc( REAL_C( -0.1 ) ), 0 ); EXPECT_EQ( math_trunc( REAL_C( 42.5 ) ), 42 ); EXPECT_EQ( math_align_poweroftwo( 2 ), 2 ); EXPECT_EQ( math_align_poweroftwo( 3 ), 4 ); EXPECT_EQ( math_align_poweroftwo( 4 ), 4 ); EXPECT_EQ( math_align_poweroftwo( 33 ), 64 ); EXPECT_EQ( math_align_poweroftwo( 134217729 ), 268435456 ); for( i = 1; i < 31; ++i ) { EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i ) - 1 ) ) ); EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i ) ) ) ); EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i ) + 1 ) ) ); EXPECT_FALSE( math_is_poweroftwo( ( 2 << i ) - 1 ) ); EXPECT_TRUE( math_is_poweroftwo( ( 2 << i ) ) ); EXPECT_FALSE( math_is_poweroftwo( ( 2 << i ) + 1 ) ); } EXPECT_EQ( math_align_up( 1, 1 ), 1 ); EXPECT_EQ( math_align_up( 1, 2 ), 2 ); EXPECT_EQ( math_align_up( 17, 2 ), 18 ); EXPECT_EQ( math_align_up( 43, 42 ), 84 ); EXPECT_REALZERO( math_smoothstep( REAL_ZERO ) ); EXPECT_REALONE( math_smoothstep( REAL_ONE ) ); EXPECT_REALEQ( math_smoothstep( REAL_HALF ), REAL_HALF ); EXPECT_REALZERO( math_smootherstep( REAL_ZERO ) ); EXPECT_REALONE( math_smootherstep( REAL_ONE ) ); EXPECT_REALEQ( math_smootherstep( REAL_HALF ), REAL_HALF ); EXPECT_REALZERO( math_lerp( REAL_ZERO, REAL_ZERO, REAL_ONE ) ); EXPECT_REALZERO( math_lerp( REAL_ONE, REAL_ONE, REAL_ZERO ) ); EXPECT_REALONE( math_lerp( REAL_ONE, REAL_ZERO, REAL_ONE ) ); EXPECT_REALONE( math_lerp( REAL_ZERO, REAL_ONE, REAL_ZERO ) ); EXPECT_REALEQ( math_lerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF ); EXPECT_REALEQ( math_lerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF ); EXPECT_REALZERO( math_unlerp( REAL_ZERO, REAL_ZERO, REAL_ONE ) ); EXPECT_REALZERO( math_unlerp( REAL_ONE, REAL_ONE, REAL_ZERO ) ); EXPECT_REALONE( math_unlerp( REAL_ONE, REAL_ZERO, REAL_ONE ) ); EXPECT_REALONE( math_unlerp( REAL_ZERO, REAL_ONE, REAL_ZERO ) ); EXPECT_REALEQ( math_unlerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF ); EXPECT_REALEQ( math_unlerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF ); EXPECT_REALONE( math_linear_remap( REAL_C( 150.0 ), REAL_C( 100.0 ), REAL_C( 200.0 ), REAL_ZERO, REAL_TWO ) ); EXPECT_REALZERO( math_clamp( -REAL_ONE, REAL_ZERO, REAL_ONE ) ); EXPECT_REALZERO( math_clamp( REAL_ZERO, REAL_ZERO, REAL_ONE ) ); EXPECT_REALEQ( math_clamp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF ); EXPECT_REALONE( math_clamp( REAL_ONE, REAL_ZERO, REAL_ONE ) ); EXPECT_REALONE( math_clamp( REAL_TWO, REAL_ZERO, REAL_ONE ) ); return 0; }
int _time_initialize( void ) { #if FOUNDATION_PLATFORM_WINDOWS tick_t unused; if( !QueryPerformanceFrequency( (LARGE_INTEGER*)&_time_freq ) || !QueryPerformanceCounter( (LARGE_INTEGER*)&unused ) ) return -1; #elif FOUNDATION_PLATFORM_APPLE if( mach_timebase_info( &_time_info ) ) return -1; _time_freq = 1000000000ULL; #elif FOUNDATION_PLATFORM_POSIX struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; if( clock_gettime( CLOCK_MONOTONIC, &ts ) ) return -1; _time_freq = 1000000000ULL; #endif _time_oofreq = REAL_C(1.0) / (double)_time_freq; _time_startup = time_current(); return 0; } void _time_shutdown( void ) { } tick_t time_current( void ) { #if FOUNDATION_PLATFORM_WINDOWS tick_t curclock; QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); return curclock; #elif FOUNDATION_PLATFORM_APPLE tick_t curclock = 0; absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); return curclock; #elif FOUNDATION_PLATFORM_POSIX struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; clock_gettime( CLOCK_MONOTONIC, &ts ); return ( (uint64_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; #endif } tick_t time_startup( void ) { return _time_startup; } tick_t time_ticks_per_second( void ) { return _time_freq; } tick_t time_diff( const tick_t from, const tick_t to ) { if( to <= from ) return 0; return ( to - from ); } deltatime_t time_elapsed( const tick_t t ) { return (deltatime_t)( (double)time_elapsed_ticks( t ) * _time_oofreq ); } tick_t time_elapsed_ticks( const tick_t t ) { tick_t dt = 0; #if FOUNDATION_PLATFORM_WINDOWS tick_t curclock = t; QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); dt = curclock - t; #elif FOUNDATION_PLATFORM_APPLE tick_t curclock = t; absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); dt = curclock - t; #elif FOUNDATION_PLATFORM_POSIX tick_t curclock; struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; clock_gettime( CLOCK_MONOTONIC, &ts ); curclock = ( (tick_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; dt = curclock - t; #endif return dt; } deltatime_t time_ticks_to_seconds( const tick_t dt ) { return (deltatime_t)( (double)dt * _time_oofreq ); } #if FOUNDATION_PLATFORM_WINDOWS struct __timeb64 { __time64_t time; unsigned short millitm; short timezone; short dstflag; };
DECLARE_TEST( event, delay ) { event_stream_t* stream; event_block_t* block; event_t* event; tick_t delivery = 0; tick_t limit = 0; tick_t current = 0; uint8_t expect_event = FOUNDATIONEVENT_TERMINATE; stream = event_stream_allocate( 0 ); current = time_current(); delivery = current + ( time_ticks_per_second() / 2 ); limit = current + ( time_ticks_per_second() * 20 ); event_post( stream, expect_event, 0, 0, 0, current + ( time_ticks_per_second() / 2 ) ); event_post( stream, expect_event + 1, 0, 0, 0, current + (tick_t)((real)time_ticks_per_second() * REAL_C( 0.51 )) ); do { block = event_stream_process( stream ); event = event_next( block, 0 ); current = time_current(); if( ( expect_event == FOUNDATIONEVENT_TERMINATE ) && event ) { EXPECT_EQ( event->id, expect_event ); EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload EXPECT_EQ( event->object, 0 ); EXPECT_EQ( event->flags, EVENTFLAG_DELAY ); EXPECT_EQ( event_payload_size( event ), 0 ); EXPECT_GE( current, delivery ); EXPECT_GE( current, delivery ); ++expect_event; event = event_next( block, event ); } if( ( expect_event == FOUNDATIONEVENT_TERMINATE + 1 ) && event ) { EXPECT_EQ( event->id, expect_event ); EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload EXPECT_EQ( event->object, 0 ); EXPECT_EQ( event->flags, EVENTFLAG_DELAY ); EXPECT_EQ( event_payload_size( event ), 0 ); EXPECT_GE( current, delivery ); EXPECT_GE( current, delivery ); ++expect_event; event = event_next( block, event ); EXPECT_EQ( event, 0 ); } if( ( expect_event > FOUNDATIONEVENT_TERMINATE + 1 ) && !event ) break; thread_yield(); } while( time_current() < limit ); EXPECT_EQ( event, 0 ); EXPECT_EQ( expect_event, FOUNDATIONEVENT_TERMINATE + 2 ); EXPECT_LE( time_current(), limit ); //Reverse order of delivery current = time_current(); delivery = current + ( time_ticks_per_second() / 2 ); limit = current + ( time_ticks_per_second() * 20 ); event_post( stream, expect_event, 0, 0, 0, current + ( time_ticks_per_second() / 2 ) ); event_post( stream, expect_event + 1, 0, 0, 0, current + (tick_t)((real)time_ticks_per_second() * REAL_C( 0.41 )) ); do { block = event_stream_process( stream ); event = event_next( block, 0 ); current = time_current(); if( ( expect_event == FOUNDATIONEVENT_TERMINATE ) && event ) { EXPECT_EQ( event->id, expect_event ); EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload EXPECT_EQ( event->object, 0 ); EXPECT_EQ( event->flags, EVENTFLAG_DELAY ); EXPECT_EQ( event_payload_size( event ), 0 ); EXPECT_GE( current, delivery ); EXPECT_GE( current, delivery ); ++expect_event; event = event_next( block, event ); } if( ( expect_event == FOUNDATIONEVENT_TERMINATE + 1 ) && event ) { EXPECT_EQ( event->id, expect_event ); EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload EXPECT_EQ( event->object, 0 ); EXPECT_EQ( event->flags, EVENTFLAG_DELAY ); EXPECT_EQ( event_payload_size( event ), 0 ); EXPECT_GE( current, delivery ); EXPECT_GE( current, delivery ); ++expect_event; event = event_next( block, event ); EXPECT_EQ( event, 0 ); } if( ( expect_event > FOUNDATIONEVENT_TERMINATE + 1 ) && !event ) break; thread_yield(); } while( time_current() < limit ); EXPECT_EQ( event, 0 ); EXPECT_EQ( expect_event, FOUNDATIONEVENT_TERMINATE + 2 ); EXPECT_LE( time_current(), limit ); event_stream_deallocate( stream ); return 0; }