|
@@ -19,7 +19,6 @@
|
|
|
#include <datawizard/memory_nodes.h>
|
|
|
#include <datawizard/memalloc.h>
|
|
|
#include <datawizard/footprint.h>
|
|
|
-#include <core/dependencies/data_concurrency.h>
|
|
|
#include <core/disk.h>
|
|
|
#include <starpu.h>
|
|
|
#include <common/uthash.h>
|
|
@@ -175,7 +174,6 @@ static void unlock_all_subtree(starpu_data_handle_t handle)
|
|
|
_starpu_spin_unlock(&handle->header_lock);
|
|
|
}
|
|
|
|
|
|
-/* This locks header_lock for all the subdatas */
|
|
|
static int lock_all_subtree(starpu_data_handle_t handle)
|
|
|
{
|
|
|
int child;
|
|
@@ -201,68 +199,30 @@ static int lock_all_subtree(starpu_data_handle_t handle)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static unsigned release_all_subtree(starpu_data_handle_t handle);
|
|
|
-/* This checks that all subdatas are available, and acquire the rw lock */
|
|
|
-static int may_free_subtree(starpu_data_handle_t handle, unsigned node)
|
|
|
+static unsigned may_free_subtree(starpu_data_handle_t handle, unsigned node)
|
|
|
{
|
|
|
/* we only free if no one refers to the leaf */
|
|
|
uint32_t refcnt = _starpu_get_data_refcnt(handle, node);
|
|
|
if (refcnt)
|
|
|
return 0;
|
|
|
|
|
|
- if (!_starpu_attempt_to_acquire_data(handle, STARPU_R))
|
|
|
- return 0;
|
|
|
+ if (!handle->nchildren)
|
|
|
+ return 1;
|
|
|
|
|
|
/* look into all sub-subtrees children */
|
|
|
- int child;
|
|
|
- for (child = 0; child < (int) handle->nchildren; child++)
|
|
|
+ unsigned child;
|
|
|
+ for (child = 0; child < handle->nchildren; child++)
|
|
|
{
|
|
|
- int res;
|
|
|
+ unsigned res;
|
|
|
starpu_data_handle_t child_handle = starpu_data_get_child(handle, child);
|
|
|
res = may_free_subtree(child_handle, node);
|
|
|
- /* The children can't have disappeared since we still hold the
|
|
|
- * parent header_lock */
|
|
|
- STARPU_ASSERT(res >= 0);
|
|
|
- if (!res)
|
|
|
- {
|
|
|
- /* Oops, can't free a child, undo what we did */
|
|
|
- for (child-- ; child >= 0; child--)
|
|
|
- {
|
|
|
- child_handle = starpu_data_get_child(handle, child);
|
|
|
- res = release_all_subtree(child_handle);
|
|
|
- /* The children can't have disappeared since we still hold the
|
|
|
- * parent header_lock */
|
|
|
- STARPU_ASSERT(!res);
|
|
|
- }
|
|
|
- res = _starpu_notify_data_dependencies(handle);
|
|
|
- if (res)
|
|
|
- /* Urgl, it even disappeared, tell caller that it shouldn't even unlock it */
|
|
|
- return -1;
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ if (!res) return 0;
|
|
|
}
|
|
|
|
|
|
/* no problem was found */
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-/* This releases the rw lock of all subdatas */
|
|
|
-static unsigned release_all_subtree(starpu_data_handle_t handle)
|
|
|
-{
|
|
|
- unsigned child;
|
|
|
-
|
|
|
- for (child = 0; child < handle->nchildren; child++)
|
|
|
- {
|
|
|
- unsigned res;
|
|
|
- starpu_data_handle_t child_handle = starpu_data_get_child(handle, child);
|
|
|
- res = release_all_subtree(child_handle);
|
|
|
- /* The children can't have disappeared since we still hold the
|
|
|
- * parent header_lock */
|
|
|
- STARPU_ASSERT(!res);
|
|
|
- }
|
|
|
- return _starpu_notify_data_dependencies(handle);
|
|
|
-}
|
|
|
-
|
|
|
/* Warn: this releases the header lock of the handle during the transfer
|
|
|
* The handle may thus unexpectedly disappear. This returns 1 in that case.
|
|
|
*/
|
|
@@ -290,9 +250,12 @@ static int transfer_subtree_to_node(starpu_data_handle_t handle, unsigned src_no
|
|
|
/* There is no way we don't need a request, since
|
|
|
* source is OWNER, destination can't be having it */
|
|
|
STARPU_ASSERT(r);
|
|
|
+ /* Keep the handle alive while we are working on it */
|
|
|
+ handle->busy_count++;
|
|
|
_starpu_spin_unlock(&handle->header_lock);
|
|
|
_starpu_wait_data_request_completion(r, 1);
|
|
|
_starpu_spin_lock(&handle->header_lock);
|
|
|
+ handle->busy_count--;
|
|
|
if (_starpu_data_check_not_busy(handle))
|
|
|
return 1;
|
|
|
}
|
|
@@ -492,9 +455,7 @@ static size_t try_to_free_mem_chunk(struct _starpu_mem_chunk *mc, unsigned node)
|
|
|
else if (lock_all_subtree(handle))
|
|
|
{
|
|
|
/* check if they are all "free" */
|
|
|
- int res = may_free_subtree(handle, node);
|
|
|
-
|
|
|
- if (res == 1)
|
|
|
+ if (may_free_subtree(handle, node))
|
|
|
{
|
|
|
int target = -1;
|
|
|
|
|
@@ -510,6 +471,7 @@ static size_t try_to_free_mem_chunk(struct _starpu_mem_chunk *mc, unsigned node)
|
|
|
|
|
|
if (target != -1)
|
|
|
{
|
|
|
+ int res;
|
|
|
/* Should have been avoided in our caller */
|
|
|
STARPU_ASSERT(!mc->remove_notify);
|
|
|
mc->remove_notify = &mc;
|
|
@@ -546,22 +508,10 @@ static size_t try_to_free_mem_chunk(struct _starpu_mem_chunk *mc, unsigned node)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /* release the tree */
|
|
|
- if (!release_all_subtree(handle))
|
|
|
- /* unlock the tree */
|
|
|
- unlock_all_subtree(handle);
|
|
|
- }
|
|
|
- else if (res == 0)
|
|
|
- {
|
|
|
- /* busy, unlock the tree */
|
|
|
- unlock_all_subtree(handle);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- STARPU_ASSERT(res == -1);
|
|
|
- /* busy and disappeared, don't even unlock */
|
|
|
}
|
|
|
+
|
|
|
+ /* unlock the tree */
|
|
|
+ unlock_all_subtree(handle);
|
|
|
}
|
|
|
return freed;
|
|
|
}
|
|
@@ -628,9 +578,9 @@ static unsigned try_to_reuse_mem_chunk(struct _starpu_mem_chunk *mc, unsigned no
|
|
|
/* and check if they are all "free" */
|
|
|
if (lock_all_subtree(old_data))
|
|
|
{
|
|
|
- int res = may_free_subtree(old_data, node);
|
|
|
- if (res == 1)
|
|
|
+ if (may_free_subtree(old_data, node))
|
|
|
{
|
|
|
+ int res;
|
|
|
/* Should have been avoided in our caller */
|
|
|
STARPU_ASSERT(!mc->remove_notify);
|
|
|
mc->remove_notify = &mc;
|
|
@@ -655,22 +605,10 @@ static unsigned try_to_reuse_mem_chunk(struct _starpu_mem_chunk *mc, unsigned no
|
|
|
success = 1;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /* release the tree */
|
|
|
- if (!release_all_subtree(old_data))
|
|
|
- /* unlock the tree */
|
|
|
- unlock_all_subtree(old_data);
|
|
|
- }
|
|
|
- else if (res == 0)
|
|
|
- {
|
|
|
- /* busy, unlock the tree */
|
|
|
- unlock_all_subtree(old_data);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- STARPU_ASSERT(res == -1);
|
|
|
- /* busy and disappeared, don't even unlock */
|
|
|
}
|
|
|
+
|
|
|
+ /* unlock the tree */
|
|
|
+ unlock_all_subtree(old_data);
|
|
|
}
|
|
|
|
|
|
return success;
|