예제 #1
0
const char* environment_current_working_directory( void )
{
	if( _environment_current_working_dir[0] )
		return _environment_current_working_dir;
#if FOUNDATION_PLATFORM_WINDOWS
	{
		char* path;
		wchar_t* wd = memory_allocate_zero( sizeof( wchar_t ) * FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
		GetCurrentDirectoryW( FOUNDATION_MAX_PATHLEN-1, wd );
		path = path_clean( string_allocate_from_wstring( wd, 0 ), true );
		string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
		string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
		string_deallocate( path );
		memory_deallocate( wd );
	}
#elif FOUNDATION_PLATFORM_POSIX
	char* path = memory_allocate_zero( FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
	if( !getcwd( path, FOUNDATION_MAX_PATHLEN ) )
	{
		log_errorf( ERROR_SYSTEM_CALL_FAIL, "Unable to get cwd: %s", system_error_message( 0 ) );
		return "";
	}
	path = path_clean( path, true );
	string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
	memory_deallocate( path );
#else
#  error Not implemented
#endif
	return _environment_current_working_dir;
}
예제 #2
0
static void _log_outputf( uint64_t context, int severity, const char* prefix, const char* format, va_list list, void* std )
{
	log_timestamp_t timestamp = _log_make_timestamp();
	uint64_t tid = thread_id();
	unsigned int pid = thread_hardware();
	int need, more, remain, size = 383;
	char local_buffer[385];
	char* buffer = local_buffer;
	while(1)
	{
		//This is guaranteed to always fit in minimum size of 383 bytes defined above, so need is always > 0
		if( _log_prefix )
			need = snprintf( buffer, size, "[%u:%02u:%02u.%03u] <%" PRIx64 ":%d> %s", timestamp.hours, timestamp.minutes, timestamp.seconds, timestamp.milliseconds, tid, pid, prefix );
		else
			need = snprintf( buffer, size, "%s", prefix );

		remain = size - need;
		{
			va_list clist;
			va_copy( clist, list );
			more = vsnprintf( buffer + need, remain, format, clist );
			va_end( clist );
		}
			
		if( ( more > -1 ) && ( more < remain ) )
		{
			buffer[need+more] = '\n';
			buffer[need+more+1] = 0;

#if FOUNDATION_PLATFORM_WINDOWS
			OutputDebugStringA( buffer );
#endif

#if FOUNDATION_PLATFORM_ANDROID
			if( _log_stdout )
				__android_log_write( ANDROID_LOG_DEBUG + severity - 1, environment_application()->short_name, buffer );
#else
			if( _log_stdout && std )
				fprintf( std, "%s", buffer );
#endif

			if( _log_callback )
				_log_callback( context, severity, buffer );

			break;
		}

		if( ( more > -1 ) && ( need > -1 ) )
			size = more + need + 1;
		else
			size *= 2;

		if( buffer != local_buffer )
			memory_deallocate( buffer );
		buffer = memory_allocate( size + 2, 0, MEMORY_TEMPORARY );
	}
	if( buffer != local_buffer )
		memory_deallocate( buffer );
}
예제 #3
0
void
render_context_deallocate(render_context_t* context) {
	if (context) {
		render_target_unref(context->target);
		radixsort_deallocate(context->sort);
		memory_deallocate(context->commands);
		memory_deallocate(context->keys);
		memory_deallocate(context);
	}
}
예제 #4
0
파일: test.c 프로젝트: emoon/foundation_lib
static void test_free( void )
{
	unsigned int ig, gsize, ic, csize;
	for( ig = 0, gsize = array_size( _test_groups ); ig < gsize; ++ig )
	{
		for( ic = 0, csize = array_size( _test_groups[ig]->cases ); ic < csize; ++ic )
		{
			memory_deallocate( _test_groups[ig]->cases[ic] );
		}
		array_deallocate( _test_groups[ig]->cases );
		memory_deallocate( _test_groups[ig] );
	}
	array_deallocate( _test_groups );
	_test_groups = 0;
}
예제 #5
0
void stream_determine_binary_mode( stream_t* stream, unsigned int num )
{
	char* buf;
	int64_t cur;
	uint64_t actual_read, i;

	FOUNDATION_ASSERT( stream );
	if( !( stream->mode & STREAM_IN ) || stream_is_sequential( stream ) )
		return;

	if( !num )
		num = 8;

	buf = memory_allocate( num, 0, MEMORY_TEMPORARY );
	memset( buf, 32, num );
	
	cur = stream_tell( stream );
	actual_read = stream_read( stream, buf, num );
	stream_seek( stream, cur, STREAM_SEEK_BEGIN );

	stream->mode &= ~STREAM_BINARY;
	
	for( i = 0; i < actual_read; ++i )
	{
		//TODO: What about UTF-8?
		if( ( ( buf[i] < 0x20 ) && ( buf[i] != 0x09 ) && ( buf[i] != 0x0a ) && ( buf[i] != 0x0d ) ) || ( buf[i] > 0x7e ) )
		{
			stream->mode |= STREAM_BINARY;
			break;
		}
	}

	memory_deallocate( buf );
}
예제 #6
0
const char* environment_variable( const char* var )
{
#if FOUNDATION_PLATFORM_WINDOWS
	unsigned int required;
	wchar_t* key = wstring_allocate_from_string( var, 0 );
	wchar_t val[FOUNDATION_MAX_PATHLEN]; val[0] = 0;
	if( ( required = GetEnvironmentVariableW( key, val, FOUNDATION_MAX_PATHLEN ) ) > FOUNDATION_MAX_PATHLEN )
	{
		wchar_t* val_local = memory_allocate( sizeof( wchar_t ) * ( required + 2 ), 0, MEMORY_TEMPORARY );
		val_local[0] = 0;
		GetEnvironmentVariableW( key, val_local, required + 1 );
		if( _environment_var )
			string_deallocate( _environment_var );
		_environment_var = string_allocate_from_wstring( val_local, 0 );
		memory_deallocate( val_local );
	}
	else
	{
		if( _environment_var )
			string_deallocate( _environment_var );
		_environment_var = string_allocate_from_wstring( val, 0 );
	}
	wstring_deallocate( key );
	return _environment_var;
#elif FOUNDATION_PLATFORM_POSIX
	return getenv( var );
#else
#  error Not implemented
#endif
}
예제 #7
0
void
mutex_deallocate(mutex_t* mutex) {
	if (!mutex)
		return;
	_mutex_finalize(mutex);
	memory_deallocate(mutex);
}
예제 #8
0
void memory_context_thread_deallocate( void )
{
	memory_context_t* context = get_thread_memory_context();
	if( context )
		memory_deallocate( context );
	set_thread_memory_context( 0 );
}
예제 #9
0
shader_t* shader_create(const char* data, const int64_t dataSize, ShaderType type)
{
	GLuint shaderHandle = glCreateShader(type == VertexShader ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
	mint_CHECKFORGLERROR;
	{
		//Shader source should never exceed 4Gb anyway, riiight? 
		FOUNDATION_ASSERT(dataSize < 0xffffffff);
		int32_t shaderSourceSize = (int32_t) dataSize;
		glShaderSource(shaderHandle, 1, &data, &shaderSourceSize);
		mint_CHECKFORGLERROR;
		glCompileShader(shaderHandle);
		mint_CHECKFORGLERROR;

		int32_t logLength = 0, success;
		glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &success);
		glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &logLength);
		if (success != GL_TRUE && logLength > 1)
		{
			int32_t charsWritten;
			GLchar* log = (GLchar*) memory_allocate(sizeof(GLchar) * (logLength + 1), 4, MEMORY_TEMPORARY);
			glGetShaderInfoLog(shaderHandle, logLength + 1, &charsWritten, log);
			log_errorf(ERROR_NONE, "Compiler results: %s", (char*) log);
			memory_deallocate(log);
		}
	}

	shader_t* shader = (shader_t*) memory_allocate(sizeof(shader_t), 4, MEMORY_PERSISTENT);
	shader->buffer = shaderHandle;
	return shader;
}
예제 #10
0
static void _memory_tracker_shutdown( void )
{
	if( _memory_table )
		hashtable_deallocate( _memory_table );
	if( _memory_tags )
	{
		bool got_leaks = false;

		log_debug( "Checking for memory leaks" );
		for( unsigned int it = 0; it < MAX_CONCURRENT_ALLOCATIONS; ++it )
		{
			memory_tag_t* tag = _memory_tags + it;
			if( tag->address )
			{
				char* trace = stacktrace_resolve( tag->trace, 14, 0 );
				log_warnf( WARNING_MEMORY, "Memory leak: %d bytes @ " STRING_FORMAT_POINTER " : tag %d\n%s", (unsigned int)tag->size, tag->address, it, trace );
				string_deallocate( trace );
				got_leaks = true;
			}
		}
		memory_deallocate( _memory_tags );

		if( !got_leaks )
			log_debug( "No memory leaks detected" );
	}
}
예제 #11
0
DECLARE_TEST(stacktrace, resolve) {
#define TEST_DEPTH 64
	void* trace[TEST_DEPTH];
	size_t num_frames;
	char* buffer;
	string_t resolved;

	if (system_platform() == PLATFORM_PNACL)
		return 0;

	num_frames = stacktrace_capture(trace, TEST_DEPTH, 0);
	EXPECT_GT(num_frames, 3);

	buffer = memory_allocate(0, 1024, 0, MEMORY_TEMPORARY);
	resolved = stacktrace_resolve(buffer, 1024, trace, num_frames, 0);
	EXPECT_NE(resolved.str, 0);
	EXPECT_NE(resolved.length, 0);

	//log_infof(HASH_TEST, STRING_CONST("Resolved stack trace:\n%.*s"), (int)resolved.length,
	//          resolved.str);

#if !FOUNDATION_PLATFORM_ANDROID && !(FOUNDATION_PLATFORM_WINDOWS && (FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG))
	EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("stacktraceresolve_fn"),
	                             0), STRING_NPOS);
	EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("main"), 0), STRING_NPOS);
