27using namespace NSROOT::OS;
34 mutex_init(&x_gate_lock);
36 mutex_init(&s_gate_lock);
40 TNode * n1 = new_node(thread_t());
41 TNode * n2 = new_node(thread_t());
46Latch::TNode * Latch::find_node(
const thread_t&
id)
49 while (p !=
nullptr && thread_equal(p->id,
id) == 0)
56Latch::TNode * Latch::new_node(
const thread_t&
id)
59 if (s_freed ==
nullptr)
78 if (s_nodes !=
nullptr)
86void Latch::free_node(TNode * n)
95 n->_prev->_next = n->_next;
97 if (n->_next !=
nullptr)
99 n->_next->_prev = n->_prev;
103 if (s_freed !=
nullptr)
124Latch::Latch(
bool _px)
139 while (s_freed !=
nullptr) {
141 s_freed = s_freed->_next;
145 while (s_nodes !=
nullptr) {
147 s_nodes = s_nodes->_next;
151 cond_destroy(&s_gate);
152 mutex_destroy(&s_gate_lock);
153 cond_destroy(&x_gate);
154 mutex_destroy(&x_gate_lock);
174#define EXIT_TIMEOUT 1000
178 thread_t tid = thread_self();
182 if (!thread_equal(x_owner, tid))
191 if (x_flag == X_STEP_0 || x_flag == X_STEP_2)
200 mutex_lock(&x_gate_lock);
202 cond_timedwait(&x_gate, &x_gate_lock, EXIT_TIMEOUT);
203 mutex_unlock(&x_gate_lock);
209 TNode * n = find_node(tid);
216 if (s_nodes ==
nullptr || (s_nodes == n && s_nodes->_next ==
nullptr))
224 mutex_lock(&s_gate_lock);
226 cond_timedwait(&s_gate, &s_gate_lock, EXIT_TIMEOUT);
227 mutex_unlock(&s_gate_lock);
230 if (x_flag == X_STEP_3)
251 thread_t tid = thread_self();
254 if (thread_equal(x_owner, tid))
258 if (x_flag == X_STEP_2)
260 x_owner = thread_t(0);
268 mutex_lock(&x_gate_lock);
269 cond_broadcast(&x_gate);
270 mutex_unlock(&x_gate_lock);
283void Latch::lock_shared()
285 thread_t tid = thread_self();
290 TNode * n = find_node(tid);
292 if (!thread_equal(x_owner, tid))
302 if (x_flag < X_STEP_2)
312 if (x_flag == X_STEP_0 || (x_flag == X_STEP_1 && n !=
nullptr))
318 mutex_lock(&x_gate_lock);
320 cond_timedwait(&x_gate, &x_gate_lock, EXIT_TIMEOUT);
321 mutex_unlock(&x_gate_lock);
335void Latch::unlock_shared()
337 thread_t tid = thread_self();
342 TNode * n = find_node(tid);
344 assert(n !=
nullptr);
351 if (x_flag == X_STEP_1 && !thread_equal(x_owner, tid))
353 if (s_nodes ==
nullptr)
359 mutex_lock(&s_gate_lock);
360 cond_signal(&s_gate);
361 mutex_unlock(&s_gate_lock);
374bool Latch::try_lock_shared()
376 thread_t tid = thread_self();
382 if (x_flag == X_STEP_0 || thread_equal(x_owner, tid))
385 TNode * n = find_node(tid);