[coop] Refactor/reuse mono_value_box_handle/mono_value_box_checked and reduce raw...
[mono-project.git] / mono / utils / mono-threads-api.h
blobd5f48d46b8de2af367886c9d1aa5ef7d8d9bd48a
1 /**
2 * \file
3 * Low level access to thread state.
5 * Author:
6 * Rodrigo Kumpera (kumpera@gmail.com)
8 * (C) 2015 Xamarin
9 */
11 #ifndef __MONO_THREADS_API_H__
12 #define __MONO_THREADS_API_H__
14 #include <glib.h>
15 #include <mono/utils/mono-publib.h>
16 #include <mono/utils/mono-compiler.h>
18 MONO_BEGIN_DECLS
21 >>>> WARNING WARNING WARNING <<<<
23 This API is experimental. It will eventually be required to properly use the rest of the raw-omp embedding API.
26 typedef struct _MonoStackData {
27 gpointer stackpointer;
28 const char *function_name;
29 } MonoStackData;
31 // FIXME an ifdef to change __func__ to empty or further minimization.
32 #define MONO_STACKDATA(x) MonoStackData x = { &x, __func__ }
34 static inline const char*
35 mono_stackdata_get_function_name (const MonoStackData *stackdata)
37 return stackdata->function_name;
40 static inline gpointer
41 mono_stackdata_get_stackpointer (const MonoStackData *stackdata)
43 return stackdata->stackpointer;
46 MONO_API MONO_RT_EXTERNAL_ONLY gpointer
47 mono_threads_enter_gc_unsafe_region (gpointer* stackdata);
49 gpointer
50 mono_threads_enter_gc_unsafe_region_internal (MonoStackData *stackdata);
52 MONO_API MONO_RT_EXTERNAL_ONLY void
53 mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer* stackdata);
55 void
56 mono_threads_exit_gc_unsafe_region_internal (gpointer cookie, MonoStackData *stackdata);
58 MONO_API gpointer
59 mono_threads_enter_gc_unsafe_region_unbalanced (gpointer* stackdata);
61 gpointer
62 mono_threads_enter_gc_unsafe_region_unbalanced_internal (MonoStackData *stackdata);
64 MONO_API void
65 mono_threads_exit_gc_unsafe_region_unbalanced (gpointer cookie, gpointer* stackdata);
67 void
68 mono_threads_exit_gc_unsafe_region_unbalanced_internal (gpointer cookie, MonoStackData *stackdata);
70 MONO_API MONO_RT_EXTERNAL_ONLY void
71 mono_threads_assert_gc_unsafe_region (void);
73 MONO_API MONO_RT_EXTERNAL_ONLY gpointer
74 mono_threads_enter_gc_safe_region (gpointer *stackdata);
76 MONO_PROFILER_API gpointer
77 mono_threads_enter_gc_safe_region_internal (MonoStackData *stackdata);
79 MONO_API MONO_RT_EXTERNAL_ONLY void
80 mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata);
82 MONO_PROFILER_API void
83 mono_threads_exit_gc_safe_region_internal (gpointer cookie, MonoStackData *stackdata);
85 MONO_API gpointer
86 mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata);
88 gpointer
89 mono_threads_enter_gc_safe_region_unbalanced_internal (MonoStackData *stackdata);
91 MONO_API void
92 mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata);
94 void
95 mono_threads_exit_gc_safe_region_unbalanced_internal (gpointer cookie, MonoStackData *stackdata);
97 MONO_API void
98 mono_threads_assert_gc_safe_region (void);
101 Use those macros to limit regions of code that interact with managed memory or use the embedding API.
102 This will put the current thread in GC Unsafe mode.
104 For further explanation of what can and can't be done in GC unsafe mode:
105 http://www.mono-project.com/docs/advanced/runtime/docs/coop-suspend/#gc-unsafe-mode
107 #define MONO_ENTER_GC_UNSAFE \
108 do { \
109 MONO_STACKDATA (__gc_unsafe_dummy); \
110 gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region_internal (&__gc_unsafe_dummy)
112 #define MONO_EXIT_GC_UNSAFE \
113 mono_threads_exit_gc_unsafe_region_internal (__gc_unsafe_cookie, &__gc_unsafe_dummy); \
114 } while (0)
116 #define MONO_ENTER_GC_UNSAFE_UNBALANCED \
117 do { \
118 MONO_STACKDATA (__gc_unsafe_unbalanced_dummy); \
119 gpointer __gc_unsafe_unbalanced_cookie = mono_threads_enter_gc_unsafe_region_unbalanced_internal (&__gc_unsafe_unbalanced_dummy)
121 #define MONO_EXIT_GC_UNSAFE_UNBALANCED \
122 mono_threads_exit_gc_unsafe_region_unbalanced_internal (__gc_unsafe_unbalanced_cookie, &__gc_unsafe_unbalanced_dummy); \
123 } while (0)
125 #define MONO_ENTER_GC_SAFE \
126 do { \
127 MONO_STACKDATA (__gc_safe_dummy); \
128 gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region_internal (&__gc_safe_dummy)
130 #define MONO_EXIT_GC_SAFE \
131 mono_threads_exit_gc_safe_region_internal (__gc_safe_cookie, &__gc_safe_dummy); \
132 } while (0)
134 #define MONO_ENTER_GC_SAFE_UNBALANCED \
135 do { \
136 MONO_STACKDATA (__gc_safe_unbalanced_dummy); \
137 gpointer __gc_safe_unbalanced_cookie = mono_threads_enter_gc_safe_region_unbalanced_internal (&__gc_safe_unbalanced_dummy)
139 #define MONO_EXIT_GC_SAFE_UNBALANCED \
140 mono_threads_exit_gc_safe_region_unbalanced_internal (__gc_safe_unbalanced_cookie, &__gc_safe_unbalanced_dummy); \
141 } while (0)
143 void
144 mono_threads_enter_no_safepoints_region (const char *func);
146 void
147 mono_threads_exit_no_safepoints_region (const char *func);
149 #define MONO_ENTER_NO_SAFEPOINTS \
150 do { \
151 do { \
152 if (mono_threads_are_safepoints_enabled ()) \
153 mono_threads_enter_no_safepoints_region (__func__); \
154 } while (0)
156 #define MONO_EXIT_NO_SAFEPOINTS \
157 if (mono_threads_are_safepoints_enabled ()) \
158 mono_threads_exit_no_safepoints_region (__func__); \
159 } while (0)
161 MONO_END_DECLS
163 #endif /* __MONO_LOGGER_H__ */