* Copyright 2003-2008 Ximian, Inc.
*
* See LICENSE for licensing information.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include <signal.h>
#include <mono/utils/dtrace.h>
#include "mini.h"
+#include "mini-windows.h"
#include <string.h>
#include <ctype.h>
#include "trace.h"
#include "jit-icalls.h"
-#ifdef _WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
#include <mmsystem.h>
#endif
mono_runtime_install_handlers (void)
{
#ifndef MONO_CROSS_COMPILE
- if (!mono_aot_only) {
- win32_seh_init();
- win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
- win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
- win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
- if (mini_get_debug_options ()->handle_sigint)
- win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);
- }
+ win32_seh_init();
+ win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
+ win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
+ win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
+ if (mini_get_debug_options ()->handle_sigint)
+ win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);
#endif
}
mono_runtime_cleanup_handlers (void)
{
#ifndef MONO_CROSS_COMPILE
- if (!mono_aot_only) {
- win32_seh_cleanup();
- }
+ win32_seh_cleanup();
#endif
}
return TRUE;
}
-static HANDLE win32_main_thread;
-static MMRESULT win32_timer;
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static MMRESULT g_timer_event = 0;
+static HANDLE g_timer_main_thread = INVALID_HANDLE_VALUE;
-static void CALLBACK
-win32_time_proc (UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+static VOID
+thread_timer_expired (HANDLE thread)
{
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
- if (GetThreadContext (win32_main_thread, &context)) {
+ if (GetThreadContext (thread, &context)) {
#ifdef _WIN64
mono_profiler_stat_hit ((guchar *) context.Rip, &context);
#else
}
}
-void
-mono_runtime_setup_stat_profiler (void)
+static VOID CALLBACK
+timer_event_proc (UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
- static int inited = 0;
- TIMECAPS timecaps;
+ thread_timer_expired ((HANDLE)dwUser);
+}
- if (inited)
- return;
+static VOID
+stop_profiler_timer_event (void)
+{
+ if (g_timer_event != 0) {
+
+ timeKillEvent (g_timer_event);
+ g_timer_event = 0;
+ }
+
+ if (g_timer_main_thread != INVALID_HANDLE_VALUE) {
+
+ CloseHandle (g_timer_main_thread);
+ g_timer_main_thread = INVALID_HANDLE_VALUE;
+ }
+}
+
+static VOID
+start_profiler_timer_event (void)
+{
+ g_return_if_fail (g_timer_main_thread == INVALID_HANDLE_VALUE && g_timer_event == 0);
+
+ TIMECAPS timecaps;
- inited = 1;
if (timeGetDevCaps (&timecaps, sizeof (timecaps)) != TIMERR_NOERROR)
return;
- if ((win32_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ())) == NULL)
+ g_timer_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ());
+ if (g_timer_main_thread == NULL)
return;
if (timeBeginPeriod (1) != TIMERR_NOERROR)
return;
- if ((win32_timer = timeSetEvent (1, 0, (LPTIMECALLBACK)win32_time_proc, (DWORD_PTR)NULL, TIME_PERIODIC)) == 0) {
+ g_timer_event = timeSetEvent (1, 0, (LPTIMECALLBACK)timer_event_proc, (DWORD_PTR)g_timer_main_thread, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
+ if (g_timer_event == 0) {
timeEndPeriod (1);
return;
}
}
+void
+mono_runtime_setup_stat_profiler (void)
+{
+ start_profiler_timer_event ();
+ return;
+}
+
void
mono_runtime_shutdown_stat_profiler (void)
{
+ stop_profiler_timer_event ();
+ return;
}
gboolean
-mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
+mono_setup_thread_context(DWORD thread_id, MonoContext *mono_context)
{
- DWORD id = mono_thread_info_get_tid (info);
HANDLE handle;
CONTEXT context;
- DWORD result;
- MonoContext *ctx;
- MonoJitTlsData *jit_tls;
- void *domain;
- MonoLMF *lmf = NULL;
- gpointer *addr;
- tctx->valid = FALSE;
- tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
- tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
- tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
+ g_assert (thread_id != GetCurrentThreadId ());
- g_assert (id != GetCurrentThreadId ());
-
- handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id);
+ handle = OpenThread (THREAD_ALL_ACCESS, FALSE, thread_id);
g_assert (handle);
context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
g_assert (context.ContextFlags & CONTEXT_INTEGER);
g_assert (context.ContextFlags & CONTEXT_CONTROL);
- ctx = &tctx->ctx;
+ memset (mono_context, 0, sizeof (MonoContext));
+ mono_sigctx_to_monoctx (&context, mono_context);
+
+ CloseHandle (handle);
+ return TRUE;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+gboolean
+mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
+{
+ DWORD id = mono_thread_info_get_tid (info);
+ MonoJitTlsData *jit_tls;
+ void *domain;
+ MonoLMF *lmf = NULL;
+ gpointer *addr;
+
+ tctx->valid = FALSE;
+ tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
- memset (ctx, 0, sizeof (MonoContext));
- mono_sigctx_to_monoctx (&context, ctx);
+ mono_setup_thread_context(id, &tctx->ctx);
/* mono_set_jit_tls () sets this */
jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS);
return TRUE;
}
-