ARGOBOTS
abti_local.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #ifndef ABTI_LOCAL_H_INCLUDED
7 #define ABTI_LOCAL_H_INCLUDED
8 
9 /*
10  * An inlined getter function for ES Local Data. This function is more
11  * efficient than ABTI_local_get_local_uninlined, but it can be used once only
12  * at the beginning of the function to avoid TLS caching across context switch.
13  *
14  * Consider the following case:
15  *
16  * int ABT_any_func()
17  * {
18  * ABTI_xstream *p_xstream = ABTI_local_get_local()->p_xstream;
19  * [context switch (e.g., ABTI_thread_yield())];
20  * ABTI_xstream *p_xstream2 = ABTI_local_get_local()->p_xstream;
21  * }
22  *
23  * p_xstream and p_xstream2 can be always the same although context switch
24  * changes the running execution stream because a compiler assumes that the
25  * running Pthreads is the same across the function call
26  * (i.e., ABTI_thread_yield()) and caches a thread local value as a compiler
27  * optimization. To avoid this, we need to assure that the second
28  * ABTI_local_get_local() really reads the thread local value again.
29  *
30  * See https://github.com/pmodels/argobots/issues/55 for details.
31  *
32  * ABTI_local_get_local_uninlined() guarantees that it truly reads the thread
33  * local value of the current Pthreads, but it is slow.
34  * ABTI_local_get_local_uninlined() should be used only after context switch
35  * happens, and in other cases, ABTI_local_get_local() should be called for
36  * performance.
37  *
38  * If you don't understand this problem well and it is not in the critical path,
39  * use the uninlined version for correctness.
40  */
41 static inline ABTI_local *ABTI_local_get_local(void)
42 {
43  return lp_ABTI_local;
44 }
45 
46 /*
47  * A safe getter function for ES Local Data, which guarantees that it reads
48  * the thread local value without referring to the cached TLS. This is slower
49  * than ABTI_local_get_local(), so use ABTI_local_get_local() if possible.
50  */
51 static inline ABTI_local *ABTI_local_get_local_uninlined(void)
52 {
53  return gp_ABTI_local_func.get_local_f();
54 }
55 
56 /*
57  * A setter function for ES Local Data. This function is rarely called, so it
58  * uses a slow version for correctness.
59  */
60 static inline void ABTI_local_set_local(ABTI_local *p_local)
61 {
62  gp_ABTI_local_func.set_local_f(p_local);
63 }
64 
65 /*
66  * A safe getter function for a pointer to an ES Local Data, which is useful to
67  * identify a native thread (i.e., execution streams and external threads).
68  */
69 static inline void *ABTI_local_get_local_ptr(void)
70 {
71  return gp_ABTI_local_func.get_local_ptr_f();
72 }
73 
74 #endif /* ABTI_LOCAL_H_INCLUDED */
ABTI_local_func gp_ABTI_local_func
Definition: local.c:27
ABTD_XSTREAM_LOCAL ABTI_local * lp_ABTI_local
Definition: local.c:33