Ver código fonte

Add timedwait variants for conditions variables and queues

Samuel Thibault 7 anos atrás
pai
commit
cc398aa325
3 arquivos alterados com 62 adições e 0 exclusões
  1. 1 0
      include/starpu_thread.h
  2. 28 0
      include/starpu_thread_util.h
  3. 33 0
      src/common/thread.c

+ 1 - 0
include/starpu_thread.h

@@ -405,6 +405,7 @@ int starpu_pthread_queue_register(starpu_pthread_wait_t *w, starpu_pthread_queue
 int starpu_pthread_queue_unregister(starpu_pthread_wait_t *w, starpu_pthread_queue_t *q);
 int starpu_pthread_wait_reset(starpu_pthread_wait_t *w);
 int starpu_pthread_wait_wait(starpu_pthread_wait_t *w);
+int starpu_pthread_wait_timedwait(starpu_pthread_wait_t *w, const struct timespec *abstime);
 int starpu_pthread_wait_destroy(starpu_pthread_wait_t *w);
 #endif
 

+ 28 - 0
include/starpu_thread_util.h

@@ -329,6 +329,34 @@ int _starpu_pthread_rwlock_trywrlock(starpu_pthread_rwlock_t *rwlock, char *file
 	}                                                                      \
 } while (0)
 
+/* pthread_cond_timedwait not yet available on windows, but we don't run simgrid there anyway */
+#ifdef STARPU_SIMGRID
+#define STARPU_PTHREAD_COND_TIMEDWAIT(cond, mutex, abstime) \
+	_starpu_pthread_cond_timedwait(cond, mutex, abstime, __FILE__, __LINE__)
+static STARPU_INLINE
+int _starpu_pthread_cond_timedwait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex, const struct timespec *abstime, char *file, int line)
+{
+	int p_ret = starpu_pthread_cond_timedwait(cond, mutex, abstime);
+	if (STARPU_UNLIKELY(p_ret != 0 && p_ret != ETIMEDOUT)) {
+		fprintf(stderr,
+			"%s:%d starpu_pthread_cond_timedwait: %s\n",
+			file, line, strerror(p_ret));
+		STARPU_ABORT();
+	}
+	return p_ret;
+}
+#endif
+
+#define STARPU_PTHREAD_COND_TIMED_WAIT(cond, mutex, abstime) do {              \
+	int p_ret = starpu_pthread_cond_timedwait((cond), (mutex), (abstime)); \
+	if (STARPU_UNLIKELY(p_ret && p_ret != ETIMEDOUT)) {                    \
+		fprintf(stderr,                                                \
+			"%s:%d starpu_pthread_cond_timedwait: %s\n",           \
+			__FILE__, __LINE__, strerror(p_ret));                  \
+		STARPU_ABORT();                                                \
+	}                                                                      \
+} while (0)
+
 /*
  * Encapsulation of the starpu_pthread_barrier_* functions.
  */

+ 33 - 0
src/common/thread.c

@@ -23,6 +23,7 @@
 #endif
 #include <common/thread.h>
 #include <common/fxt.h>
+#include <common/timing.h>
 
 #include <errno.h>
 #include <limits.h>
@@ -340,6 +341,26 @@ int starpu_pthread_cond_wait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t
 	return 0;
 }
 
+int starpu_pthread_cond_timedwait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+	struct timespec now, delta;
+	double delay;
+	_starpu_clock_gettime(&now);
+	delta.tv_sec = abstime->tv_sec - now.tv_sec;
+	delta.tv_nsec = abstime->tv_nsec - now.tv_nsec;
+	delay = (double) delta.tv_sec + (double) delta.tv_nsec / 1000000000.;
+
+	_STARPU_TRACE_COND_WAIT_BEGIN();
+
+	_starpu_pthread_cond_auto_init(cond);
+	xbt_cond_timedwait(*cond, *mutex, delay);
+	STARPU_ASSERT(0, "FIXME: we don't have a return value for ETIMEOUT");
+
+	_STARPU_TRACE_COND_WAIT_END();
+
+	return 0;
+}
+
 int starpu_pthread_cond_destroy(starpu_pthread_cond_t *cond)
 {
 	if (*cond)
@@ -508,6 +529,18 @@ int starpu_pthread_wait_wait(starpu_pthread_wait_t *w)
 	return 0;
 }
 
+/* pthread_cond_timedwait not yet available on windows, but we don't run simgrid there anyway */
+#ifdef STARPU_SIMGRID
+int starpu_pthread_wait_timedwait(starpu_pthread_wait_t *w, const struct timespec *abstime)
+{
+	STARPU_PTHREAD_MUTEX_LOCK(&w->mutex);
+	while (w->block == 1)
+		STARPU_PTHREAD_COND_TIMEDWAIT(&w->cond, &w->mutex, abstime);
+	STARPU_PTHREAD_MUTEX_UNLOCK(&w->mutex);
+	return 0;
+}
+#endif
+
 int starpu_pthread_queue_signal(starpu_pthread_queue_t *q)
 {
 	starpu_pthread_wait_t *w;