Browse Source

now links on windows

Samuel Thibault 15 years ago
parent
commit
8e9b6a48df
6 changed files with 118 additions and 26 deletions
  1. 35 9
      acinclude.m4
  2. 9 2
      configure.ac
  3. 46 12
      include/pthread-win32/pthread.h
  4. 21 1
      include/starpu-util.h
  5. 5 0
      src/common/utils.c
  6. 2 2
      src/core/perfmodel/perfmodel_history.c

+ 35 - 9
acinclude.m4

@@ -1,16 +1,29 @@
 dnl This test is taken from libgfortran
 
-dnl Check whether the target supports __sync_*_compare_and_swap.
-AC_DEFUN([STARPU_CHECK_SYNC_BUILTINS], [
-  AC_CACHE_CHECK([whether the target supports __sync_*_compare_and_swap],
-		 ac_cv_have_sync_builtins, [
+dnl Check whether the target supports __sync_val_compare_and_swap.
+AC_DEFUN([STARPU_CHECK_SYNC_VAL_COMPARE_SWAP], [
+  AC_CACHE_CHECK([whether the target supports __sync_val_compare_and_swap],
+		 ac_cv_have_sync_val_compare_and_swap, [
   AC_LINK_IFELSE([AC_LANG_PROGRAM([int foo, bar;],
 			[bar = __sync_val_compare_and_swap(&foo, 0, 1);])],
-			[ac_cv_have_sync_builtins=yes],
-			[ac_cv_have_sync_builtins=no])])
-  if test $ac_cv_have_sync_builtins = yes; then
-    AC_DEFINE(STARPU_HAVE_SYNC_BUILTINS, 1,
-	      [Define to 1 if the target supports __sync_*_compare_and_swap])
+			[ac_cv_have_sync_val_compare_and_swap=yes],
+			[ac_cv_have_sync_val_compare_and_swap=no])])
+  if test $ac_cv_have_sync_val_compare_and_swap = yes; then
+    AC_DEFINE(STARPU_HAVE_SYNC_VAL_COMPARE_SWAP, 1,
+	      [Define to 1 if the target supports __sync_val_compare_and_swap])
+  fi])
+
+dnl Check whether the target supports __sync_bool_compare_and_swap.
+AC_DEFUN([STARPU_CHECK_SYNC_BOOL_COMPARE_AND_SWAP], [
+  AC_CACHE_CHECK([whether the target supports __sync_bool_compare_and_swap],
+		 ac_cv_have_sync_bool_compare_and_swap, [
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([int foo, bar;],
+			[bar = __sync_bool_compare_and_swap(&foo, 0, 1);])],
+			[ac_cv_have_sync_bool_compare_and_swap=yes],
+			[ac_cv_have_sync_bool_compare_and_swap=no])])
+  if test $ac_cv_have_sync_bool_compare_and_swap = yes; then
+    AC_DEFINE(STARPU_HAVE_SYNC_BOOL_COMPARE_AND_SWAP, 1,
+	      [Define to 1 if the target supports __sync_bool_compare_and_swap])
   fi])
 
 dnl Check whether the target supports __sync_fetch_and_add.
@@ -51,3 +64,16 @@ AC_DEFUN([STARPU_CHECK_SYNC_LOCK_TEST_AND_SET], [
     AC_DEFINE(STARPU_HAVE_SYNC_LOCK_TEST_AND_SET, 1,
 	      [Define to 1 if the target supports __sync_lock_test_and_set])
   fi])
+
+dnl Check whether the target supports __sync_synchronize.
+AC_DEFUN([STARPU_CHECK_SYNC_SYNCHRONIZE], [
+  AC_CACHE_CHECK([whether the target supports __sync_synchronize],
+		 ac_cv_have_sync_synchronize, [
+  AC_LINK_IFELSE([AC_LANG_PROGRAM(,
+			[__sync_synchronize();])],
+			[ac_cv_have_sync_synchronize=yes],
+			[ac_cv_have_sync_synchronize=no])])
+  if test $ac_cv_have_sync_synchronize = yes; then
+    AC_DEFINE(STARPU_HAVE_SYNC_SYNCHRONIZE, 1,
+	      [Define to 1 if the target supports __sync_synchronize])
+  fi])

+ 9 - 2
configure.ac

@@ -61,6 +61,7 @@ AC_COMPILE_IFELSE(
   ]], [[ pthread_t t; pthread_create(&t, NULL, NULL, NULL); ]]),,
   AC_MSG_ERROR([pthread_create unavailable]))
 AC_SEARCH_LIBS([sqrt],[m],,AC_MSG_ERROR([math library unavailable]))
