6 #ifndef ABTI_WAITLIST_H_INCLUDED
7 #define ABTI_WAITLIST_H_INCLUDED
11 static inline void ABTI_waitlist_init(ABTI_waitlist *p_waitlist)
13 p_waitlist->p_head = NULL;
14 p_waitlist->p_tail = NULL;
18 ABTI_waitlist_wait_and_unlock(ABTI_local **pp_local, ABTI_waitlist *p_waitlist,
19 ABTI_spinlock *p_lock,
ABT_bool blocking,
22 ABTI_ASSERT(ABTI_spinlock_is_locked(p_lock) ==
ABT_TRUE);
23 ABTI_ythread *p_ythread = NULL;
24 ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(*pp_local);
25 if (!ABTI_IS_EXT_THREAD_ENABLED || p_local_xstream) {
26 p_ythread = ABTI_thread_get_ythread_or_null(p_local_xstream->p_thread);
28 if (!p_ythread || blocking) {
31 thread.type = ABTI_THREAD_TYPE_EXT;
36 if (p_waitlist->p_head == NULL) {
37 p_waitlist->p_head = &thread;
39 p_waitlist->p_tail->p_next = &thread;
41 p_waitlist->p_tail = &thread;
44 ABTI_spinlock_release(p_lock);
45 while (ABTD_atomic_acquire_load_int(&thread.state) !=
50 p_ythread->thread.p_next = NULL;
51 if (p_waitlist->p_head == NULL) {
52 p_waitlist->p_head = &p_ythread->thread;
54 p_waitlist->p_tail->p_next = &p_ythread->thread;
56 p_waitlist->p_tail = &p_ythread->thread;
59 ABTI_ythread_set_blocked(p_ythread);
60 ABTI_spinlock_release(p_lock);
61 ABTI_ythread_suspend(&p_local_xstream, p_ythread,
64 *pp_local = ABTI_xstream_get_local(p_local_xstream);
69 static inline ABT_bool ABTI_waitlist_wait_timedout_and_unlock(
70 ABTI_local **pp_local, ABTI_waitlist *p_waitlist, ABTI_spinlock *p_lock,
74 ABTI_ASSERT(ABTI_spinlock_is_locked(p_lock) ==
ABT_TRUE);
75 ABTI_ythread *p_ythread = NULL;
76 ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(*pp_local);
77 if (!ABTI_IS_EXT_THREAD_ENABLED || p_local_xstream)
78 p_ythread = ABTI_thread_get_ythread_or_null(p_local_xstream->p_thread);
82 thread.type = ABTI_THREAD_TYPE_EXT;
90 if (p_waitlist->p_head == NULL) {
91 p_waitlist->p_head = &thread;
94 p_waitlist->p_tail->p_next = &thread;
95 thread.p_prev = p_waitlist->p_tail;
97 p_waitlist->p_tail = &thread;
100 ABTI_spinlock_release(p_lock);
101 while (ABTD_atomic_acquire_load_int(&thread.state) !=
103 double cur_time = ABTI_get_wtime();
104 if (cur_time >= target_time) {
107 ABTI_spinlock_acquire(p_lock);
109 (ABTD_atomic_acquire_load_int(&thread.state) !=
115 if (p_waitlist->p_head == &thread) {
120 p_waitlist->p_head = thread.p_next;
121 if (!thread.p_next) {
123 ABTI_ASSERT(p_waitlist->p_tail == &thread);
124 p_waitlist->p_tail = NULL;
128 ABTI_ASSERT(thread.p_prev);
129 thread.p_prev->p_next = thread.p_next;
130 if (thread.p_next && thread.type == ABTI_THREAD_TYPE_EXT) {
134 thread.p_next->p_prev = thread.p_prev;
137 ABTI_ASSERT(p_waitlist->p_tail == &thread);
138 p_waitlist->p_tail = thread.p_prev;
144 ABTI_spinlock_release(p_lock);
147 if (p_ythread && !blocking) {
148 ABTI_ythread_yield(&p_local_xstream, p_ythread, sync_event_type,
150 *pp_local = ABTI_xstream_get_local(p_local_xstream);
159 static inline void ABTI_waitlist_signal(ABTI_local *p_local,
160 ABTI_waitlist *p_waitlist)
162 ABTI_thread *p_thread = p_waitlist->p_head;
164 ABTI_thread *p_next = p_thread->p_next;
165 p_thread->p_next = NULL;
167 ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
169 ABTI_ythread_set_ready(p_local, p_ythread);
172 ABTD_atomic_release_store_int(&p_thread->state,
177 p_waitlist->p_head = p_next;
179 p_waitlist->p_tail = NULL;
183 static inline void ABTI_waitlist_broadcast(ABTI_local *p_local,
184 ABTI_waitlist *p_waitlist)
186 ABTI_thread *p_thread = p_waitlist->p_head;
189 ABTI_thread *p_next = p_thread->p_next;
190 p_thread->p_next = NULL;
192 ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
194 ABTI_ythread_set_ready(p_local, p_ythread);
197 ABTD_atomic_release_store_int(&p_thread->state,
204 p_waitlist->p_head = NULL;
205 p_waitlist->p_tail = NULL;
209 static inline ABT_bool ABTI_waitlist_is_empty(ABTI_waitlist *p_waitlist)