2020 *
2121 * Copyright (c) 2020 Cisco Systems, Inc. All rights reserved.
2222 * Copyright (c) 2021 Argonne National Laboratory. All rights reserved.
23+ * Copyright (c) 2022 Sandia National Laboratories. All rights reserved.
2324 * $COPYRIGHT$
2425 *
2526 * Additional copyrights may follow
3839#include "opal/constants.h"
3940#include "opal/mca/threads/qthreads/threads_qthreads.h"
4041#include "opal/sys/atomic.h"
41- #include "opal/util/output .h"
42+ #include "opal/util/show_help .h"
4243
4344BEGIN_C_DECLS
4445
45- typedef opal_atomic_lock_t opal_thread_internal_mutex_t ;
46+ typedef qthread_spinlock_t opal_thread_internal_mutex_t ;
4647
47- #define OPAL_THREAD_INTERNAL_MUTEX_INITIALIZER OPAL_ATOMIC_LOCK_INIT
48- #define OPAL_THREAD_INTERNAL_RECURSIVE_MUTEX_INITIALIZER OPAL_ATOMIC_LOCK_INIT
48+ #define OPAL_THREAD_INTERNAL_MUTEX_INITIALIZER QTHREAD_MUTEX_INITIALIZER
49+ #define OPAL_THREAD_INTERNAL_RECURSIVE_MUTEX_INITIALIZER QTHREAD_RECURSIVE_MUTEX_INITIALIZER
4950
5051static inline int opal_thread_internal_mutex_init (opal_thread_internal_mutex_t * p_mutex ,
5152 bool recursive )
5253{
53- opal_atomic_lock_init (p_mutex , 0 );
54+ opal_threads_ensure_init_qthreads ();
55+ #if OPAL_ENABLE_DEBUG
56+ int ret = qthread_spinlock_init (p_mutex ,recursive );
57+ if (QTHREAD_SUCCESS != ret ) {
58+ opal_show_help ("help-opal-threads.txt" , "mutex init failed" , true);
59+ }
60+ #else
61+ qthread_spinlock_init (p_mutex ,recursive );
62+ #endif
5463 return OPAL_SUCCESS ;
5564}
5665
5766static inline void opal_thread_internal_mutex_lock (opal_thread_internal_mutex_t * p_mutex )
5867{
5968 opal_threads_ensure_init_qthreads ();
60-
61- int ret = opal_atomic_trylock (p_mutex );
62- while (0 != ret ) {
63- qthread_yield ();
64- ret = opal_atomic_trylock (p_mutex );
69+ #if OPAL_ENABLE_DEBUG
70+ int ret = qthread_spinlock_lock (p_mutex );
71+ if (QTHREAD_SUCCESS != ret ) {
72+ opal_show_help ("help-opal-threads.txt" , "mutex lock failed" , true);
6573 }
74+ #else
75+ qthread_spinlock_lock (p_mutex );
76+ #endif
6677}
6778
6879static inline int opal_thread_internal_mutex_trylock (opal_thread_internal_mutex_t * p_mutex )
6980{
7081 opal_threads_ensure_init_qthreads ();
71-
72- int ret = opal_atomic_trylock (p_mutex );
73- if (0 != ret ) {
74- /* Yield to avoid a deadlock. */
75- qthread_yield ();
76- }
77- return ret ;
82+ int ret = qthread_spinlock_trylock (p_mutex );
83+ if (QTHREAD_OPFAIL == ret ) {
84+ return 1 ;
85+ } else if (QTHREAD_SUCCESS != ret ) {
86+ #if OPAL_ENABLE_DEBUG
87+ opal_show_help ("help-opal-threads.txt" , "mutex trylock failed" , true);
88+ #endif
89+ return 1 ;
90+ }
91+ return 0 ;
7892}
7993
8094static inline void opal_thread_internal_mutex_unlock (opal_thread_internal_mutex_t * p_mutex )
8195{
8296 opal_threads_ensure_init_qthreads ();
83-
84- opal_atomic_unlock (p_mutex );
97+ int ret ;
98+ #if OPAL_ENABLE_DEBUG
99+ ret = qthread_spinlock_unlock (p_mutex );
100+ if (QTHREAD_SUCCESS != ret ) {
101+ opal_show_help ("help-opal-threads.txt" , "mutex unlock failed" , true);
102+ }
103+ #else
104+ qthread_spinlock_unlock (p_mutex );
105+ #endif
85106 /* For fairness of locking. */
86107 qthread_yield ();
87108}
@@ -97,19 +118,19 @@ typedef struct opal_thread_cond_waiter_t {
97118} opal_thread_cond_waiter_t ;
98119
99120typedef struct {
100- opal_atomic_lock_t m_lock ;
121+ opal_thread_internal_mutex_t m_lock ;
101122 opal_thread_cond_waiter_t * m_waiter_head ;
102123 opal_thread_cond_waiter_t * m_waiter_tail ;
103124} opal_thread_internal_cond_t ;
104125
105126#define OPAL_THREAD_INTERNAL_COND_INITIALIZER \
106127 { \
107- .m_lock = OPAL_ATOMIC_LOCK_INIT , .m_waiter_head = NULL, .m_waiter_tail = NULL, \
128+ .m_lock = QTHREAD_MUTEX_INITIALIZER , .m_waiter_head = NULL, .m_waiter_tail = NULL, \
108129 }
109130
110131static inline int opal_thread_internal_cond_init (opal_thread_internal_cond_t * p_cond )
111132{
112- opal_atomic_lock_init (& p_cond -> m_lock , 0 );
133+ qthread_spinlock_init (& p_cond -> m_lock , false /* is_recursive */ );
113134 p_cond -> m_waiter_head = NULL ;
114135 p_cond -> m_waiter_tail = NULL ;
115136 return OPAL_SUCCESS ;
@@ -121,24 +142,23 @@ static inline void opal_thread_internal_cond_wait(opal_thread_internal_cond_t *p
121142 opal_threads_ensure_init_qthreads ();
122143 /* This thread is taking "lock", so only this thread can access this
123144 * condition variable. */
124- opal_atomic_lock (& p_cond -> m_lock );
145+ qthread_spinlock_lock (& p_cond -> m_lock );
125146 opal_thread_cond_waiter_t waiter = {0 , NULL };
126147 if (NULL == p_cond -> m_waiter_head ) {
127148 p_cond -> m_waiter_tail = & waiter ;
128149 } else {
129150 p_cond -> m_waiter_head -> m_prev = & waiter ;
130151 }
131152 p_cond -> m_waiter_head = & waiter ;
132- opal_atomic_unlock (& p_cond -> m_lock );
133-
134- while (1 ) {
153+ qthread_spinlock_unlock (& p_cond -> m_lock );
154+ while (1 ) {
135155 opal_thread_internal_mutex_unlock (p_mutex );
136156 qthread_yield ();
137157 opal_thread_internal_mutex_lock (p_mutex );
138158 /* Check if someone woke me up. */
139- opal_atomic_lock (& p_cond -> m_lock );
159+ qthread_spinlock_lock (& p_cond -> m_lock );
140160 int signaled = waiter .m_signaled ;
141- opal_atomic_unlock (& p_cond -> m_lock );
161+ qthread_spinlock_unlock (& p_cond -> m_lock );
142162 if (1 == signaled ) {
143163 break ;
144164 }
@@ -148,7 +168,7 @@ static inline void opal_thread_internal_cond_wait(opal_thread_internal_cond_t *p
148168
149169static inline void opal_thread_internal_cond_broadcast (opal_thread_internal_cond_t * p_cond )
150170{
151- opal_atomic_lock (& p_cond -> m_lock );
171+ qthread_spinlock_lock (& p_cond -> m_lock );
152172 while (NULL != p_cond -> m_waiter_tail ) {
153173 opal_thread_cond_waiter_t * p_cur_tail = p_cond -> m_waiter_tail ;
154174 p_cond -> m_waiter_tail = p_cur_tail -> m_prev ;
@@ -157,12 +177,12 @@ static inline void opal_thread_internal_cond_broadcast(opal_thread_internal_cond
157177 }
158178 /* No waiters. */
159179 p_cond -> m_waiter_head = NULL ;
160- opal_atomic_unlock (& p_cond -> m_lock );
180+ qthread_spinlock_unlock (& p_cond -> m_lock );
161181}
162182
163183static inline void opal_thread_internal_cond_signal (opal_thread_internal_cond_t * p_cond )
164184{
165- opal_atomic_lock (& p_cond -> m_lock );
185+ qthread_spinlock_lock (& p_cond -> m_lock );
166186 if (NULL != p_cond -> m_waiter_tail ) {
167187 opal_thread_cond_waiter_t * p_cur_tail = p_cond -> m_waiter_tail ;
168188 p_cond -> m_waiter_tail = p_cur_tail -> m_prev ;
@@ -172,7 +192,7 @@ static inline void opal_thread_internal_cond_signal(opal_thread_internal_cond_t
172192 p_cond -> m_waiter_head = NULL ;
173193 }
174194 }
175- opal_atomic_unlock (& p_cond -> m_lock );
195+ qthread_spinlock_unlock (& p_cond -> m_lock );
176196}
177197
178198static inline void opal_thread_internal_cond_destroy (opal_thread_internal_cond_t * p_cond )
0 commit comments