1
2
3
4
5
6
7
8
9
10 #ifndef ORTE_THREADS_H
11 #define ORTE_THREADS_H
12
13 #include "orte_config.h"
14
15 #include "opal/sys/atomic.h"
16 #include "opal/threads/threads.h"
17
18
19
20
21
22
23
24 #define ORTE_POST_OBJECT(o) opal_atomic_wmb()
25
26
27
28 #define ORTE_ACQUIRE_OBJECT(o) opal_atomic_rmb()
29
30 #define orte_condition_wait(a,b) pthread_cond_wait(a, &(b)->m_lock_pthread)
31 typedef pthread_cond_t orte_condition_t;
32 #define orte_condition_broadcast(a) pthread_cond_broadcast(a)
33 #define orte_condition_signal(a) pthread_cond_signal(a)
34 #define ORTE_CONDITION_STATIC_INIT PTHREAD_COND_INITIALIZER
35
36
37 #define ORTE_THREADSHIFT(x, eb, f, p) \
38 do { \
39 opal_event_set((eb), &((x)->ev), -1, OPAL_EV_WRITE, (f), (x)); \
40 opal_event_set_priority(&((x)->ev), (p)); \
41 ORTE_POST_OBJECT((x)); \
42 opal_event_active(&((x)->ev), OPAL_EV_WRITE, 1); \
43 } while(0)
44
45 typedef struct {
46 opal_mutex_t mutex;
47 orte_condition_t cond;
48 volatile bool active;
49 } orte_lock_t;
50
51 #define ORTE_CONSTRUCT_LOCK(l) \
52 do { \
53 OBJ_CONSTRUCT(&(l)->mutex, opal_mutex_t); \
54 pthread_cond_init(&(l)->cond, NULL); \
55 (l)->active = true; \
56 } while(0)
57
58 #define ORTE_DESTRUCT_LOCK(l) \
59 do { \
60 OBJ_DESTRUCT(&(l)->mutex); \
61 pthread_cond_destroy(&(l)->cond); \
62 } while(0)
63
64
65 #if OPAL_ENABLE_DEBUG
66 #define ORTE_ACQUIRE_THREAD(lck) \
67 do { \
68 opal_mutex_lock(&(lck)->mutex); \
69 if (opal_debug_threads) { \
70 opal_output(0, "Waiting for thread %s:%d", \
71 __FILE__, __LINE__); \
72 } \
73 while ((lck)->active) { \
74 orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
75 } \
76 if (opal_debug_threads) { \
77 opal_output(0, "Thread obtained %s:%d", \
78 __FILE__, __LINE__); \
79 } \
80 (lck)->active = true; \
81 OPAL_ACQUIRE_OBJECT(lck); \
82 } while(0)
83 #else
84 #define ORTE_ACQUIRE_THREAD(lck) \
85 do { \
86 opal_mutex_lock(&(lck)->mutex); \
87 while ((lck)->active) { \
88 orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
89 } \
90 (lck)->active = true; \
91 OPAL_ACQUIRE_OBJECT(lck); \
92 } while(0)
93 #endif
94
95
96 #if OPAL_ENABLE_DEBUG
97 #define ORTE_WAIT_THREAD(lck) \
98 do { \
99 opal_mutex_lock(&(lck)->mutex); \
100 if (opal_debug_threads) { \
101 opal_output(0, "Waiting for thread %s:%d", \
102 __FILE__, __LINE__); \
103 } \
104 while ((lck)->active) { \
105 orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
106 } \
107 if (opal_debug_threads) { \
108 opal_output(0, "Thread obtained %s:%d", \
109 __FILE__, __LINE__); \
110 } \
111 OPAL_ACQUIRE_OBJECT(&lck); \
112 opal_mutex_unlock(&(lck)->mutex); \
113 } while(0)
114 #else
115 #define ORTE_WAIT_THREAD(lck) \
116 do { \
117 opal_mutex_lock(&(lck)->mutex); \
118 while ((lck)->active) { \
119 orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
120 } \
121 OPAL_ACQUIRE_OBJECT(lck); \
122 opal_mutex_unlock(&(lck)->mutex); \
123 } while(0)
124 #endif
125
126
127 #if OPAL_ENABLE_DEBUG
128 #define ORTE_RELEASE_THREAD(lck) \
129 do { \
130 if (opal_debug_threads) { \
131 opal_output(0, "Releasing thread %s:%d", \
132 __FILE__, __LINE__); \
133 } \
134 (lck)->active = false; \
135 OPAL_POST_OBJECT(lck); \
136 orte_condition_broadcast(&(lck)->cond); \
137 opal_mutex_unlock(&(lck)->mutex); \
138 } while(0)
139 #else
140 #define ORTE_RELEASE_THREAD(lck) \
141 do { \
142 (lck)->active = false; \
143 OPAL_POST_OBJECT(lck); \
144 orte_condition_broadcast(&(lck)->cond); \
145 opal_mutex_unlock(&(lck)->mutex); \
146 } while(0)
147 #endif
148
149
150 #define ORTE_WAKEUP_THREAD(lck) \
151 do { \
152 opal_mutex_lock(&(lck)->mutex); \
153 (lck)->active = false; \
154 OPAL_POST_OBJECT(lck); \
155 orte_condition_broadcast(&(lck)->cond); \
156 opal_mutex_unlock(&(lck)->mutex); \
157 } while(0)
158
159 #endif