Merge pull request #2102 from AdamBurgess/master
[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 void* mono_threads_try_prepare_blocking (void* stackdata);
46 void mono_threads_finish_try_blocking (void* cookie, void* stackdata);
47
48 static inline void
49 mono_threads_safepoint (void)
50 {
51         if (G_UNLIKELY (mono_polling_required))
52                 mono_threads_state_poll ();
53 }
54
55 #define MONO_PREPARE_BLOCKING   \
56 {       \
57         void *__dummy;  \
58         void *__blocking_cookie = mono_threads_prepare_blocking (&__dummy);
59
60 #define MONO_FINISH_BLOCKING \
61         mono_threads_finish_blocking (__blocking_cookie, &__dummy);     \
62 }
63
64 #define MONO_PREPARE_RESET_BLOCKING     \
65 {       \
66         void *__dummy;  \
67         void *__reset_cookie = mono_threads_reset_blocking_start (&__dummy);
68
69 #define MONO_FINISH_RESET_BLOCKING \
70         mono_threads_reset_blocking_end (__reset_cookie, &__dummy);     \
71 }
72
73 #define MONO_TRY_BLOCKING       \
74 {       \
75         void *__dummy;  \
76         void *__try_block_cookie = mono_threads_try_prepare_blocking (&__dummy);
77
78 #define MONO_FINISH_TRY_BLOCKING \
79         mono_threads_finish_try_blocking (__try_block_cookie, &__dummy);        \
80 }
81
82 #endif