Beispiel #1
0
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);
	}