Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-10-01 00:47:24 +0300
committerScott Mosier <smosier@microsoft.com>2015-10-01 00:47:24 +0300
commitad0323ab91a7b1469b42ca5457ddd631b94294fe (patch)
tree88fae57e1ec3aae90288463dc07e58f7aebc1de8 /src/Native/Runtime/Profiling.cpp
parent6763d16387778f126ec510c0421783952602f8f7 (diff)
Initial population of CoreRT Runtime files.
Diffstat (limited to 'src/Native/Runtime/Profiling.cpp')
-rw-r--r--src/Native/Runtime/Profiling.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/Native/Runtime/Profiling.cpp b/src/Native/Runtime/Profiling.cpp
new file mode 100644
index 000000000..be8e23ebf
--- /dev/null
+++ b/src/Native/Runtime/Profiling.cpp
@@ -0,0 +1,148 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+#include "common.h"
+#ifdef DACCESS_COMPILE
+#include "gcrhenv.h"
+#endif // DACCESS_COMPILE
+
+#ifndef DACCESS_COMPILE
+#include "commontypes.h"
+#include "daccess.h"
+#include "commonmacros.h"
+#include "palredhawkcommon.h"
+#include "palredhawk.h"
+#include "assert.h"
+#include "static_check.h"
+#include "slist.h"
+#include "holder.h"
+#include "crst.h"
+#include "rhbinder.h" // for GenericInstanceDesc
+#include "rwlock.h"
+#include "runtimeinstance.h"
+#include "gcrhinterface.h"
+#include "module.h"
+#else
+#include "rhbinder.h"
+#include "runtimeinstance.h"
+#include "gcrhinterface.h"
+#include "module.h"
+#endif
+
+// Macro nonsense to get around limitations of the C++ preprocessor.
+#define MAKE_WIDE_STRING(_str) L ## _str
+#define WIDE_STRING(_str) MAKE_WIDE_STRING(_str)
+
+#define MAIN_RH_MODULE_NAME_W WIDE_STRING(RH_BASE_NAME)
+
+
+
+#ifdef FEATURE_PROFILING
+#ifndef APP_LOCAL_RUNTIME //need to sort out how to get this thread started, where to log, etc., without violating the WACK
+UInt32 __stdcall ProfileThread(void *pv)
+{
+ RuntimeInstance *runtimeInstance = (RuntimeInstance *)pv;
+ for (;;)
+ {
+ PalSleep(10*1000);
+ runtimeInstance->WriteProfileInfo();
+ }
+}
+#endif
+
+void RuntimeInstance::InitProfiling(ModuleHeader *pModuleHeader)
+{
+#ifndef APP_LOCAL_RUNTIME //need to sort out how to get this thread started, where to log, etc., without violating the WACK
+ if (!m_fProfileThreadCreated && pModuleHeader->GetProfilingEntries() != NULL)
+ {
+ // this module has profile data, and we don't have a profile-writing thread yet
+ // so let's create one
+ UInt32 threadId;
+ PalCreateThread(NULL, 4096, ProfileThread, this, 0, &threadId);
+
+ m_fProfileThreadCreated = true;
+ }
+#endif
+}
+
+
+void RuntimeInstance::WriteProfileInfo()
+{
+#ifndef APP_LOCAL_RUNTIME //need to sort out how to get this thread started, where to log, etc., without violating the WACK
+ FOREACH_MODULE(pModule)
+ {
+ PTR_ModuleHeader pModuleHeader = pModule->GetModuleHeader();
+ if (pModuleHeader->GetProfilingEntries() != NULL)
+ {
+ // our general error handling strategy is just to give up writing the profile
+ // if we encounter any errors or the names get insanely long
+ WCHAR *wzModuleFileName;
+ const size_t MAX_PATH = 260;
+ size_t moduleFileNameLength = PalGetModuleFileName(&wzModuleFileName, pModule->GetOsModuleHandle());
+ if (moduleFileNameLength >= MAX_PATH)
+ continue;
+ const UInt32 BUFFER_SIZE = 512;
+ WCHAR profileName[BUFFER_SIZE];
+ WCHAR *basicName = wcsrchr(wzModuleFileName, L'\\');
+ if (basicName == NULL)
+ basicName = wzModuleFileName;
+ else
+ basicName += 1; // skip past the '\'
+ size_t basicNameLength = wcslen(basicName);
+ size_t dirNameLength = PalGetEnvironmentVariableW(L"LOCALAPPDATA", profileName, MAX_PATH);
+
+ // make sure the names are not so long as to cause trouble
+ const size_t MAX_SAFE_LENGTH = MAX_PATH - 50;
+ if ( basicNameLength >= MAX_SAFE_LENGTH
+ || dirNameLength >= MAX_SAFE_LENGTH
+ || basicNameLength + dirNameLength >= MAX_SAFE_LENGTH)
+ {
+ continue;
+ }
+
+ // make sure %LOCALAPPDATA%\Microsoft\mrt100\ProfileData exists
+ wcscat_s(profileName, L"\\Microsoft");
+ if (!PalCreateDirectoryW(profileName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
+ continue;
+
+ wcscat_s(profileName, L"\\");
+ wcscat_s(profileName, MAIN_RH_MODULE_NAME_W);
+ if (!PalCreateDirectoryW(profileName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
+ continue;
+
+ wcscat_s(profileName, L"\\ProfileData");
+ if (!PalCreateDirectoryW(profileName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
+ continue;
+
+ // final filename is %LOCALAPPDATA%\Microsoft\mrt100\ProfileData\<basicName>.profile
+ wcscat_s(profileName, L"\\");
+ wcscat_s(profileName, basicName);
+ wcscat_s(profileName, L".profile");
+ HANDLE fileHandle = PalCreateFileW(profileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if (fileHandle == INVALID_HANDLE_VALUE)
+ {
+ continue;
+ }
+ else
+ {
+ ProfilingEntry *profilingEntry = (ProfilingEntry *)pModuleHeader->GetProfilingEntries();
+ ProfilingEntry *profilingEntryLast = profilingEntry + pModuleHeader->CountOfProfilingEntries;
+ for( ; profilingEntry < profilingEntryLast; profilingEntry++)
+ {
+ if (profilingEntry->m_count != 0)
+ {
+ UInt32 bytesWritten = 0;
+ if (!PalWriteFile(fileHandle, profilingEntry, sizeof(ProfilingEntry), &bytesWritten, NULL))
+ break;
+ }
+ }
+ PalCloseHandle(fileHandle);
+ }
+ }
+ }
+ END_FOREACH_MODULE;
+#endif //!APP_LOCAL_RUNTIME
+}
+#endif // FEATURE_PROFILING
+