ソースを参照

Fix of the livelock discovered by Marc Sergent's internship, by adding a maximum trylock threshold before a blocking lock

Marc Sergent 12 年 前
コミット
9783f21238
共有5 個のファイルを変更した38 個の追加6 個の削除を含む
  1. 2 0
      src/common/starpu_spinlock.h
  2. 7 1
      src/core/dependencies/data_concurrency.c
  3. 14 2
      src/datawizard/coherency.c
  4. 8 2
      src/datawizard/memalloc.c
  5. 7 1
      src/datawizard/write_back.c

+ 2 - 0
src/common/starpu_spinlock.h

@@ -107,4 +107,6 @@ int _starpu_spin_unlock(struct _starpu_spinlock *lock);
 }) 
 
 
+#define STARPU_SPIN_MAXTRY 10 
+
 #endif // __STARPU_SPINLOCK_H__

+ 7 - 1
src/core/dependencies/data_concurrency.c

@@ -92,8 +92,14 @@ static unsigned _starpu_attempt_to_submit_data_request(unsigned request_from_cod
 	 * lock to be available. */
 	if (request_from_codelet)
 	{
-		while (_starpu_spin_trylock(&handle->header_lock))
+		int cpt = 0;
+		while (cpt < STARPU_SPIN_MAXTRY && _starpu_spin_trylock(&handle->header_lock))
+		{
+			cpt++;
 			_starpu_datawizard_progress(_starpu_memory_node_get_local_key(), 0);
+		}
+		if (cpt == STARPU_SPIN_MAXTRY)
+			_starpu_spin_lock(&handle->header_lock);
 	}
 	else
 	{

+ 14 - 2
src/datawizard/coherency.c

@@ -494,8 +494,14 @@ int _starpu_fetch_data_on_node(starpu_data_handle_t handle, struct _starpu_data_
 	unsigned local_node = _starpu_memory_node_get_local_key();
         _STARPU_LOG_IN();
 
-	while (_starpu_spin_trylock(&handle->header_lock))
+	int cpt = 0;
+	while (cpt < STARPU_SPIN_MAXTRY && _starpu_spin_trylock(&handle->header_lock))
+	{
+		cpt++;
 		_starpu_datawizard_progress(local_node, 1);
+	}
+	if (cpt == STARPU_SPIN_MAXTRY)
+		_starpu_spin_lock(&handle->header_lock);
 
 	if (!detached)
 	{
@@ -565,8 +571,14 @@ void _starpu_release_data_on_node(starpu_data_handle_t handle, uint32_t default_
 		_starpu_write_through_data(handle, memory_node, wt_mask);
 
 	unsigned local_node = _starpu_memory_node_get_local_key();
-	while (_starpu_spin_trylock(&handle->header_lock))
+	int cpt = 0;
+	while (cpt < STARPU_SPIN_MAXTRY && _starpu_spin_trylock(&handle->header_lock))
+	{
+		cpt++;
 		_starpu_datawizard_progress(local_node, 1);
+	}
+	if (cpt == STARPU_SPIN_MAXTRY)
+		_starpu_spin_lock(&handle->header_lock);
 
 	/* Release refcnt taken by fetch_data_on_node */
 	replicate->refcnt--;

+ 8 - 2
src/datawizard/memalloc.c

@@ -862,8 +862,14 @@ static starpu_ssize_t _starpu_allocate_interface(starpu_data_handle_t handle, st
 				_starpu_memory_reclaim_generic(dst_node, 0, reclaim);
 			_STARPU_TRACE_END_MEMRECLAIM(dst_node,is_prefetch);
 
-		        while (_starpu_spin_trylock(&handle->header_lock))
-		                _starpu_datawizard_progress(_starpu_memory_node_get_local_key(), 0);
+			int cpt = 0;
+			while (cpt < STARPU_SPIN_MAXTRY && _starpu_spin_trylock(&handle->header_lock))
+			{
+				cpt++;
+				_starpu_datawizard_progress(_starpu_memory_node_get_local_key(), 0);
+			}
+			if (cpt == STARPU_SPIN_MAXTRY)
+				_starpu_spin_lock(&handle->header_lock);
 
 			replicate->refcnt--;
 			STARPU_ASSERT(replicate->refcnt >= 0);

+ 7 - 1
src/datawizard/write_back.c

@@ -46,8 +46,14 @@ void _starpu_write_through_data(starpu_data_handle_t handle, unsigned requesting
 			/* we need to commit the buffer on that node */
 			if (node != requesting_node)
 			{
-				while (_starpu_spin_trylock(&handle->header_lock))
+				int cpt = 0;
+				while (cpt < STARPU_SPIN_MAXTRY && _starpu_spin_trylock(&handle->header_lock))
+				{
+					cpt++;
 					_starpu_datawizard_progress(requesting_node, 1);
+				}
+				if (cpt == STARPU_SPIN_MAXTRY)
+					_starpu_spin_lock(&handle->header_lock);
 
 				/* We need to keep a Read lock to avoid letting writers corrupt our copy.  */
 				STARPU_ASSERT(handle->current_mode != STARPU_REDUX);