sirp Posted October 13, 2010 Posted October 13, 2010 ProfilerCallback.cpp// This is the function that will invoke the managed code through COM interop on another thread// this function creates the CCW object// [in] this pointerDWORD WINAPI CreateManagedStub(LPVOID lpParam){ _ManagedStub * pIManagedStub = NULL; HRESULT hr = CoCreateInstance(CLSID_ManagedStub, NULL, CLSCTX_INPROC_SERVER, IID__ManagedStub, (void **)&pIManagedStub); if (FAILED(hr)) { printf("Fail to CoCreateInstance on ManagedStub class 0x%x\n", hr); return 1; } if (pIManagedStub == NULL) { printf("pIManagedStub is null 0x%x\n", hr); return 1; } // we have the managed instance now. ((CProfilerCallback*)lpParam)->m_pIManagedStub = pIManagedStub; return 0;}// this function is the actual caller to the managed world. // this function can be used to get a managed dynamic method token back// [in] this pointer; method token; assembly name// [out] delegate type nameDWORD WINAPI ManagedPreStub(LPVOID lpParam){ PMYDATA pData = (PMYDATA)lpParam; LPWSTR delegateName = NULL; if (pData->thisObj->m_pIManagedStub == NULL) { printf("pData->thisObj->m_pIManagedStub is null"); return 1; } HRESULT hr = pData->thisObj->m_pIManagedStub->PreStub(pData->assemblyName, pData->methodTk, &delegateName); if (FAILED(hr)) { printf("Fail to Call PreStub 0x%x\n", hr); } wcscpy_s(pData->delegateName, (wchar_t*)delegateName); return 0;}......// Profiler callback functionHRESULT CProfilerCallback::JITCompilationstarted(UINT functionId, BOOL fIsSafeToBlock){ HANDLE hThread = NULL; DWORD dwThreadId; ///////////////////////////////////////////////////////// // We dont want to continue on JITCompilationstarted if the thread is for the "managed code" we are to call from this callback. // We store these thread ids in our skip thread hashtable // 1. if the JITCompilationstarted is on one of the skipping thread, avoid following steps. DWORD currentThreadId = GetCurrentThreadId(); if (m_SkipJCHashTable->PLookup(currentThreadId)) return S_OK; // create the ManagedStub object if (m_pIManagedStub==NULL) // if it is already created, no need to create twice { hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateManagedStub, this, 0, &dwThreadId); // add the thread Id to skip pool so that JITCompilationstarted will do nothing on that thread. m_SkipJCHashTable->SetAt(dwThreadId, 0); if (hThread != NULL) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } m_SkipJCHashTable->RemoveKey(dwThreadId); }.... /////////////////////////////////////////////////////// // try to define a managed dynamic method and get the dynamic method method token // prepare the parameters to be passed in PMYDATA pData = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA)); if( pData == NULL ) goto exit; pData->assemblyName = wszAssemblyName; pData->methodTk = tkMethod; pData->thisObj = this; ProfilerPrintf("Working on asm %ws func %ws.", wszAssemblyName, wszFunctionName); hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ManagedPreStub, pData, 0, &dwThreadId); m_SkipJCHashTable->SetAt(dwThreadId, 0); if (hThread != NULL) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } m_SkipJCHashTable->RemoveKey(dwThreadId); // we free up the memory here instead of in the thread because we want some return value back. wchar_t wszDelegateName[512]; if (pData->delegateName == NULL) return S_OK; // copy the return value out wcsncpy_s(wszDelegateName, _countof(pData->delegateName), pData->delegateName, _countof(pData->delegateName)); HeapFree(GetProcessHeap(), 0, pData);...We have these definitions in ProfilerCallback.h:private: CMap<DWORD, DWORD, int, int> * m_SkipJCHashTable; ... Enjoy!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now