OpenMPI  0.1.1
condition.h
1 /*
2  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
3  * University Research and Technology
4  * Corporation. All rights reserved.
5  * Copyright (c) 2004-2005 The University of Tennessee and The University
6  * of Tennessee Research Foundation. All rights
7  * reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  * University of Stuttgart. All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  * All rights reserved.
12  * Copyright (c) 2007 Los Alamos National Security, LLC. All rights
13  * reserved.
14  * $COPYRIGHT$
15  *
16  * Additional copyrights may follow
17  *
18  * $HEADER$
19  */
20 #ifndef OPAL_CONDITION_SPINLOCK_H
21 #define OPAL_CONDITION_SPINLOCK_H
22 
23 #include "opal_config.h"
24 #ifdef HAVE_SYS_TIME_H
25 #include <sys/time.h>
26 #endif
27 #ifdef HAVE_TIME_H
28 #include <time.h>
29 #endif
30 #if OPAL_HAVE_POSIX_THREADS
31 #include <pthread.h>
32 #elif OPAL_HAVE_SOLARIS_THREADS
33 #include <thread.h>
34 #include <synch.h>
35 #endif
36 
37 #include "opal/threads/mutex.h"
39 
40 #include "opal/runtime/opal_cr.h"
41 
42 BEGIN_C_DECLS
43 
44 /*
45  * Combine pthread support w/ polled progress to allow run-time selection
46  * of threading vs. non-threading progress.
47  */
48 
50  opal_object_t super;
51  volatile int c_waiting;
52  volatile int c_signaled;
53 #if OPAL_HAVE_POSIX_THREADS
54  pthread_cond_t c_cond;
55 #elif OPAL_HAVE_SOLARIS_THREADS
56  cond_t c_cond;
57 #endif
58  char *name;
59 };
60 typedef struct opal_condition_t opal_condition_t;
61 
63 
64 
65 static inline int opal_condition_wait(opal_condition_t *c, opal_mutex_t *m)
66 {
67  int rc = 0;
68  c->c_waiting++;
69 
70 #if OPAL_ENABLE_DEBUG && !OPAL_ENABLE_MULTI_THREADS
71  if (opal_mutex_check_locks && 0 == m->m_lock_debug) { \
72  opal_output(0, "Warning -- mutex not locked in condition_wait"); \
73  } \
74  m->m_lock_debug--;
75 #endif
76 
77  if (opal_using_threads()) {
78 #if OPAL_HAVE_POSIX_THREADS && OPAL_ENABLE_MULTI_THREADS
79  rc = pthread_cond_wait(&c->c_cond, &m->m_lock_pthread);
80 #elif OPAL_HAVE_SOLARIS_THREADS && OPAL_ENABLE_MULTI_THREADS
81  rc = cond_wait(&c->c_cond, &m->m_lock_solaris);
82 #else
83  if (c->c_signaled) {
84  c->c_waiting--;
86  opal_progress();
87  OPAL_CR_TEST_CHECKPOINT_READY_STALL();
88  opal_mutex_lock(m);
89  return 0;
90  }
91  while (c->c_signaled == 0) {
93  opal_progress();
94  OPAL_CR_TEST_CHECKPOINT_READY_STALL();
95  opal_mutex_lock(m);
96  }
97 #endif
98  } else {
99  while (c->c_signaled == 0) {
100  opal_progress();
101  OPAL_CR_TEST_CHECKPOINT_READY_STALL();
102  }
103  }
104 
105 #if OPAL_ENABLE_DEBUG && !OPAL_ENABLE_MULTI_THREADS
106  m->m_lock_debug++;
107 #endif
108 
109  c->c_signaled--;
110  c->c_waiting--;
111  return rc;
112 }
113 
114 static inline int opal_condition_timedwait(opal_condition_t *c,
115  opal_mutex_t *m,
116  const struct timespec *abstime)
117 {
118  struct timeval tv;
119  struct timeval absolute;
120  int rc = 0;
121 
122 #if OPAL_ENABLE_DEBUG && !OPAL_ENABLE_MULTI_THREADS
123  if (opal_mutex_check_locks && 0 == m->m_lock_debug) { \
124  opal_output(0, "Warning -- mutex not locked in condition_wait"); \
125  } \
126  m->m_lock_debug--;
127 #endif
128 
129  c->c_waiting++;
130  if (opal_using_threads()) {
131 #if OPAL_HAVE_POSIX_THREADS && OPAL_ENABLE_MULTI_THREADS
132  rc = pthread_cond_timedwait(&c->c_cond, &m->m_lock_pthread, abstime);
133 #elif OPAL_HAVE_SOLARIS_THREADS && OPAL_ENABLE_MULTI_THREADS
134  /* deal with const-ness */
135  timestruc_t to;
136  to.tv_sec = abstime->tv_sec;
137  to.tv_nsec = abstime->tv_nsec;
138  rc = cond_timedwait(&c->c_cond, &m->m_lock_solaris, &to);
139 #else
140  absolute.tv_sec = abstime->tv_sec;
141  absolute.tv_usec = abstime->tv_nsec * 1000;
142  gettimeofday(&tv,NULL);
143  if (c->c_signaled == 0) {
144  do {
146  opal_progress();
147  gettimeofday(&tv,NULL);
148  opal_mutex_lock(m);
149  } while (c->c_signaled == 0 &&
150  (tv.tv_sec <= absolute.tv_sec ||
151  (tv.tv_sec == absolute.tv_sec && tv.tv_usec < absolute.tv_usec)));
152  }
153 #endif
154  } else {
155  absolute.tv_sec = abstime->tv_sec;
156  absolute.tv_usec = abstime->tv_nsec * 1000;
157  gettimeofday(&tv,NULL);
158  if (c->c_signaled == 0) {
159  do {
160  opal_progress();
161  gettimeofday(&tv,NULL);
162  } while (c->c_signaled == 0 &&
163  (tv.tv_sec <= absolute.tv_sec ||
164  (tv.tv_sec == absolute.tv_sec && tv.tv_usec < absolute.tv_usec)));
165  }
166  }
167 
168 #if OPAL_ENABLE_DEBUG && !OPAL_ENABLE_MULTI_THREADS
169  m->m_lock_debug++;
170 #endif
171 
172  if (c->c_signaled != 0) c->c_signaled--;
173  c->c_waiting--;
174  return rc;
175 }
176 
177 static inline int opal_condition_signal(opal_condition_t *c)
178 {
179  if (c->c_waiting) {
180  c->c_signaled++;
181 #if OPAL_HAVE_POSIX_THREADS && OPAL_ENABLE_MULTI_THREADS
182  if(opal_using_threads()) {
183  pthread_cond_signal(&c->c_cond);
184  }
185 #elif OPAL_HAVE_SOLARIS_THREADS && OPAL_ENABLE_MULTI_THREADS
186  if(opal_using_threads()) {
187  cond_signal(&c->c_cond);
188  }
189 #endif
190  }
191  return 0;
192 }
193 
194 static inline int opal_condition_broadcast(opal_condition_t *c)
195 {
196  c->c_signaled = c->c_waiting;
197 #if OPAL_HAVE_POSIX_THREADS && OPAL_ENABLE_MULTI_THREADS
198  if (opal_using_threads()) {
199  if( 1 == c->c_waiting ) {
200  pthread_cond_signal(&c->c_cond);
201  } else {
202  pthread_cond_broadcast(&c->c_cond);
203  }
204  }
205 #elif OPAL_HAVE_SOLARIS_THREADS && OPAL_ENABLE_MULTI_THREADS
206  if (opal_using_threads()) {
207  cond_broadcast(&c->c_cond);
208  }
209 #endif
210  return 0;
211 }
212 
213 END_C_DECLS
214 
215 #endif
216 
Progress engine for Open MPI.
static void opal_mutex_lock(opal_mutex_t *mutex)
Acquire a mutex.
Definition: condition.h:49
Definition: mutex_unix.h:53
Functions for multi-threaded applications using Libevent.
static void opal_mutex_unlock(opal_mutex_t *mutex)
Release a mutex.
OPAL_DECLSPEC void opal_output(int output_id, const char *format,...) __opal_attribute_format__(__printf__
Main function to send output to a stream.
#define opal_using_threads()
Check and see if the process is using multiple threads.
Definition: mutex.h:157
Base object.
Definition: opal_object.h:182
Definition: ompi_time.h:160
OPAL_DECLSPEC void opal_progress(void)
Progress all pending events.
Definition: opal_progress.c:165
Mutual exclusion functions.
Checkpoint functionality for Open MPI.
#define OBJ_CLASS_DECLARATION(NAME)
Declaration for class descriptor.
Definition: opal_object.h:236