Esempio n. 1
0
DECLARE_TEST( semaphore, postwait )
{
	semaphore_t sem;
	tick_t start, end;

	semaphore_initialize( &sem, 0 );
	EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) );

	semaphore_post( &sem );
	EXPECT_TRUE( semaphore_wait( &sem ) );
	EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) );

	semaphore_post( &sem );
	semaphore_post( &sem );
	EXPECT_TRUE( semaphore_wait( &sem ) );
	EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) );
	EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) );

	start = time_current();
	semaphore_try_wait( &sem, 0 );
	end = time_current();
	EXPECT_LT( end - start, time_ticks_per_second() / 1000 );

	start = time_current();
	semaphore_try_wait( &sem, 500 );
	end = time_current();
	EXPECT_GE( end - start, time_ticks_per_second() / 2 );

	semaphore_destroy( &sem );

	return 0;
}
Esempio n. 2
0
static log_timestamp_t _log_make_timestamp( void )
{
	tick_t elapsed;
	tick_t ticks_per_sec;
	uint64_t milliseconds;
	uint64_t seconds;
	uint64_t minutes;

	log_timestamp_t timestamp = {0};
	
	ticks_per_sec = time_ticks_per_second();
	if( !ticks_per_sec )
		return timestamp;
	
	elapsed = time_current() - time_startup();
	milliseconds = ( ( elapsed % ticks_per_sec ) * 1000ULL ) / ticks_per_sec;
	seconds = elapsed / ticks_per_sec;
	minutes = seconds / 60ULL;

	timestamp.milliseconds = (unsigned int)( milliseconds % 1000ULL );
	timestamp.seconds = (unsigned int)( seconds % 60ULL );
	timestamp.minutes = (unsigned int)( minutes % 60ULL );
	timestamp.hours = (unsigned int)( minutes / 24ULL );

	return timestamp;
}
Esempio n. 3
0
static void* _profile_io( object_t thread, void* arg )
{
	unsigned int system_info_counter = 0;
	profile_block_t system_info;
	FOUNDATION_UNUSED( arg );
	memset( &system_info, 0, sizeof( profile_block_t ) );
	system_info.data.id = PROFILE_ID_SYSTEMINFO;
	system_info.data.start = time_ticks_per_second();
	string_copy( system_info.data.name, "sysinfo", 7 );

	while( !thread_should_terminate( thread ) )
	{
		thread_sleep( _profile_wait );

		if( !atomic_load32( &_profile_root ) )
			continue;

		profile_begin_block( "profile_io" );

		if( atomic_load32( &_profile_root ) )
		{
			profile_begin_block( "process" );

			//This is thread safe in the sense that only completely closed and ended
			//blocks will be put as children to root block, so no additional blocks
			//will ever be added to child subtrees while we process it here
			_profile_process_root_block();

			profile_end_block();
		}

		if( system_info_counter++ > 10 )
		{
			if( _profile_write )
				_profile_write( &system_info, sizeof( profile_block_t ) );
			system_info_counter = 0;
		}

		profile_end_block();
	}

	if( atomic_load32( &_profile_root ) )
		_profile_process_root_block();

	if( _profile_write )
	{
		profile_block_t terminate;
		memset( &terminate, 0, sizeof( profile_block_t ) );
		terminate.data.id = PROFILE_ID_ENDOFSTREAM;
		_profile_write( &terminate, sizeof( profile_block_t ) );
	}

	return 0;
}
Esempio n. 4
0
DECLARE_TEST(time, builtin) {
	tick_t tick, newtick, tps;
	deltatime_t dt;

	tps = time_ticks_per_second();
	EXPECT_GT(tps, 0);

	tick = time_current();
	thread_sleep(30);
	newtick = time_current();

	EXPECT_TICKNE(tick, 0);
	EXPECT_TICKGT(newtick, tick);

	EXPECT_TICKGT(time_diff(tick, newtick), 0);
	EXPECT_GT_MSGFORMAT(time_diff(tick, newtick), (tps / 100LL),
	                    "time elapsed not more than 10ms: %" PRId64 " (%" PRId64 ")", time_diff(tick, newtick),
	                    (tps / 100)); //more than 10 ms
	EXPECT_LT_MSGFORMAT(time_diff(tick, newtick), (tps / 20LL),
	                    "time elapsed not less than 50ms: %" PRId64 " (%" PRId64 ")", time_diff(tick, newtick),
	                    (tps / 33)); //less than 30 ms
	EXPECT_REALGT(time_elapsed(tick), 0);
	EXPECT_REALGT(time_elapsed(tick), 0.01f); //more than 10 ms
	EXPECT_TICKGT(time_elapsed_ticks(tick), 0);
	EXPECT_TICKGT(time_elapsed_ticks(tick), (tps / 100)); //more than 10 ms
	EXPECT_TICKLT(time_elapsed_ticks(tick), (tps / 20));  //less than 50 ms

	dt = time_ticks_to_seconds(newtick - tick);
	EXPECT_REALGT(dt, 0);
	EXPECT_GT_MSGFORMAT(dt, 0.01f, "time elapsed in seconds not more than 10ms: %.5f",
	                    dt);   //more than 10 ms
	EXPECT_LT_MSGFORMAT(dt, 0.05f, "time elapsed in seconds not less than 30ms: %.5f",
	                    dt);   //less than 30 ms

	tick = time_startup();
	EXPECT_TICKGT(tick, 0);
	EXPECT_TICKLT(tick, newtick);
	EXPECT_TICKEQ(tick, time_startup());

	tick = time_system();
	thread_sleep(100);
	newtick = time_system();

	EXPECT_TICKGT(tick, 0);
	EXPECT_TICKGT(newtick, 0);
	EXPECT_TICKGT(newtick, tick);
	EXPECT_GT_MSGFORMAT(newtick - tick, 50,
	                    "Elapsed system time less than 50ms, expected 100ms, got %" PRId64 "ms", newtick - tick);
	EXPECT_LT_MSGFORMAT(newtick - tick, 200,
	                    "Elapsed system time more than 200ms, expected 100ms, got %" PRId64 "ms", newtick - tick);

	return 0;
}
Esempio n. 5
0
DECLARE_TEST( time, builtin )
{
	tick_t tick, newtick, tps;
	deltatime_t dt;

	tps = time_ticks_per_second();
	EXPECT_GT( tps, 0 );

	tick = time_current();
	thread_sleep( 20 );
	newtick = time_current();

	EXPECT_NE( tick, 0 );
	EXPECT_GT( newtick, tick );

	EXPECT_GT( time_diff( tick, newtick ), 0 );
	EXPECT_GT_MSGFORMAT( time_diff( tick, newtick ), ( tps / 100LL ), "time elapsed not more than 10ms: %lld (%lld)", time_diff( tick, newtick ), ( tps / 100LL ) ); //more than 10 ms
	EXPECT_LT_MSGFORMAT( time_diff( tick, newtick ), ( tps / 30LL  ), "time elapsed not less than 30ms: %lld (%lld)", time_diff( tick, newtick ), ( tps / 33LL  ) ); //less than 30 ms
	EXPECT_GT( time_elapsed( tick ), 0 );
	EXPECT_GT( time_elapsed( tick ), 0.01f ); //more than 10 ms
	EXPECT_GT( time_elapsed_ticks( tick ), 0 );
	EXPECT_GT( time_elapsed_ticks( tick ), ( tps / 100 ) ); //more than 10 ms

	dt = time_ticks_to_seconds( newtick - tick );
	EXPECT_GT( dt, 0 );
	EXPECT_GT_MSGFORMAT( dt, 0.01f, "time elapsed in seconds not more than 10ms: %.5f", dt ); //more than 10 ms
	EXPECT_LT_MSGFORMAT( dt, 0.03f, "time elapsed in seconds not less than 30ms: %.5f", dt ); //less than 30 ms

	tick = time_startup();
	EXPECT_GT( tick, 0 );
	EXPECT_LT( tick, newtick );
	EXPECT_EQ( tick, time_startup() );

	tick = time_system();
	EXPECT_GT( tick, 0 );

	thread_sleep( 100 );

	newtick = time_system();
	EXPECT_GT( newtick, 0 );
	EXPECT_GT( newtick, tick );
	EXPECT_GT( newtick - tick, 50 ); //more than 50 ms
	EXPECT_LT( newtick - tick, 200 ); //less than 200 ms

	return 0;
}
Esempio n. 6
0
static tick_t
blast_time_elapsed_ms(const tick_t since) {
	const tick_t elapsed = time_elapsed_ticks(since);
	return (elapsed * 1000LL) / time_ticks_per_second();
}
Esempio n. 7
0
DECLARE_TEST( event, delay_threaded )
{
	object_t thread[32];
	producer_thread_arg_t args[32] = {0};
	event_stream_t* stream;
	event_block_t* block;
	event_t* event;
	tick_t endtime, curtime, payloadtime, begintime, prevtime;
	unsigned int read[32];
	int i;
	bool running = true;
	int num_threads = math_clamp( system_hardware_threads() * 4, 4, 32 );

	stream = event_stream_allocate( 0 );
	begintime = time_current();

	for( i = 0; i < num_threads; ++i )
	{
		args[i].stream = stream;
		args[i].end_time = time_current() + ( time_ticks_per_second() * 5 );
		args[i].max_delay = time_ticks_per_second() * 5;
		args[i].sleep_time = 50;
		args[i].id = i;

		read[i] = 0;
		thread[i] = thread_create( producer_thread, "event_producer", THREAD_PRIORITY_NORMAL, 0 );
		thread_start( thread[i], &args[i] );
	}

	test_wait_for_threads_startup( thread, num_threads );

	while( running )
	{
		running = false;

		for( i = 0; i < num_threads; ++i )
		{
			if( thread_is_running( thread[i] ) )
			{
				running = true;
				break;
			}
		}

		thread_yield();

		prevtime = begintime;
		begintime = time_current();
		block = event_stream_process( stream );
		event = event_next( block, 0 );
		curtime = time_current();

		while( event )
		{
			running = true;
			++read[ event->object ];
			memcpy( &payloadtime, event->payload, sizeof( tick_t ) );

			EXPECT_GE( event_payload_size( event ), 8 );
			EXPECT_LE( event_payload_size( event ), 256 );
			EXPECT_GE( payloadtime, prevtime );
			EXPECT_GE( curtime, payloadtime );

			event = event_next( block, event );
			curtime = time_current();
		}
	}

	endtime = time_current() + ( time_ticks_per_second() * 6 );
	do
	{
		prevtime = begintime;
		begintime = time_current();
		block = event_stream_process( stream );
		event = event_next( block, 0 );
		curtime = time_current();
		while( event )
		{
			++read[ event->object ];
			memcpy( &payloadtime, event->payload, sizeof( tick_t ) );

			EXPECT_GE( event_payload_size( event ), 8 );
			EXPECT_LE( event_payload_size( event ), 256 );
			EXPECT_GE( payloadtime, prevtime );
			EXPECT_GE( curtime, payloadtime );

			event = event_next( block, event );
			curtime = time_current();
		}

		thread_sleep( 10 );

	} while( time_current() < endtime );

	for( i = 0; i < num_threads; ++i )
	{
		unsigned int should_have_read = (unsigned int)((uintptr_t)thread_result( thread[i] ));
		EXPECT_EQ( read[i], should_have_read );
		thread_terminate( thread[i] );
		thread_destroy( thread[i] );
	}

	test_wait_for_threads_exit( thread, num_threads );

	event_stream_deallocate( stream );
	
	return 0;
}
Esempio n. 8
0
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;
}