#endif

	memory_deallocate(buffer);

	return 0;
}
예제 #12
0
void
stream_determine_binary_mode(stream_t* stream, size_t num) {
	char fixed_buffer[32];
	char* buf;
	size_t cur;
	size_t actual_read, i;

	if (!(stream->mode & STREAM_IN) || stream_is_sequential(stream))
		return;

	if (!num)
		num = 8;

	buf = (num <= sizeof(fixed_buffer)) ?
	      fixed_buffer : memory_allocate(0, num, 0, MEMORY_TEMPORARY);
	memset(buf, 32, num);

	cur = stream_tell(stream);
	actual_read = stream_read(stream, buf, num);
	stream_seek(stream, (ssize_t)cur, STREAM_SEEK_BEGIN);

	stream->mode &= ~STREAM_BINARY;

	for (i = 0; i < actual_read; ++i) {
		//TODO: What about UTF-8?
		if (((buf[i] < 0x20) && (buf[i] != 0x09) && (buf[i] != 0x0a) && (buf[i] != 0x0d)) ||
		        (buf[i] > 0x7e)) {
			stream->mode |= STREAM_BINARY;
			break;
		}
	}

	if (buf != fixed_buffer)
		memory_deallocate(buf);
}
예제 #13
0
void
stream_deallocate(stream_t* stream) {
	if (!stream)
		return;
	stream_finalize(stream);
	memory_deallocate(stream);
}
예제 #14
0
void
blast_reader_close(blast_reader_t* reader) {
    //munmap(reader->data, reader->size);
    //close(reader->id);
    string_deallocate(reader->name.str);
    memory_deallocate(reader);
}
예제 #15
0
void process_deallocate( process_t* proc )
{
	if( !proc )
		return;
	process_finalize( proc );
	memory_deallocate( proc );
}
예제 #16
0
void hashmap_deallocate( hashmap_t* map )
{
	unsigned int ibucket;
	for( ibucket = 0; ibucket < map->num_buckets; ++ibucket )
		array_deallocate( map->bucket[ibucket] );
	memory_deallocate( map );
}
예제 #17
0
const char* environment_temporary_directory( void )
{
	if( _environment_temp_dir[0] )
		return _environment_temp_dir;
#if FOUNDATION_PLATFORM_WINDOWS
	{
		char* path;
		wchar_t* wpath = memory_allocate_zero( sizeof( wchar_t ) * FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
		GetTempPathW( FOUNDATION_MAX_PATHLEN, wpath );
		path = path_clean( string_allocate_from_wstring( wpath, 0 ), true );
		string_copy( _environment_temp_dir, path, FOUNDATION_MAX_PATHLEN );
		string_deallocate( path );
		memory_deallocate( wpath );
	}
#elif FOUNDATION_PLATFORM_POSIX
	string_copy( _environment_temp_dir, P_tmpdir, FOUNDATION_MAX_PATHLEN );
	unsigned int len = string_length( _environment_temp_dir );
	if( ( len > 1 ) && ( _environment_temp_dir[ len - 1 ] == '/' ) )
		_environment_temp_dir[ len - 1 ] = 0;
#else
#  error Not implemented
#endif
	if( _environment_app.config_dir )
	{
		unsigned int curlen = string_length( _environment_temp_dir );
		unsigned int cfglen = string_length( _environment_app.config_dir );
		if( ( curlen + cfglen + 2 ) < FOUNDATION_MAX_PATHLEN )
		{
			_environment_temp_dir[curlen] = '/';
			memcpy( _environment_temp_dir + curlen + 1, _environment_app.config_dir, cfglen + 1 );
		}
	}
	return _environment_temp_dir;
}
예제 #18
0
static void
_atomic_allocate_finalize(void) {
	void* storage = _memory_temporary.storage;
	memset(&_memory_temporary, 0, sizeof(_memory_temporary));
	if (storage)
		memory_deallocate(storage);
}
예제 #19
0
void
network_address_array_deallocate(network_address_t** addresses) {
	unsigned int iaddr, asize;
	for (iaddr = 0, asize = array_size(addresses); iaddr < asize; ++iaddr)
		memory_deallocate(addresses[iaddr]);
	array_deallocate(addresses);
}
예제 #20
0
void
network_poll_deallocate(network_poll_t* pollobj) {
#if FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_ANDROID
	close(pollobj->fd_poll);
#endif

	memory_deallocate(pollobj);
}
예제 #21
0
static void custom_deallocate(void* ptr) {
  assert(ptr);

  g_memory_total_size -= memory_size(ptr);
  g_memory_total_count--;

  memory_deallocate(ptr);
}
예제 #22
0
void mutex_deallocate( mutex_t* mutex )
{
	if( !mutex )
		return;

	_mutex_shutdown( mutex );

	memory_deallocate( mutex );
}
예제 #23
0
void stream_deallocate( stream_t* stream )
{
	if( !stream )
		return;
	if( stream->vtable && stream->vtable->deallocate )
		stream->vtable->deallocate( stream );
	string_deallocate( stream->path );
	memory_deallocate( stream );
}
예제 #24
0
void
lua_modulemap_finalize(void) {
	for (size_t ibucket = 0; ibucket < _lua_modulemap->num_buckets; ++ibucket) {
		hashmap_node_t* bucket = _lua_modulemap->bucket[ibucket];
		for (size_t inode = 0, nsize = array_size(bucket); inode < nsize; ++inode)
			memory_deallocate(bucket[inode].value);
	}
	hashmap_deallocate(_lua_modulemap);
	mutex_deallocate(_lua_modulemap_lock);
}
예제 #25
0
void _error_context_thread_deallocate( void )
{
	error_context_t* context = get_thread_error_context();
	if( context )
	{
		FOUNDATION_ASSERT_MSG( !context->depth, "Error context thread exit with non-zero context stack" );
		memory_deallocate( context );
		set_thread_error_context( 0 );
	}
}
예제 #26
0
static void*
objectmap_thread(void* arg) {
	objectmap_t* map;
	object_base_t* objects;
	int obj;
	int loop;
	object_base_t* lookup;

	map = arg;
	objects = memory_allocate(0, sizeof(object_base_t) * 512, 16,
	                          MEMORY_PERSISTENT | MEMORY_ZERO_INITIALIZED);

	thread_sleep(10);

	for (loop = 0; loop < 32; ++loop) {
		thread_yield();

		for (obj = 0; obj < 512; ++obj) {
			atomic_store32(&objects[obj].ref, 1);
			objects[obj].id = objectmap_reserve(map);
			EXPECT_NE_MSGFORMAT(objects[obj].id, 0, "Unable to reserve slot for object num %d", obj);
			EXPECT_EQ_MSGFORMAT(objectmap_lookup(map, objects[obj].id), 0,
			                    "Object %d (%" PRIx64 ") already stored in map in loop %d",
			                    obj, objects[obj].id, loop);
			EXPECT_TRUE(objectmap_set(map, objects[obj].id, objects + obj));
			lookup = objectmap_lookup(map, objects[obj].id);
			EXPECT_NE_MSGFORMAT(lookup, 0, "Object num %d (%" PRIx64 ") not set in map, got null on lookup in loop %d",
			                    obj, objects[obj].id, loop);
			EXPECT_EQ_MSGFORMAT(lookup, objects + obj,
			                    "Object %d (%" PRIx64 ") 0x%" PRIfixPTR " was not set at reserved slot in map, got object 0x%"
			                    PRIfixPTR " in loop %d", obj, objects[obj].id, (uintptr_t)(objects + obj), (uintptr_t)lookup, loop);
		}

		thread_yield();

		for (obj = 0; obj < 512; ++obj) {
			void* raw = map->map[ objects[obj].id & map->mask_index ];
			lookup = objectmap_lookup(map, objects[obj].id);
			EXPECT_NE_MSGFORMAT(lookup, 0, "Object 0x%" PRIfixPTR " num %d (%" PRIx64 ") not set in map, got null on lookup in loop %d (raw 0x%" PRIfixPTR ")",
			                    (uintptr_t)(objects + obj), obj, objects[obj].id, loop, (uintptr_t)raw);
			EXPECT_EQ_MSGFORMAT(lookup, objects + obj,
			                    "Object %d (%" PRIx64 ") 0x%" PRIfixPTR " was not set at reserved slot in map, got object 0x%"
			                    PRIfixPTR " in loop %d", obj, objects[obj].id, (uintptr_t)(objects + obj), (uintptr_t)lookup, loop);
			EXPECT_TRUE(objectmap_free(map, objects[obj].id));
			lookup = objectmap_lookup(map, objects[obj].id);
			EXPECT_EQ_MSGFORMAT(lookup, 0,
			                    "Object %d (%" PRIx64 ") 0x%" PRIfixPTR " still set in map, got non-null (0x%" PRIfixPTR ") on lookup in loop %d", obj,
			                    objects[obj].id, (uintptr_t)(objects + obj), (uintptr_t)lookup, loop);
		}
	}

	memory_deallocate(objects);

	return 0;
}
예제 #27
0
static void _load_process_modules()
{
	int           error = 0;	
	bool          succeeded;
	HMODULE       module_handles[MAX_MOD_HANDLES];
	HMODULE*      module_handle = module_handles;
	int           module_count = 0;
	int           i;
	DWORD         bytes = 0;
	MODULEINFO    module_info;
	HANDLE        process_handle = GetCurrentProcess(); 

	succeeded = CallEnumProcessModules( process_handle, module_handles, sizeof( module_handles ), &bytes );
	if( !succeeded )
	{
		error = GetLastError();
		return;
	}

	if( bytes > sizeof( module_handles ) )
	{
		module_handle = memory_allocate( bytes, 0, MEMORY_TEMPORARY );
		CallEnumProcessModules( process_handle, module_handle, bytes, &bytes );
	}

	module_count = bytes / sizeof( HMODULE );

	for( i = 0; i < module_count; ++i )
	{
		char module_name[1024];
		char image_name[1024];
		char search_path[1024];
		char* file_name = 0;
		uint64_t base_address;

		CallGetModuleInformation( process_handle, module_handle[i], &module_info, sizeof( module_info ) );
		CallGetModuleFileNameEx( process_handle, module_handle[i], image_name, 1024 );
		CallGetModuleBaseName( process_handle, module_handle[i], module_name, 1024 );

		GetFullPathNameA( image_name, 1024, search_path, &file_name );
		*file_name = 0;
		CallSymSetSearchPath( process_handle, search_path );

		base_address = CallSymLoadModule64( process_handle, module_handle[i], image_name, module_name, (uint64_t)((uintptr_t)module_info.lpBaseOfDll), module_info.SizeOfImage );
		if( !base_address )
		{
			error = GetLastError();
		}
	} 

	// Free the module handle pointer allocated in case the static array was insufficient.
	if( module_handle != module_handles )
		memory_deallocate( module_handle );
}
예제 #28
0
static void _buffer_stream_finalize( stream_t* stream )
{
	stream_buffer_t* bufferstream = (stream_buffer_t*)stream;

	if( !bufferstream || ( stream->type != STREAMTYPE_MEMORY ) )
		return;

	if( bufferstream->own )
		memory_deallocate( bufferstream->buffer );
	bufferstream->buffer = 0;
}
예제 #29
0
파일: cvsu_types.c 프로젝트: amnipar/cvsu
void typed_pointer_destroy
(
    typed_pointer *tptr
)
{
    if (tptr != NULL && tptr->value != NULL) {
        memory_deallocate((data_pointer*)&tptr->value);
        tptr->type = t_UNDEF;
        tptr->count = 0;
    }
}
예제 #30
0
static void _library_destroy( library_t* library )
{
	objectmap_free( _library_map, library->id );

#if FOUNDATION_PLATFORM_WINDOWS
	FreeLibrary( library->dll );
#elif FOUNDATION_PLATFORM_POSIX
	dlclose( library->lib );
#endif

	memory_deallocate( library );
}