void fcl::tools::Profiler::clear(void) { lock_.lock(); data_.clear(); tinfo_ = TimeInfo(); if (running_) tinfo_.set(); lock_.unlock(); }
void NzMemoryManager::Free(void* pointer, bool multi) { if (!pointer) return; Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<nzUInt8*>(pointer) - sizeof(Block)); if (ptr->magic != s_magic) return; #if defined(NAZARA_PLATFORM_WINDOWS) EnterCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_lock(&s_mutex); #endif if (ptr->array != multi) { char timeStr[23]; TimeInfo(timeStr); FILE* log = std::fopen(s_logFileName, "a"); const char* error = (multi) ? "delete[] after new" : "delete after new[]"; if (s_nextFreeFile) std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); else std::fprintf(log, "%s Warning: %s at unknown position\n", error, timeStr); std::fclose(log); } ptr->magic = 0; // Évitons des problèmes ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; s_allocatedBlock--; s_allocatedSize -= ptr->size; std::free(ptr); s_nextFreeFile = nullptr; s_nextFreeLine = 0; #if defined(NAZARA_PLATFORM_WINDOWS) LeaveCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_unlock(&s_mutex); #endif }
void MemoryManager::Uninitialize() { #ifdef NAZARA_PLATFORM_WINDOWS DeleteCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_destroy(&s_mutex); #endif FILE* log = std::fopen(s_logFileName, "a"); char timeStr[23]; TimeInfo(timeStr); std::fprintf(log, "%s Application finished, checking leaks...\n", timeStr); if (s_allocatedBlock == 0) { std::fprintf(log, "%s ==============================\n", timeStr); std::fprintf(log, "%s No leak detected \n", timeStr); std::fprintf(log, "%s ==============================", timeStr); } else { std::fprintf(log, "%s ==============================\n", timeStr); std::fprintf(log, "%s Leaks have been detected \n", timeStr); std::fprintf(log, "%s ==============================\n\n", timeStr); std::fputs("Leak list:\n", log); Block* ptr = s_list.next; while (ptr != &s_list) { if (ptr->file) std::fprintf(log, "-0x%s -> %zu bytes allocated at %s:%u\n", reinterpret_cast<UInt8*>(ptr) + sizeof(Block), ptr->size, ptr->file, ptr->line); else std::fprintf(log, "-0x%s -> %zu bytes allocated at unknown position\n", reinterpret_cast<UInt8*>(ptr) + sizeof(Block), ptr->size); void* pointer = ptr; ptr = ptr->next; std::free(pointer); } std::fprintf(log, "\n%u blocks leaked (%zu bytes)", s_allocatedBlock, s_allocatedSize); } std::fclose(log); }
void MemoryManager::Initialize() { char timeStr[23]; TimeInfo(timeStr); FILE* file = std::fopen(s_logFileName, "w"); std::fprintf(file, "%s ==============================\n", timeStr); std::fprintf(file, "%s Nazara Memory Leak Tracker \n", timeStr); std::fprintf(file, "%s ==============================\n", timeStr); std::fclose(file); if (std::atexit(Uninitialize) != 0) { static MemoryManager manager; } #ifdef NAZARA_PLATFORM_WINDOWS InitializeCriticalSection(&s_mutex); //#elif defined(NAZARA_PLATFORM_POSIX) is already done in the namespace #endif s_initialized = true; }
void MemoryManager::Free(void* pointer, bool multi) { if (!pointer) return; Block* ptr = reinterpret_cast<Block*>(static_cast<UInt8*>(pointer) - sizeof(Block)); if (ptr->magic != s_allocatedId) { char timeStr[23]; TimeInfo(timeStr); FILE* log = std::fopen(s_logFileName, "a"); const char* error = (ptr->magic == s_freedId) ? "double-delete" : "possible delete of dangling pointer"; if (s_nextFreeFile) std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); else std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); std::fclose(log); return; } #if defined(NAZARA_PLATFORM_WINDOWS) EnterCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_lock(&s_mutex); #endif if (ptr->array != multi) { char timeStr[23]; TimeInfo(timeStr); FILE* log = std::fopen(s_logFileName, "a"); const char* error = (multi) ? "delete[] after new" : "delete after new[]"; if (s_nextFreeFile) std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); else std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); std::fclose(log); } ptr->magic = s_freedId; ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; s_allocatedBlock--; s_allocatedSize -= ptr->size; if (s_allocationFilling) { UInt8* data = reinterpret_cast<UInt8*>(ptr) + sizeof(Block); std::memset(data, 0xFF, ptr->size); } std::free(ptr); s_nextFreeFile = nullptr; s_nextFreeLine = 0; #if defined(NAZARA_PLATFORM_WINDOWS) LeaveCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_unlock(&s_mutex); #endif }
void* MemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line) { if (!s_initialized) Initialize(); #if defined(NAZARA_PLATFORM_WINDOWS) EnterCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_lock(&s_mutex); #endif Block* ptr = static_cast<Block*>(std::malloc(size+sizeof(Block))); if (!ptr) { char timeStr[23]; TimeInfo(timeStr); FILE* log = std::fopen(s_logFileName, "a"); if (file) std::fprintf(log, "%s Failed to allocate %zu bytes at %s:%u\n", timeStr, size, file, line); else std::fprintf(log, "%s Failed to allocate %zu bytes at unknown position\n", timeStr, size); std::fclose(log); throw std::bad_alloc(); } ptr->array = multi; ptr->file = file; ptr->line = line; ptr->size = size; ptr->magic = s_allocatedId; ptr->prev = s_list.prev; ptr->next = &s_list; s_list.prev->next = ptr; s_list.prev = ptr; s_allocatedBlock++; s_allocatedSize += size; s_allocationCount++; if (s_allocationFilling) { UInt8* data = reinterpret_cast<UInt8*>(ptr) + sizeof(Block); std::memset(data, 0xFF, size); } if (s_allocationLogging) { char timeStr[23]; TimeInfo(timeStr); FILE* log = std::fopen(s_logFileName, "a"); if (file) std::fprintf(log, "%s Allocated %zu bytes at %s:%u\n", timeStr, size, file, line); else std::fprintf(log, "%s Allocated %zu bytes at unknown position\n", timeStr, size); std::fclose(log); } #if defined(NAZARA_PLATFORM_WINDOWS) LeaveCriticalSection(&s_mutex); #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_unlock(&s_mutex); #endif return reinterpret_cast<UInt8*>(ptr) + sizeof(Block); }