Преглед изворни кода

Add starpu_memory_wait_available

Samuel Thibault пре 10 година
родитељ
комит
89e3bade75

+ 10 - 1
doc/doxygen/chapters/api/standard_memory_library.doxy

@@ -98,7 +98,7 @@ By default, the function returns -ENOMEM if there is not enough room on
 the given node. \p flags can be either STARPU_MEMORY_MANAGER_WAIT or
 STARPU_MEMORY_MANAGER_OVERFLOW to change this.
 
-\fn int starpu_memory_deallocate(unsigned node, size_t size)
+\fn void starpu_memory_deallocate(unsigned node, size_t size)
 \ingroup API_Standard_Memory_Library
 If a memory limit is defined on the given node (see Section \ref
 HowToLimitMemoryPerNode), free some of it. This does not actually free memory,
@@ -108,6 +108,15 @@ only the eventual amount needs to be the same, i.e. one call to
 starpu_memory_allocate() can be followed by several calls to
 starpu_memory_deallocate() to declare the deallocation piece by piece.
 
+\fn void starpu_memory_wait_available(unsigned node, size_t size)
+\ingroup API_Standard_Memory_Library If a memory limit is defined on the given
+node (see Section \ref HowToLimitMemoryPerNode), this will wait for \p size
+bytes to become available on \p node. Of course, since another thread may be
+allocating memory concurrently, this does not necessarily mean that this amount
+will be actually available, just that it was reached. To atomically wait for
+some amount of memory and reserve it, starpu_memory_allocate() should be used
+with the STARPU_MEMORY_MANAGER_WAIT flag.
+
 \def STARPU_MEMORY_MANAGER_WAIT
 \ingroup API_Standard_Memory_Library
 Value passed to starpu_memory_allocate() to specify that the function should

+ 1 - 0
include/starpu_stdlib.h

@@ -39,6 +39,7 @@ int starpu_free_flags(void *A, size_t dim, int flags);
 
 starpu_ssize_t starpu_memory_get_total(unsigned node);
 starpu_ssize_t starpu_memory_get_available(unsigned node);
+void starpu_memory_wait_available(unsigned node, size_t size);
 
 #define STARPU_MEMORY_WAIT (1)
 #define STARPU_MEMORY_OVERFLOW (2)

+ 22 - 0
src/datawizard/memory_manager.c

@@ -132,6 +132,28 @@ starpu_ssize_t starpu_memory_get_available(unsigned node)
 		return global_size[node] - used_size[node];
 }
 
+void starpu_memory_wait_available(unsigned node, size_t size)
+{
+	int ret;
+
+	STARPU_PTHREAD_MUTEX_LOCK(&lock_nodes[node]);
+	waiters[node]++;
+
+	/* Tell deallocators we need this amount */
+	if (!min_waiting_size[node] || size < min_waiting_size[node])
+		min_waiting_size[node] = size;
+
+	/* Wait for it */
+	while (used_size[node] + size > global_size[node])
+		STARPU_PTHREAD_COND_WAIT(&cond_nodes[node], &lock_nodes[node]);
+
+	if (!--waiters[node])
+		/* Nobody is waiting any more, we can reset the minimum
+		 */
+		min_waiting_size[node] = 0;
+	STARPU_PTHREAD_MUTEX_UNLOCK(&lock_nodes[node]);
+}
+
 int _starpu_memory_manager_test_allocate_size(unsigned node, size_t size)
 {
 	int ret;