Sfoglia il codice sorgente

Add starpu_memory_wait_available

Samuel Thibault 10 anni fa
parent
commit
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
 the given node. \p flags can be either STARPU_MEMORY_MANAGER_WAIT or
 STARPU_MEMORY_MANAGER_OVERFLOW to change this.
 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
 \ingroup API_Standard_Memory_Library
 If a memory limit is defined on the given node (see Section \ref
 If a memory limit is defined on the given node (see Section \ref
 HowToLimitMemoryPerNode), free some of it. This does not actually free memory,
 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_allocate() can be followed by several calls to
 starpu_memory_deallocate() to declare the deallocation piece by piece.
 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
 \def STARPU_MEMORY_MANAGER_WAIT
 \ingroup API_Standard_Memory_Library
 \ingroup API_Standard_Memory_Library
 Value passed to starpu_memory_allocate() to specify that the function should
 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_total(unsigned node);
 starpu_ssize_t starpu_memory_get_available(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_WAIT (1)
 #define STARPU_MEMORY_OVERFLOW (2)
 #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];
 		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 _starpu_memory_manager_test_allocate_size(unsigned node, size_t size)
 {
 {
 	int ret;
 	int ret;