コード例 #1
0
ファイル: buffer.c プロジェクト: ifzz/render_lib
void
render_buffer_lock(object_t id, unsigned int lock) {
	render_buffer_t* buffer = GET_BUFFER(id);
	if (render_buffer_ref(id) != id)
		return;
	if (lock & RENDERBUFFER_LOCK_WRITE) {
		atomic_incr32(&buffer->locks);
		buffer->access = buffer->store;
	}
	else if (lock & RENDERBUFFER_LOCK_READ) {
		atomic_incr32(&buffer->locks);
		buffer->access = buffer->store;
	}
	buffer->flags |= (lock & RENDERBUFFER_LOCK_BITS);
}
コード例 #2
0
ファイル: profile.c プロジェクト: HardlyHaki/ProDBG
static profile_block_t* _profile_allocate_block( void )
{
	//Grab block from free list, avoiding ABA issues by
	//using high 16 bit as a loop counter
	profile_block_t* block;
	uint32_t free_block_tag, free_block, next_block_tag;
	do
	{
		free_block_tag = atomic_load32( &_profile_free );
		free_block = free_block_tag & 0xffff;

		next_block_tag = GET_BLOCK( free_block )->child;
		next_block_tag |= ( atomic_incr32( &_profile_loopid ) & 0xffff ) << 16;
	} while( free_block && !atomic_cas32( &_profile_free, next_block_tag, free_block_tag ) );

	if( !free_block )
	{
		static atomic32_t has_warned = {0};
		if( atomic_cas32( &has_warned, 1, 0 ) )
			log_error( 0, ERROR_OUT_OF_MEMORY, ( _profile_num_blocks < 65535 ) ? "Profile blocks exhausted, increase profile memory block size" : "Profile blocks exhausted, decrease profile output wait time" );
		return 0;
	}

	block = GET_BLOCK( free_block );
	memset( block, 0, sizeof( profile_block_t ) );
	return block;
}
コード例 #3
0
ファイル: main.c プロジェクト: rampantpixels/foundation_lib
static void*
thread_waiter(void* arg) {
	mutex_t* mutex = arg;

	atomic_incr32(&thread_waiting);

	if (mutex_try_wait(mutex, 30000)) {
		atomic_incr32(&thread_waited);
		mutex_unlock(mutex);
	}
	else {
		log_warn(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Thread timeout"));
	}

	return 0;
}
コード例 #4
0
ファイル: profile.c プロジェクト: HardlyHaki/ProDBG
static void _profile_free_block( uint32_t block, uint32_t leaf )
{
	uint32_t last_tag, block_tag;
	do
	{
		block_tag = block | ( ( atomic_incr32( &_profile_loopid ) & 0xffff ) << 16 );
		last_tag = atomic_load32( &_profile_free );
		GET_BLOCK( leaf )->child = last_tag & 0xffff;
	} while( !atomic_cas32( &_profile_free, block_tag, last_tag ) );
}
コード例 #5
0
ファイル: main.c プロジェクト: emoon/foundation_lib
static void* thread_wait( object_t thread, void* arg )
{
	mutex_t* mutex = arg;
	FOUNDATION_UNUSED( thread );
	FOUNDATION_UNUSED( arg );

	atomic_incr32( &thread_waiting );

	if( mutex_wait( mutex, 30000 ) )
	{
		atomic_incr32( &thread_waited );
		mutex_unlock( mutex );
	}
	else
	{
		log_warn( HASH_TEST, WARNING_SUSPICIOUS, "Thread timeout" );
	}

	return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: haifenghuang/foundation_lib
static void*
inc_thread(void* arg) {
	int loop = 0;
	int icount = 0;
	FOUNDATION_UNUSED(arg);
	while (!thread_try_wait(0) && (loop < 65535)) {
		for (icount = 0; icount < 256; ++icount) {
			atomic_incr32(&val_32);
			atomic_incr64(&val_64);
		}

		++loop;
		thread_yield();
	}
	return 0;
}
コード例 #7
0
ファイル: main.c プロジェクト: NocturnDragon/foundation_lib
void* inc_thread( object_t thread, void* arg )
{
    int loop = 0;
    int icount = 0;
    while( !thread_should_terminate( thread ) && ( loop < 65535 ) )
    {
        for( icount = 0; icount < 256; ++icount )
        {
            atomic_incr32( &val_32 );
            atomic_incr64( &val_64 );
        }

        ++loop;
        thread_yield();
    }
    return 0;
}
コード例 #8
0
ファイル: uuid.c プロジェクト: HardlyHaki/ProDBG
uuid_t uuid_generate_time( void )
{
	uuid_time_t time_uuid;
	uuid_convert_t convert;
	int64_t current_time;
	int32_t current_counter;
	tick_t current_tick;
	int in = 0;
	uint32_t clock_seq = 0;
	uint64_t host_id = 0;

	//Allows creation of 10000 unique timestamps per millisecond
	current_time = time_system();
	current_counter = atomic_incr32( &_uuid_last_counter ) % 10000;

	current_tick = ( (tick_t)current_time * 10000ULL ) + current_counter + 0x01B21DD213814000ULL; //Convert to 100ns since UUID UTC base time, October 15 1582, and add counter

	//We have no state so clock sequence is random
	clock_seq = random32();

	time_uuid.time_low = (uint32_t)( current_tick & 0xFFFFFFFFULL );
	time_uuid.time_mid = (uint16_t)( ( current_tick >> 32ULL ) & 0xFFFFULL );
	time_uuid.time_hi_and_version = (uint16_t)( current_tick >> 48ULL );
	time_uuid.clock_seq_low = ( clock_seq & 0xFF );
	time_uuid.clock_seq_hi_and_reserved = ( ( clock_seq & 0x3F00 ) >> 8 );

	//If hardware node ID is null, use random and set identifier (multicast) bit
	host_id = system_hostid();
	if( host_id )
	{
		for( in = 0; in < 6; ++in )
			time_uuid.node[5-in] = (uint8_t)( ( host_id >> ( 8ULL * in ) ) & 0xFF );
	}
	else
	{
		for( in = 0; in < 6; ++in )
コード例 #9
0
ファイル: main.c プロジェクト: emoon/foundation_lib
static void test_profile_output( void* buffer, uint64_t size )
{
	FOUNDATION_UNUSED( buffer );
	FOUNDATION_UNUSED( size );
	atomic_incr32( &_test_profile_output_counter );
}
コード例 #10
0
ファイル: mutex.c プロジェクト: haifenghuang/foundation_lib
bool
mutex_try_wait(mutex_t* mutex, unsigned int milliseconds) {
#if FOUNDATION_PLATFORM_WINDOWS
	DWORD ret;
#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL
	struct timeval now;
	struct timespec then;
#endif
#if FOUNDATION_PLATFORM_WINDOWS

#if !BUILD_DEPLOY
	profile_wait(STRING_ARGS(mutex->name));
#endif

	atomic_incr32(&mutex->waiting);

	ret = WaitForSingleObject(mutex->event, milliseconds);

	if (ret == WAIT_OBJECT_0)
		mutex_lock(mutex);

	if (atomic_decr32(&mutex->waiting) == 0)
		ResetEvent(mutex->event);

	return ret == WAIT_OBJECT_0;

#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL

	mutex_lock(mutex);

	if (mutex->pending) {
		mutex->pending = false;
		return true;
	}
	if (!milliseconds) {
		mutex_unlock(mutex);
		return false;
	}

	--mutex->lockcount;

	bool was_signal = false;
	if (milliseconds == 0xFFFFFFFF) {
		int ret = pthread_cond_wait(&mutex->cond, &mutex->mutex);
		if (ret == 0) {
			was_signal = true;
		}
		else {
			string_const_t errmsg = system_error_message(ret);
			log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to wait on mutex '%.*s': %.*s (%d)"),
			           STRING_FORMAT(mutex->name), STRING_FORMAT(errmsg), ret);
		}
	}
	else {
		int ret;
		gettimeofday(&now, 0);
		then.tv_sec  = now.tv_sec + (time_t)(milliseconds / 1000);
		then.tv_nsec = (now.tv_usec * 1000) + (long)(milliseconds % 1000) * 1000000L;
		while (then.tv_nsec >= 1000000000L) {
			++then.tv_sec;
			then.tv_nsec -= 1000000000L;
		}
		ret = pthread_cond_timedwait(&mutex->cond, &mutex->mutex, &then);
		if (ret == 0) {
			was_signal = true;
		}
		else if (ret != ETIMEDOUT) {
			string_const_t errmsg = system_error_message(ret);
			log_errorf(0, ERROR_SYSTEM_CALL_FAIL,
			           STRING_CONST("Unable to wait (timed) on mutex '%.*s': %.*s (%d)"),
			           STRING_FORMAT(mutex->name), STRING_FORMAT(errmsg), ret);
		}
	}

	++mutex->lockcount;
	mutex->lockedthread = thread_id();

	if (was_signal)
		mutex->pending = false;
	else
		mutex_unlock(mutex);

	return was_signal;

#else
#  error mutex_wait not implemented
#endif
}
コード例 #11
0
ファイル: mutex.c プロジェクト: apprisi/foundation_lib
bool mutex_wait( mutex_t* mutex, unsigned int timeout )
{
#if FOUNDATION_PLATFORM_WINDOWS
	DWORD ret;
#elif FOUNDATION_PLATFORM_POSIX
	struct timeval now;
	struct timespec then;
#endif	
	FOUNDATION_ASSERT( mutex );
#if FOUNDATION_PLATFORM_WINDOWS

#if !BUILD_DEPLOY
	profile_wait( mutex->name );
#endif

	atomic_incr32( &mutex->waiting );

	ret = WaitForSingleObject( mutex->event, ( timeout == 0 ) ? INFINITE : timeout );

	if( ret == WAIT_OBJECT_0 )
		mutex_lock( mutex );
	
	if( atomic_decr32( &mutex->waiting ) == 0 )
		ResetEvent( mutex->event );

	return ret == WAIT_OBJECT_0;

#elif FOUNDATION_PLATFORM_POSIX
	
	mutex_lock( mutex );
	
	if( mutex->pending )
	{
		mutex->pending = false;
		return true;
	}

	--mutex->lockcount;
	
	bool was_signal = false;
	if( !timeout )
	{
		int ret = pthread_cond_wait( &mutex->cond, &mutex->mutex );
		if( ret == 0 )
		{
			was_signal = true;
		}
		else
		{
			log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to wait on mutex '%s': %s (%d)", mutex->name, system_error_message( ret ), ret );
		}
	}
	else
	{
		int ret;
		gettimeofday( &now, 0 );
		then.tv_sec  = now.tv_sec + ( timeout / 1000 );
		then.tv_nsec = ( now.tv_usec * 1000 ) + (long)( timeout % 1000 ) * 1000000L;
		while( then.tv_nsec > 999999999 )
		{
			++then.tv_sec;
			then.tv_nsec -= 1000000000L;
		}
		ret = pthread_cond_timedwait( &mutex->cond, &mutex->mutex, &then );
		if( ret == 0 )
		{
			was_signal = true;
		}
		else if( ret != ETIMEDOUT )
		{
			log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to wait (timed) on mutex '%s': %s (%d)", mutex->name, system_error_message( ret ), ret );
		}
	}

	++mutex->lockcount;
	mutex->lockedthread = thread_id();
	
	if( was_signal )
		mutex->pending = false;
	else
		mutex_unlock( mutex );
	
	return was_signal;

#else
#  error mutex_wait not implemented
#endif
}
コード例 #12
0
object_t library_load( const char* name )
{
	library_t* library;
	hash_t namehash;
	unsigned int i, size;
	uint64_t id;
#if FOUNDATION_PLATFORM_WINDOWS
	char* dllname;
	HANDLE dll;
#endif

	//Locate already loaded library
	library = 0;
	namehash = string_hash( name );
	for( i = 0, size = objectmap_size( _library_map ); i < size; ++i )
	{
		library = objectmap_raw_lookup( _library_map, i );
		if( library && ( library->namehash == namehash ) )
		{
			FOUNDATION_ASSERT( string_equal( library->name, name ) );
			atomic_incr32( &library->ref );
			return library->id;
		}
	}
	
	error_context_push( "loading library", name );

	//Try loading library
#if FOUNDATION_PLATFORM_WINDOWS

	dllname = string_format( "%s.dll", name );
	dll = LoadLibraryA( dllname );
	if( !dll )
	{
#if FOUNDATION_PLATFORM_ARCH_X86
		string_deallocate( dllname );
		dllname = string_format( "%s32.dll", name );
		dll = LoadLibraryA( dllname );
#elif FOUNDATION_PLATFORM_ARCH_X86_64
		string_deallocate( dllname );
		dllname = string_format( "%s64.dll", name );
		dll = LoadLibraryA( dllname );
#endif
	}
	string_deallocate( dllname );
	if( !dll )
	{
		log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load DLL '%s': %s", name, system_error_message( 0 ) );
		error_context_pop();
		return 0;
	}

#elif FOUNDATION_PLATFORM_POSIX

#  if FOUNDATION_PLATFORM_APPLE
	char* libname = string_format( "lib%s.dylib", name );
#  else
	char* libname = string_format( "lib%s.so", name );
#  endif
	void* lib = dlopen( libname, RTLD_LAZY );
	string_deallocate( libname );
#if FOUNDATION_PLATFORM_ANDROID
	if( !lib )
	{
		libname = string_format( "%s/lib%s.so", environment_executable_directory(), name );
		lib = dlopen( libname, RTLD_LAZY );
		string_deallocate( libname );
	}
#endif
	if( !lib )
	{
		log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load dynamic library '%s': %s", name, dlerror() );
		error_context_pop();
		return 0;
	}

#else
	
	log_errorf( 0, ERROR_NOT_IMPLEMENTED, "Dynamic library loading not implemented for this platform: %s", name );
	error_context_pop();
	return 0;

#endif

	id = objectmap_reserve( _library_map );
	if( !id )
	{
#if FOUNDATION_PLATFORM_WINDOWS
		FreeLibrary( dll );
#elif FOUNDATION_PLATFORM_POSIX
		dlclose( lib );
#endif
		log_errorf( 0, ERROR_OUT_OF_MEMORY, "Unable to allocate new library '%s', map full", name );	
		error_context_pop();
		return 0;
	}
	library = memory_allocate_zero( sizeof( library_t ), 0, MEMORY_PERSISTENT );
	library->ref = 1;
	library->id = id;
	library->namehash = string_hash( name );
	string_copy( library->name, name, 32 );
#if FOUNDATION_PLATFORM_WINDOWS
	library->dll = dll;
#elif FOUNDATION_PLATFORM_POSIX
	library->lib = lib;
#endif
	objectmap_set( _library_map, id, library );

	error_context_pop();
	
	return library->id;
}