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; }
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 ); }
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); } }
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; }
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 ); }
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 }
void mutex_deallocate(mutex_t* mutex) { if (!mutex) return; _mutex_finalize(mutex); memory_deallocate(mutex); }
void memory_context_thread_deallocate( void ) { memory_context_t* context = get_thread_memory_context(); if( context ) memory_deallocate( context ); set_thread_memory_context( 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; }
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" ); } }
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; }
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); }
void stream_deallocate(stream_t* stream) { if (!stream) return; stream_finalize(stream); memory_deallocate(stream); }
void blast_reader_close(blast_reader_t* reader) { //munmap(reader->data, reader->size); //close(reader->id); string_deallocate(reader->name.str); memory_deallocate(reader); }
void process_deallocate( process_t* proc ) { if( !proc ) return; process_finalize( proc ); memory_deallocate( proc ); }
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 ); }
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; }
static void _atomic_allocate_finalize(void) { void* storage = _memory_temporary.storage; memset(&_memory_temporary, 0, sizeof(_memory_temporary)); if (storage) memory_deallocate(storage); }
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); }
void network_poll_deallocate(network_poll_t* pollobj) { #if FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_ANDROID close(pollobj->fd_poll); #endif memory_deallocate(pollobj); }
static void custom_deallocate(void* ptr) { assert(ptr); g_memory_total_size -= memory_size(ptr); g_memory_total_count--; memory_deallocate(ptr); }
void mutex_deallocate( mutex_t* mutex ) { if( !mutex ) return; _mutex_shutdown( mutex ); memory_deallocate( mutex ); }
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 ); }
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); }
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 ); } }
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; }
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 ); }
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; }
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; } }
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 ); }