Merge pull request #2247 from ivmai/match-ext-libgc-api
[mono.git] / mono / utils / mono-threads-coop.h
1 /*
2  * mono-threads-coop.h: Cooperative suspend thread helpers
3  *
4  * Author:
5  *      Rodrigo Kumpera (kumpera@gmail.com)
6  *
7  * (C) 2015 Xamarin
8  */
9
10 #ifndef __MONO_THREADS_COOP_H__
11 #define __MONO_THREADS_COOP_H__
12
13 #include <config.h>
14 #include <glib.h>
15
16 /* JIT specific interface */
17 extern volatile size_t mono_polling_required;
18
19 /* Runtime consumable API */
20
21 static gboolean G_GNUC_UNUSED
22 mono_threads_is_coop_enabled (void)
23 {
24 #if defined(USE_COOP_GC)
25         return TRUE;
26 #else
27         static gboolean is_coop_enabled = -1;
28         if (G_UNLIKELY (is_coop_enabled == -1))
29                 is_coop_enabled = g_getenv ("MONO_ENABLE_COOP") != NULL ? TRUE : FALSE;
30         return is_coop_enabled;
31 #endif
32 }
33
34 /* Internal API */
35
36 void mono_threads_state_poll (void);
37 void mono_threads_state_poll_stack_data (void* stackdata);
38
39 void* mono_threads_prepare_blocking (void* stackdata);
40 void mono_threads_finish_blocking (void* cookie, void* stackdata);
41
42 void* mono_threads_reset_blocking_start (void* stackdata);
43 void mono_threads_reset_blocking_end (void* cookie, void* stackdata);
44
45 static inline void
46 mono_threads_safepoint (void)
47 {
48         if (G_UNLIKELY (mono_polling_required))
49                 mono_threads_state_poll ();
50 }
51
52 #define MONO_PREPARE_BLOCKING   \
53         do {    \
54                 void *__dummy;  \
55                 void *__blocking_cookie = mono_threads_prepare_blocking (&__dummy)
56
57 #define MONO_FINISH_BLOCKING \
58                 mono_threads_finish_blocking (__blocking_cookie, &__dummy);     \
59         } while (0)
60
61 #define MONO_PREPARE_RESET_BLOCKING     \
62         do {    \
63                 void *__dummy;  \
64                 void *__reset_cookie = mono_threads_reset_blocking_start (&__dummy)
65
66 #define MONO_FINISH_RESET_BLOCKING \
67                 mono_threads_reset_blocking_end (__reset_cookie, &__dummy);     \
68         } while (0)
69
70 #endif