Sfoglia il codice sorgente

src/common/starpu_spinlock: revert #12042, code was broken when simgrid and spinlock_check were both enabled

Nathalie Furmento 11 anni fa
parent
commit
ab68ef8ca7
2 ha cambiato i file con 94 aggiunte e 22 eliminazioni
  1. 82 18
      src/common/starpu_spinlock.c
  2. 12 4
      src/common/starpu_spinlock.h

+ 82 - 18
src/common/starpu_spinlock.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010, 2012-2013  Université de Bordeaux 1
- * Copyright (C) 2010, 2011, 2013  Centre National de la Recherche Scientifique
+ * Copyright (C) 2010, 2011, 2013, 2014  Centre National de la Recherche Scientifique
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -19,11 +19,18 @@
 #include <common/config.h>
 #include <common/utils.h>
 #include <common/fxt.h>
-#include <common/thread.h>
+#include <starpu.h>
+
+#ifdef STARPU_SIMGRID
+#include <msg/msg.h>
+#endif
 
 int _starpu_spin_init(struct _starpu_spinlock *lock)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	lock->taken = 0;
+	return 0;
+#elif defined(STARPU_SPINLOCK_CHECK)
 //	memcpy(&lock->errcheck_lock, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, sizeof(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP));
 	int ret;
 	ret = pthread_mutexattr_init(&lock->errcheck_attr);
@@ -34,72 +41,129 @@ int _starpu_spin_init(struct _starpu_spinlock *lock)
 
 	ret = pthread_mutex_init(&lock->errcheck_lock, &lock->errcheck_attr);
 	return ret;
-#else
-	int ret = starpu_pthread_spin_init(&lock->lock, 0);
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret = pthread_spin_init(&lock->lock, 0);
 	STARPU_ASSERT(!ret);
 	return ret;
+#else
+	lock->taken = 0;
+	return 0;
 #endif
 }
 
 int _starpu_spin_destroy(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	/* we don't do anything */
+	return 0;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	pthread_mutexattr_destroy(&lock->errcheck_attr);
 	return pthread_mutex_destroy(&lock->errcheck_lock);
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret = pthread_spin_destroy(&lock->lock);
+	STARPU_ASSERT(!ret);
+	return ret;
 #else
-	return starpu_pthread_spin_destroy(&lock->lock);
+	/* we don't do anything */
+	return 0;
 #endif
 }
 
 #undef _starpu_spin_lock
 int _starpu_spin_lock(struct _starpu_spinlock *lock)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	while (1)
+	{
+		if (!lock->taken)
+		{
+			lock->taken = 1;
+			return 0;
+		}
+		/* Give hand to another thread, hopefully the one which has the
+		 * spinlock and probably just has also a short-lived mutex. */
+		MSG_process_sleep(0.000001);
+		STARPU_UYIELD();
+	}
+#elif defined(STARPU_SPINLOCK_CHECK)
 	int ret = pthread_mutex_lock(&lock->errcheck_lock);
 	STARPU_ASSERT(!ret);
 	return ret;
-#else
-	int ret = starpu_pthread_spin_lock(&lock->lock);
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret = pthread_spin_lock(&lock->lock);
 	STARPU_ASSERT(!ret);
 	return ret;
+#else
+	uint32_t prev;
+	do
+	{
+		prev = STARPU_TEST_AND_SET(&lock->taken, 1);
+		if (prev)
+			STARPU_UYIELD();
+	}
+	while (prev);
+	return 0;
 #endif
 }
 
 int _starpu_spin_checklocked(struct _starpu_spinlock *lock)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	STARPU_ASSERT(lock->taken);
+	return !lock->taken;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	int ret = starpu_pthread_mutex_trylock(&lock->errcheck_lock);
 	STARPU_ASSERT(ret != 0);
 	return ret == 0;
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret = pthread_spin_trylock(&lock->lock);
+	STARPU_ASSERT(ret != 0);
+	return ret == 0;
 #else
-	return _starpu_pthread_spin_checklocked(&lock->lock);
+	STARPU_ASSERT(lock->taken);
+	return !lock->taken;
 #endif
 }
 
 #undef _starpu_spin_trylock
 int _starpu_spin_trylock(struct _starpu_spinlock *lock)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	if (lock->taken)
+		return EBUSY;
+	lock->taken = 1;
+	return 0;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	int ret = starpu_pthread_mutex_trylock(&lock->errcheck_lock);
 	STARPU_ASSERT(!ret || (ret == EBUSY));
 	return ret;
-#else
-	int ret = starpu_pthread_spin_trylock(&lock->lock);
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret =  pthread_spin_trylock(&lock->lock);
 	STARPU_ASSERT(!ret || (ret == EBUSY));
 	return ret;
+#else
+	uint32_t prev;
+	prev = STARPU_TEST_AND_SET(&lock->taken, 1);
+	return (prev == 0)?0:EBUSY;
 #endif
 }
 
 #undef _starpu_spin_unlock
 int _starpu_spin_unlock(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	lock->taken = 0;
+	return 0;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	int ret = pthread_mutex_unlock(&lock->errcheck_lock);
 	STARPU_ASSERT(!ret);
 	return ret;
-#else
-	int ret = starpu_pthread_spin_unlock(&lock->lock);
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	int ret = pthread_spin_unlock(&lock->lock);
 	STARPU_ASSERT(!ret);
 	return ret;
+#else
+	STARPU_RELEASE(&lock->taken);
+	return 0;
 #endif
 }

+ 12 - 4
src/common/starpu_spinlock.h

@@ -19,17 +19,25 @@
 
 #include <errno.h>
 #include <stdint.h>
-#include <common/config.h>
 #include <starpu.h>
+#include <common/config.h>
+#include <common/thread.h>
 
 struct _starpu_spinlock
 {
-#if defined(STARPU_SPINLOCK_CHECK)
+#ifdef STARPU_SIMGRID
+	int taken;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	starpu_pthread_mutexattr_t errcheck_attr;
 	starpu_pthread_mutex_t errcheck_lock;
-	const char *last_taker;
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
+	_starpu_pthread_spinlock_t lock;
 #else
-	starpu_pthread_spinlock_t lock;
+	/* we only have a trivial implementation yet ! */
+	uint32_t taken STARPU_ATTRIBUTE_ALIGNED(16);
+#endif
+#ifdef STARPU_SPINLOCK_CHECK
+	const char *last_taker;
 #endif
 };