Exemplo n.º 1
0
DWORD WINAPI Sampler::AsyncUpdate(LPVOID lpParam)
{
	Sampler& sampler = *(Sampler*)(lpParam);

	std::vector<std::pair<HANDLE, ThreadEntry*>> openThreads;
	openThreads.reserve(sampler.targetThreads.size());

	for (auto entryIterator = sampler.targetThreads.begin() ; entryIterator != sampler.targetThreads.end() ; ++entryIterator)
	{
		ThreadEntry* entry = *entryIterator;
		DWORD threadID = entry->description.threadID;
		BRO_VERIFY(threadID != GetCurrentThreadId(), "It's a bad idea to sample specified thread! Deadlock will occur!", continue);

		HANDLE hThread = GetThreadHandleByThreadID(threadID);
		if (hThread == 0)
			continue;

		openThreads.push_back(std::make_pair(hThread, entry));
	}

	if (openThreads.empty())
		return 0;

	CallStackBuffer buffer;

	CONTEXT context;

	while ( sampler.finishEvent.WaitForEvent(sampler.intervalMicroSeconds) )
	{
		// Check whether we are inside sampling scope
		for (auto entry = openThreads.cbegin() ; entry != openThreads.cend() ; ++entry)
		{
			HANDLE handle = entry->first;
			const ThreadEntry* thread = entry->second;

			if (!thread->storage.isSampling)
				continue;

			uint count = 0;

			if (PauseThread(handle))
			{
				// Check scope again because it is possible to leave sampling scope while trying to suspend main thread
				if (thread->storage.isSampling && RetrieveThreadContext(handle, context))
				{
					count = sampler.symEngine.GetCallstack(handle, context, buffer);
				}
				ContinueThread(handle);
			}

			if (count > 0)
			{
				sampler.callstacks.push_back(CallStack(buffer.begin(), buffer.begin() + count));
			}
		}
	}

	for (auto entry = openThreads.begin() ; entry != openThreads.end() ; ++entry)
		ReleaseThreadHandle(entry->first);

	return 0;
}
Exemplo n.º 2
0
HMODULE Sys_LoadLibrary( const char *pLibraryName, Sys_Flags flags )
{
	char str[ 1024 ];
	// Note: DLL_EXT_STRING can be "_srv.so" or "_360.dll". So be careful
	//	when using the V_*Extension* routines...
	const char *pDllStringExtension = V_GetFileExtension( DLL_EXT_STRING );
	const char *pModuleExtension = pDllStringExtension ? ( pDllStringExtension - 1 ) : DLL_EXT_STRING;

	Q_strncpy( str, pLibraryName, sizeof(str) );

	if ( IsX360() )
	{
		// old, probably busted, behavior for xbox
		if ( !Q_stristr( str, pModuleExtension ) )
		{
			V_SetExtension( str, pModuleExtension, sizeof(str) );
		}
	}
	else
	{
		// always force the final extension to be .dll
		V_SetExtension( str, pModuleExtension, sizeof(str) );
	}

	Q_FixSlashes( str );

#ifdef _WIN32
	ThreadedLoadLibraryFunc_t threadFunc = GetThreadedLoadLibraryFunc();
	if ( !threadFunc )
		return InternalLoadLibrary( str, flags );

	// We shouldn't be passing noload while threaded.
	Assert( !( flags & SYS_NOLOAD ) );

	ThreadedLoadLibaryContext_t context;
	context.m_pLibraryName = str;
	context.m_hLibrary = 0;

	ThreadHandle_t h = CreateSimpleThread( ThreadedLoadLibraryFunc, &context );

#ifdef _X360
	ThreadSetAffinity( h, XBOX_PROCESSOR_3 );
#endif

	unsigned int nTimeout = 0;
	while( ThreadWaitForObject( h, true, nTimeout ) == TW_TIMEOUT )
	{
		nTimeout = threadFunc();
	}

	ReleaseThreadHandle( h );
	return context.m_hLibrary;

#elif POSIX
	int dlopen_mode = RTLD_NOW;

	if ( flags & SYS_NOLOAD )
		dlopen_mode |= RTLD_NOLOAD;

	HMODULE ret = ( HMODULE )dlopen( str, dlopen_mode );
	if ( !ret && !( flags & SYS_NOLOAD ) )
	{
		const char *pError = dlerror();
		if ( pError && ( strstr( pError, "No such file" ) == 0 ) && ( strstr( pError, "image not found" ) == 0 ) )
		{
			Msg( " failed to dlopen %s error=%s\n", str, pError );
		}
	}
	
	return ret;
#endif
}