+AC_HAVE_LIBRARY([wsock32])
 AC_CHECK_FUNCS([sysconf])
 
 AC_CHECK_FUNC([pthread_spin_lock], have_pthread_spin_lock=yes, have_pthread_spin_lock=no)
@@ -84,8 +85,11 @@ AC_CHECK_FUNCS([drand48],
 
 AC_CHECK_HEADERS([malloc.h])
 
-# This defines HAVE_SYNC_BUILTINS
-STARPU_CHECK_SYNC_BUILTINS
+# This defines HAVE_SYNC_VAL_COMPARE_AND_SWAP
+STARPU_CHECK_VAL_COMPARE_AND_SWAP
+
+# This defines HAVE_SYNC_BOOL_COMPARE_AND_SWAP
+STARPU_CHECK_SYNC_BOOL_COMPARE_AND_SWAP
 
 # This defines HAVE_SYNC_FETCH_AND_ADD
 STARPU_CHECK_SYNC_FETCH_AND_ADD
@@ -96,6 +100,9 @@ STARPU_CHECK_SYNC_FETCH_AND_OR
 # This defines HAVE_SYNC_LOCK_TEST_AND_SET
 STARPU_CHECK_SYNC_LOCK_TEST_AND_SET
 
+# This defines HAVE_SYNC_SYNCHRONIZE
+STARPU_CHECK_SYNC_SYNCHRONIZE
+
 CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE "
 
 AC_SEARCH_LIBS([set_mempolicy],[numa],[enable_libnuma=yes],[enable_libnuma=no])

+ 46 - 12
include/pthread-win32/pthread.h

@@ -138,7 +138,6 @@ static inline int pthread_join (pthread_t thread, void **res) {
 #define PTHREAD_MUTEX_INITIALIZER NULL
 #define PTHREAD_RWLOCK_INITIALIZER NULL
 typedef HANDLE pthread_mutex_t;
-typedef HANDLE pthread_rwlock_t;
 #define PTHREAD_MUTEX_RECURSIVE 1
 typedef int pthread_mutexattr_t;
 
@@ -168,19 +167,25 @@ static inline int pthread_mutex_unlock (pthread_mutex_t *mutex) {
   return 0;
 }
 
+static inline int pthread_mutex_lock (pthread_mutex_t *mutex);
+static inline int __pthread_mutex_alloc_concurrently (pthread_mutex_t *mutex) {
+  HANDLE mutex_init_mutex;
+  /* Get access to one global named mutex to serialize mutex initialization */
+  winPthreadAssertWindows((mutex_init_mutex = CreateMutex(NULL, FALSE, "StarPU mutex init")));
+  winPthreadAssert(!pthread_mutex_lock(&mutex_init_mutex));
+  /* Now we are the one that can initialize it */
+  if (!*mutex)
+    winPthreadAssert(!pthread_mutex_init((pthread_mutex_t *) mutex,NULL));
+  winPthreadAssert(!pthread_mutex_unlock(&mutex_init_mutex));
+  winPthreadAssertWindows(CloseHandle(mutex_init_mutex));
+  return 0;
+}
+
 static inline int pthread_mutex_lock (pthread_mutex_t *mutex) {
-  volatile pthread_mutex_t *vmutex = mutex;
-  if (!*vmutex) {
-    HANDLE mutex_init_mutex;
-    winPthreadAssertWindows((mutex_init_mutex = CreateMutex(NULL, FALSE, "BRLTTY mutex init")));
-    winPthreadAssert(!pthread_mutex_lock(&mutex_init_mutex));
-    if (!*vmutex)
-      winPthreadAssert(!pthread_mutex_init((pthread_mutex_t *) vmutex,NULL));
-    winPthreadAssert(!pthread_mutex_unlock(&mutex_init_mutex));
-    winPthreadAssertWindows(CloseHandle(mutex_init_mutex));
-  }
+  if (!*mutex)
+    __pthread_mutex_alloc_concurrently (mutex);
 again:
-  switch (WaitForSingleObject(*vmutex, INFINITE)) {
+  switch (WaitForSingleObject(*mutex, INFINITE)) {
     default:
     case WAIT_FAILED:
       setSystemErrno();
@@ -193,11 +198,40 @@ again:
   }
 }
 
+static inline int pthread_mutex_trylock (pthread_mutex_t *mutex) {
+  if (!*mutex)
+    __pthread_mutex_alloc_concurrently (mutex);
+  switch (WaitForSingleObject(*mutex, 0)) {
+    default:
+    case WAIT_FAILED:
+      setSystemErrno();
+      return errno;
+    case WAIT_ABANDONED:
+    case WAIT_OBJECT_0:
+      return 0;
+    case WAIT_TIMEOUT:
+      return EBUSY;
+  }
+}
+
 static inline int pthread_mutex_destroy (pthread_mutex_t *mutex) {
   winPthreadAssertWindows(CloseHandle(*mutex));
   return 0;
 }
 
+/********************************************
+ * rwlock                                   *
+ * VERY LAZY, don't even look at it please! *
+ * Should be fine unoptimized for now.      *
+ * TODO: FIXME, using conds for instance?   *
+ ********************************************/
+
+typedef pthread_mutex_t pthread_rwlock_t;
+#define pthread_rwlock_init(lock, attr) pthread_mutex_init(lock, NULL)
+#define pthread_rwlock_wrlock(lock) pthread_mutex_lock(lock)
+#define pthread_rwlock_rdlock(lock) pthread_mutex_lock(lock)
+#define pthread_rwlock_unlock(lock) pthread_mutex_unlock(lock)
+
 /**************
  * conditions *
  **************/

+ 21 - 1
include/starpu-util.h

@@ -73,7 +73,7 @@ static inline unsigned starpu_atomic_##name(unsigned *ptr, unsigned value) { \
 		if (starpu_cmpxchg(ptr, next) == old) \
 			break; \
 	}; \
-	return old + value; \
+	return expr; \
 }
 
 #ifdef STARPU_HAVE_SYNC_FETCH_AND_ADD
@@ -94,6 +94,14 @@ STARPU_ATOMIC_SOMETHING(or, old | value)
 #error __sync_fetch_and_or is not available
 #endif
 
+#ifdef STARPU_HAVE_SYNC_BOOL_COMPARE_AND_SWAP
+#define STARPU_BOOL_COMPARE_AND_SWAP(ptr, old, value)  (__sync_bool_compare_and_swap ((ptr), (old), (value)))
+#elif defined(STARPU_HAVE_XCHG)
+#define STARPU_BOOL_COMPARE_AND_SWAP(ptr, old, value) (starpu_cmpxchg((ptr), (value)) == (old))
+#else
+#error __sync_bool_compare_and_swap is not available
+#endif
+
 #ifdef STARPU_HAVE_SYNC_LOCK_TEST_AND_SET
 #define STARPU_TEST_AND_SET(ptr, value) (__sync_lock_test_and_set ((ptr), (value)))
 #define STARPU_RELEASE(ptr) (__sync_lock_release ((ptr)))
@@ -104,6 +112,18 @@ STARPU_ATOMIC_SOMETHING(or, old | value)
 #error __sync_lock_test_and_set is not available
 #endif
 
+#ifdef STARPU_HAVE_SYNC_SYNCHRONIZE
+#define STARPU_SYNCHRONIZE() __sync_synchronize()
+#elif defined(__i386__)
+#define STARPU_SYNCHRONIZE() __asm__ __volatile__("lock; addl $0,0(%%esp)" ::: "memory")
+#elif defined(__x86_64__)
+#define STARPU_SYNCHRONIZE() __asm__ __volatile__("mfence" ::: "memory")
+#elif defined(__ppc__) || defined(__ppc64__)
+#define STARPU_SYNCHRONIZE() __asm__ __volatile__("sync" ::: "memory")
+#else
+#error __sync_synchronize is not available
+#endif
+
 #ifdef USE_CUDA
 
 #define CUBLAS_REPORT_ERROR(status) 					\

+ 5 - 0
src/common/utils.c

@@ -19,6 +19,11 @@
 #include <common/utils.h>
 #include <libgen.h>
 
+#ifdef __MINGW32__
+#include <io.h>
+#define mkdir(path, mode) mkdir(path)
+#endif
+
 /* Function with behaviour like `mkdir -p'. This function was adapted from
  * http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/ */
 

+ 2 - 2
src/core/perfmodel/perfmodel_history.c

@@ -302,7 +302,7 @@ static void load_history_based_model(struct starpu_perfmodel_t *model, unsigned
 	STARPU_ASSERT(model->symbol);
 
 	unsigned have_to_load;
-	have_to_load = __sync_bool_compare_and_swap (&model->is_loaded, 
+	have_to_load = STARPU_BOOL_COMPARE_AND_SWAP (&model->is_loaded, 
 				STARPU_PERFMODEL_NOT_LOADED,
 				STARPU_PERFMODEL_LOADING);
 	if (!have_to_load)
@@ -310,7 +310,7 @@ static void load_history_based_model(struct starpu_perfmodel_t *model, unsigned
 		/* someone is already loading the model, we wait until it's finished */
 		while (model->is_loaded != STARPU_PERFMODEL_LOADED)
 		{
-			__sync_synchronize();
+			STARPU_SYNCHRONIZE();
 		}
 		return;
 	}