瀏覽代碼

optimize simgrid spinlocks

Samuel Thibault 12 年之前
父節點
當前提交
1d52ea71e1
共有 2 個文件被更改,包括 45 次插入38 次删除
  1. 40 33
      src/common/starpu_spinlock.c
  2. 5 5
      src/common/starpu_spinlock.h

+ 40 - 33
src/common/starpu_spinlock.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010, 2012  Université de Bordeaux 1
+ * Copyright (C) 2010, 2012-2013  Université de Bordeaux 1
  * Copyright (C) 2010, 2011  Centre National de la Recherche Scientifique
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -26,7 +26,9 @@
 
 int _starpu_spin_init(struct _starpu_spinlock *lock)
 {
-#ifdef STARPU_SPINLOCK_CHECK
+#ifdef STARPU_SIMGRID
+	lock->taken = 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);
@@ -37,8 +39,7 @@ int _starpu_spin_init(struct _starpu_spinlock *lock)
 
 	ret = pthread_mutex_init(&lock->errcheck_lock, &lock->errcheck_attr);
 	return ret;
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret = pthread_spin_init(&lock->lock, 0);
 	STARPU_ASSERT(!ret);
 	return ret;
@@ -46,16 +47,17 @@ int _starpu_spin_init(struct _starpu_spinlock *lock)
 	lock->taken = 0;
 	return 0;
 #endif
-#endif
 }
 
 int _starpu_spin_destroy(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 {
-#ifdef 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);
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret = pthread_spin_destroy(&lock->lock);
 	STARPU_ASSERT(!ret);
 	return ret;
@@ -63,33 +65,35 @@ int _starpu_spin_destroy(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 	/* we don't do anything */
 	return 0;
 #endif
-#endif
 }
 
 int _starpu_spin_lock(struct _starpu_spinlock *lock)
 {
-#ifdef STARPU_SPINLOCK_CHECK
-	int ret = pthread_mutex_lock(&lock->errcheck_lock);
-	STARPU_ASSERT(!ret);
-	return ret;
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
 #ifdef STARPU_SIMGRID
 	while (1) {
-		int ret = pthread_spin_trylock(&lock->lock);
-		if (ret <= 0)
-			return ret;
+		if (!lock->taken) {
+			lock->taken = 1;
+			return 0;
+		}
 #ifdef STARPU_DEVEL
 #warning FIXME: better way to spinlock?
 #endif
 		/* Sleep for 1µs */
+		static int warned;
+		if (!warned) {
+			warned = 1;
+			_STARPU_DISP("Warning: making simgrid spin for spinlock");
+		}
 		MSG_process_sleep(0.000001);
 	}
-#else
+#elif defined(STARPU_SPINLOCK_CHECK)
+	int ret = pthread_mutex_lock(&lock->errcheck_lock);
+	STARPU_ASSERT(!ret);
+	return ret;
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret = pthread_spin_lock(&lock->lock);
 	STARPU_ASSERT(!ret);
 	return ret;
-#endif
 #else
 	uint32_t prev;
 	do
@@ -99,17 +103,18 @@ int _starpu_spin_lock(struct _starpu_spinlock *lock)
 	while (prev);
 	return 0;
 #endif
-#endif
 }
 
 int _starpu_spin_checklocked(struct _starpu_spinlock *lock)
 {
-#ifdef 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;
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret = pthread_spin_trylock(&lock->lock);
 	STARPU_ASSERT(ret != 0);
 	return ret == 0;
@@ -117,17 +122,20 @@ int _starpu_spin_checklocked(struct _starpu_spinlock *lock)
 	STARPU_ASSERT(lock->taken);
 	return !lock->taken;
 #endif
-#endif
 }
 
 int _starpu_spin_trylock(struct _starpu_spinlock *lock)
 {
-#ifdef 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
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret =  pthread_spin_trylock(&lock->lock);
 	STARPU_ASSERT(!ret || (ret == EBUSY));
 	return ret;
@@ -136,17 +144,17 @@ int _starpu_spin_trylock(struct _starpu_spinlock *lock)
 	prev = STARPU_TEST_AND_SET(&lock->taken, 1);
 	return (prev == 0)?0:EBUSY;
 #endif
-#endif
 }
 
 int _starpu_spin_unlock(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 {
-#ifdef STARPU_SPINLOCK_CHECK
+#ifdef STARPU_SIMGRID
+	lock->taken = 0;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	int ret = pthread_mutex_unlock(&lock->errcheck_lock);
 	STARPU_ASSERT(!ret);
 	return ret;
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	int ret = pthread_spin_unlock(&lock->lock);
 	STARPU_ASSERT(!ret);
 	return ret;
@@ -154,5 +162,4 @@ int _starpu_spin_unlock(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
 	STARPU_RELEASE(&lock->taken);
 	return 0;
 #endif
-#endif
 }

+ 5 - 5
src/common/starpu_spinlock.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010-2012  Université de Bordeaux 1
+ * Copyright (C) 2010-2013  Université de Bordeaux 1
  * Copyright (C) 2010, 2011  Centre National de la Recherche Scientifique
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -25,17 +25,17 @@
 
 struct _starpu_spinlock
 {
-#ifdef STARPU_SPINLOCK_CHECK
+#ifdef STARPU_SIMGRID
+	int taken;
+#elif defined(STARPU_SPINLOCK_CHECK)
 	pthread_mutexattr_t errcheck_attr;
 	_starpu_pthread_mutex_t errcheck_lock;
-#else
-#ifdef HAVE_PTHREAD_SPIN_LOCK
+#elif defined(HAVE_PTHREAD_SPIN_LOCK)
 	_starpu_pthread_spinlock_t lock;
 #else
 	/* we only have a trivial implementation yet ! */
 	uint32_t taken __attribute__ ((aligned(16)));
 #endif
-#endif
 };
 
 int _starpu_spin_init(struct _starpu_spinlock *lock);