Sfoglia il codice sorgente

Adding the handling of multiple fathers in hierarchical schedulers,
and correcting some issues concerning the awakening of asleeped workers.
However, those fixes ended to broke the tree-ws hierarchical scheduler,
which had been deactivated for now, and will be fixed soon.
/tests/main/driver_api/init_run_deinit.c : Fix the number of calls to
driver_run_once() in run() function, as hierarchical schedulers
need more calls to driver_run_once() than classical schedulers to
correctly finish this test.

Marc Sergent 12 anni fa
parent
commit
0026768555

+ 1 - 12
include/starpu_sched_node.h

@@ -115,7 +115,7 @@ struct starpu_sched_node
 	 * The basic implementation of this function is a recursive call to
 	 * its childs, until at least one worker have been woken up.
 	 */
-	int (*avail)(struct starpu_sched_node * node);
+	void (*avail)(struct starpu_sched_node * node);
 
 #ifdef STARPU_HAVE_HWLOC
 	/* in case of a hierarchical scheduler, this is set to the part of
@@ -149,11 +149,6 @@ struct starpu_sched_tree
 struct starpu_sched_node * starpu_sched_node_create(void);
 
 void starpu_sched_node_destroy(struct starpu_sched_node * node);
-void starpu_sched_node_add_father(struct starpu_sched_node *node, struct starpu_sched_node *father_node);
-void starpu_sched_node_remove_father(struct starpu_sched_node *node, struct starpu_sched_node *father_node);
-void starpu_sched_node_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child);
-void starpu_sched_node_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child);
-
 
 int starpu_sched_node_can_execute_task(struct starpu_sched_node * node, struct starpu_task * task);
 int STARPU_WARN_UNUSED_RESULT starpu_sched_node_execute_preds(struct starpu_sched_node * node, struct starpu_task * task, double * length);
@@ -256,12 +251,6 @@ void starpu_sched_tree_update_workers(struct starpu_sched_tree * t);
 /* idem for workers_in_ctx 
  */
 void starpu_sched_tree_update_workers_in_ctx(struct starpu_sched_tree * t);
-/* wake up one underlaying workers of node which can execute the task
- */
-void starpu_sched_node_wake_available_worker(struct starpu_sched_node * node, struct starpu_task * task );
-/* wake up underlaying workers of node
- */
-void starpu_sched_node_available(struct starpu_sched_node * node);
 
 int starpu_sched_tree_push_task(struct starpu_task * task);
 struct starpu_task * starpu_sched_tree_pop_task();

+ 0 - 2
src/Makefile.am

@@ -246,7 +246,6 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	sched_policies/node_worker.c				\
 	sched_policies/node_sched.c				\
 	sched_policies/node_fifo.c 				\
-	sched_policies/node_work_stealing.c			\
 	sched_policies/prio_deque.c				\
 	sched_policies/helper_mct.c				\
 	sched_policies/node_prio.c 				\
@@ -264,7 +263,6 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	sched_policies/tree_prio_prefetching.c				\
 	sched_policies/tree_random.c				\
 	sched_policies/tree_random_prefetching.c			\
-	sched_policies/tree_ws.c				\
 	sched_policies/tree_heft.c				\
 	sched_policies/tree_heft2.c
 

+ 1 - 1
src/core/sched_policy.c

@@ -41,7 +41,7 @@ static struct starpu_sched_policy *predefined_policies[] =
 	&_starpu_sched_tree_random_prio_policy,
 	&_starpu_sched_tree_random_prefetching_policy,
 	&_starpu_sched_tree_random_prio_prefetching_policy,
-	&_starpu_sched_tree_ws_policy,
+	//&_starpu_sched_tree_ws_policy,
 	&_starpu_sched_tree_heft_policy,
 	&_starpu_sched_tree_heft2_policy,
 	&_starpu_sched_eager_policy,

+ 1 - 1
src/core/sched_policy.h

@@ -75,7 +75,7 @@ extern struct starpu_sched_policy _starpu_sched_tree_random_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_random_prio_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_random_prefetching_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_random_prio_prefetching_policy;
-extern struct starpu_sched_policy _starpu_sched_tree_ws_policy;
+//extern struct starpu_sched_policy _starpu_sched_tree_ws_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_heft_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_heft2_policy;
 #endif // __SCHED_POLICY_H__

+ 0 - 1
src/sched_policies/fifo_queues.c

@@ -160,7 +160,6 @@ int _starpu_fifo_push_back_task(struct _starpu_fifo_taskq *fifo_queue, struct st
 		starpu_task_list_push_front(&fifo_queue->taskq, task);
 
 		fifo_queue->ntasks++;
-		fifo_queue->nprocessed++;
 	}
 
 	return 0;

+ 4 - 4
src/sched_policies/node_composed.c

@@ -103,14 +103,14 @@ struct composed_node create_composed_node(struct starpu_sched_node_composed_reci
 #ifdef STARPU_HAVE_HWLOC
 		node->obj = obj;
 #endif
-		starpu_sched_node_add_child(c.bottom, node);
+		c.bottom->add_child(c.bottom, node);
 
 		/* we want to be able to traverse scheduler bottom up for all sched ctxs
 		 * when a worker call pop()
 		 */
 		unsigned j;
 		for(j = 0; j < STARPU_NMAX_SCHED_CTXS; j++)
-			starpu_sched_node_add_father(node, c.bottom);
+			node->add_father(node, c.bottom);
 		c.bottom = node;
 	}
 	STARPU_ASSERT(!starpu_sched_node_is_worker(c.bottom));
@@ -156,13 +156,13 @@ double composed_node_estimated_load(struct starpu_sched_node * node)
 static void composed_node_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
 {
 	struct composed_node * c = node->data;
-	starpu_sched_node_add_child(node, child);
+	node->add_child(node, child);
 	c->bottom->add_child(c->bottom, child);
 }
 static void composed_node_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
 {
 	struct composed_node * c = node->data;
-	starpu_sched_node_remove_child(node, child);
+	node->remove_child(node, child);
 	c->bottom->remove_child(c->bottom, child);
 }
 

+ 5 - 2
src/sched_policies/node_eager.c

@@ -36,7 +36,7 @@ static int eager_push_task(struct starpu_sched_node * node, struct starpu_task *
 				int i;
 				for (i = 0; i < node->nchilds; i++)
 				{
-					int idworker;
+					int idworker,ret;
 					for(idworker = starpu_bitmap_first(node->childs[i]->workers);
 						idworker != -1;
 						idworker = starpu_bitmap_next(node->childs[i]->workers, idworker))
@@ -50,9 +50,12 @@ static int eager_push_task(struct starpu_sched_node * node, struct starpu_task *
 							}
 							else
 							{
-								int ret = node->childs[i]->push_task(node->childs[i],task);
+								ret = node->childs[i]->push_task(node->childs[i],task);
 								if(!ret)
+								{
+									node->childs[i]->avail(node->childs[i]);
 									return ret;
+								}
 							}
 						}
 					}

+ 9 - 2
src/sched_policies/node_eager_calibration.c

@@ -48,7 +48,7 @@ static int eager_calibration_push_task(struct starpu_sched_node * node, struct s
 					int i;
 					for (i = 0; i < node->nchilds; i++)
 					{
-						int idworker;
+						int idworker,ret;
 						for(idworker = starpu_bitmap_first(node->childs[i]->workers);
 							idworker != -1;
 							idworker = starpu_bitmap_next(node->childs[i]->workers, idworker))
@@ -61,7 +61,14 @@ static int eager_calibration_push_task(struct starpu_sched_node * node, struct s
 									return 1;
 								}
 								else
-									return node->childs[i]->push_task(node->childs[i],task);
+								{
+									ret = node->childs[i]->push_task(node->childs[i],task);
+									if(!ret)
+									{
+										node->childs[i]->avail(node->childs[i]);
+										return ret;
+									}
+								}
 							}
 						}
 					}

+ 17 - 11
src/sched_policies/node_fifo.c

@@ -19,6 +19,7 @@
 #include <starpu_scheduler.h>
 
 #include "fifo_queues.h"
+#include "sched_node.h"
 
 
 struct _starpu_fifo_data
@@ -101,7 +102,7 @@ static int fifo_push_local_task(struct starpu_sched_node * node, struct starpu_t
 	struct _starpu_fifo_data * data = node->data;
 	struct _starpu_fifo_taskq * fifo = data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
-	int ret;
+	int ret = 0;
 
 	STARPU_PTHREAD_MUTEX_LOCK(mutex);
 	double exp_len;
@@ -141,12 +142,6 @@ static int fifo_push_local_task(struct starpu_sched_node * node, struct starpu_t
 		STARPU_ASSERT(!isnan(fifo->exp_len));
 		STARPU_ASSERT(!isnan(fifo->exp_start));
 		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
-
-		// When a task is pushed onto the local queue, we signify to our children
-		// that a task has been pushed, and that if everyone is sleeping, someone
-		// needs to wake up to come and take it.
-		if(!is_pushback)
-			node->avail(node);
 	}
 	
 	return ret;
@@ -154,7 +149,8 @@ static int fifo_push_local_task(struct starpu_sched_node * node, struct starpu_t
 
 static int fifo_push_task(struct starpu_sched_node * node, struct starpu_task * task)
 {
-	return fifo_push_local_task(node, task, 0);
+	int ret = fifo_push_local_task(node, task, 0);
+	return ret;
 }
 
 int starpu_sched_node_is_fifo(struct starpu_sched_node * node)
@@ -188,13 +184,17 @@ static struct starpu_task * fifo_pop_task(struct starpu_sched_node * node)
 
 	// When a pop is called, a room is called for pushing tasks onto
 	// the empty place of the queue left by the popped task.
-	int i;
+	int i,ret;
 	for(i=0; i < node->nfathers; i++)
 	{
 		if(node->fathers[i] == NULL)
 			continue;
 		else
-			node->fathers[i]->room(node->fathers[i]);
+		{
+			ret = node->fathers[i]->room(node->fathers[i]);
+			if(ret)
+				break;
+		}
 	}
 	
 	if(task)
@@ -212,23 +212,29 @@ static int fifo_room(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node && starpu_sched_node_is_fifo(node));
 	int ret = 0;
+	int res = 0;
 
 	STARPU_ASSERT(node->nchilds == 1);
 	struct starpu_sched_node * child = node->childs[0];
 
+	_starpu_sched_node_unlock_scheduling();
 	struct starpu_task * task = node->pop_task(node);
 	if(task)
 		ret = child->push_task(child,task);	
 	while(task && !ret) 
 	{
+		if(!res)
+			res = 1;
+
 		task = node->pop_task(node);
 		if(task)
 			ret = child->push_task(child,task);	
 	} 
+	_starpu_sched_node_lock_scheduling();
 	if(task && ret)
 		fifo_push_local_task(node,task,1); 
 
-	return 1;
+	return res;
 }
 
 struct starpu_sched_node * starpu_sched_node_fifo_create(struct starpu_fifo_data * params)

+ 9 - 0
src/sched_policies/node_heft.c

@@ -164,6 +164,12 @@ static int heft_progress_one(struct starpu_sched_node *node)
 		STARPU_ASSERT(best_task >= 0);
 		best_node = node->childs[best_inode];
 
+		if(starpu_sched_node_is_worker(best_node))
+		{
+			best_node->avail(best_node);
+			return 1;
+		}
+
 		int ret = best_node->push_task(best_node, tasks[best_task]);
 
 		if (ret)
@@ -176,6 +182,7 @@ static int heft_progress_one(struct starpu_sched_node *node)
 		}
 		else
 		{
+			best_node->avail(best_node);
 			return 0;
 		}
 	}
@@ -191,7 +198,9 @@ static void heft_progress(struct starpu_sched_node *node)
 
 static int heft_room(struct starpu_sched_node *node)
 {
+	_starpu_sched_node_unlock_scheduling();
 	heft_progress(node);
+	_starpu_sched_node_lock_scheduling();
 	int ret, j;
 	for(j=0; j < node->nfathers; j++)
 	{

+ 20 - 2
src/sched_policies/node_mct.c

@@ -55,7 +55,11 @@ static int mct_push_task(struct starpu_sched_node * node, struct starpu_task * t
 			estimated_lengths, estimated_transfer_length, estimated_ends_with_task,
 			&min_exp_end_with_task, &max_exp_end_with_task, suitable_nodes);
 
-	if(!nsuitable_nodes)
+	/* If no suitable nodes were found, it means that the perfmodel of
+	 * the task had been purged since it has been pushed on the mct node.
+	 * We should send a push_fail message to its father so that it will
+	 * be able to reschedule the task properly. */
+	if(nsuitable_nodes == 0)
 		return 1;
 
 	double best_fitness = DBL_MAX;
@@ -80,10 +84,24 @@ static int mct_push_task(struct starpu_sched_node * node, struct starpu_task * t
 		}
 	}
 
-	STARPU_ASSERT(best_inode != -1);
+	/* If no best node is found, it means that the perfmodel of
+	 * the task had been purged since it has been pushed on the mct node.
+	 * We should send a push_fail message to its father so that it will
+	 * be able to reschedule the task properly. */
+	if(best_inode == -1)
+		return 1;
+
 	best_node = node->childs[best_inode];
 
+	if(starpu_sched_node_is_worker(best_node))
+	{
+		best_node->avail(best_node);
+		return 1;
+	}
+
 	int ret = best_node->push_task(best_node, task);
+	if(!ret)
+		best_node->avail(best_node);
 
 	return ret;
 }

+ 16 - 10
src/sched_policies/node_prio.c

@@ -18,6 +18,7 @@
 #include <starpu_scheduler.h>
 
 #include "prio_deque.h"
+#include "sched_node.h"
 
 #define STARPU_TRACE_SCHED_NODE_PUSH_PRIO(node,ntasks,exp_len) do {                                 \
 	int workerid = STARPU_NMAXWORKERS + 1;									\
@@ -155,12 +156,6 @@ static int prio_push_local_task(struct starpu_sched_node * node, struct starpu_t
 		STARPU_ASSERT(!isnan(prio->exp_len));
 		STARPU_ASSERT(!isnan(prio->exp_start));
 		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
-
-		// When a task is pushed onto the local queue, we signify to our children
-		// that a task has been pushed, and that if everyone is sleeping, someone
-		// needs to wake up to come and take it.
-		if(!is_pushback)
-			node->avail(node);
 	}
 
 	return ret;
@@ -168,7 +163,8 @@ static int prio_push_local_task(struct starpu_sched_node * node, struct starpu_t
 
 static int prio_push_task(struct starpu_sched_node * node, struct starpu_task * task)
 {
-	return prio_push_local_task(node, task, 0);
+	int ret = prio_push_local_task(node, task, 0);
+	return ret;
 }
 
 int starpu_sched_node_is_prio(struct starpu_sched_node * node)
@@ -204,13 +200,17 @@ static struct starpu_task * prio_pop_task(struct starpu_sched_node * node)
 
 	// When a pop is called, a room is called for pushing tasks onto
 	// the empty place of the queue left by the popped task.
-	int i;
+	int i,ret;
 	for(i=0; i < node->nfathers; i++)
 	{
 		if(node->fathers[i] == NULL)
 			continue;
 		else
-			node->fathers[i]->room(node->fathers[i]);
+		{
+			ret = node->fathers[i]->room(node->fathers[i]);
+			if(ret)
+				break;
+		}
 	}
 	
 	if(task)
@@ -228,23 +228,29 @@ static int prio_room(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node && starpu_sched_node_is_prio(node));
 	int ret = 0;
+	int res = 0;
 
 	STARPU_ASSERT(node->nchilds == 1);
 	struct starpu_sched_node * child = node->childs[0];
 
+	_starpu_sched_node_unlock_scheduling();
 	struct starpu_task * task = node->pop_task(node);
 	if(task)
 		ret = child->push_task(child,task);	
 	while(task && !ret) 
 	{
+		if(!res)
+			res = 1;
+
 		task = node->pop_task(node);
 		if(task)
 			ret = child->push_task(child,task);	
 	} 
+	_starpu_sched_node_lock_scheduling();
 	if(task && ret)
 		prio_push_local_task(node,task,1); 
 
-	return 1;
+	return res;
 }
 
 struct starpu_sched_node * starpu_sched_node_prio_create(struct starpu_prio_data * params)

+ 8 - 0
src/sched_policies/node_random.c

@@ -85,7 +85,15 @@ static int random_push_task(struct starpu_sched_node * node, struct starpu_task
 		alpha += speedup[i];
 	}
 	STARPU_ASSERT(select != NULL);
+	if(starpu_sched_node_is_worker(select))
+	{
+		select->avail(select);
+		return 1;
+	}
+
 	int ret_val = select->push_task(select,task);
+	if(!ret_val)
+		select->avail(select);
 
 	return ret_val;
 }

+ 58 - 146
src/sched_policies/node_sched.c

@@ -24,100 +24,6 @@
 
 #include "sched_node.h"
 
-
-/* wake up worker workerid
- * if called by a worker it dont try to wake up himself
- */
-static void wake_simple_worker(int workerid)
-{
-	STARPU_ASSERT(0 <= workerid && (unsigned)  workerid < starpu_worker_get_count());
-	starpu_pthread_mutex_t * sched_mutex;
-	starpu_pthread_cond_t * sched_cond;
-	if(workerid == starpu_worker_get_id())
-		return;
-	starpu_worker_get_sched_condition(workerid, &sched_mutex, &sched_cond);
-	starpu_wakeup_worker(workerid, sched_cond, sched_mutex);
-	/*
-	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
-	STARPU_PTHREAD_COND_SIGNAL(sched_cond);
-	STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
-	*/
-}
-
-/* wake up all workers of a combined workers
- * this function must not be called during a pop (however this should not
- * even be possible) or you will have a dead lock
- */
-static void wake_combined_worker(int workerid)
-{
-	STARPU_ASSERT( 0 <= workerid
-		       && starpu_worker_get_count() <= (unsigned) workerid
-		       && (unsigned) workerid < starpu_worker_get_count() + starpu_combined_worker_get_count());
-	struct _starpu_combined_worker * combined_worker = _starpu_get_combined_worker_struct(workerid);
-	int * list = combined_worker->combined_workerid;
-	int size = combined_worker->worker_size;
-	int i;
-	for(i = 0; i < size; i++)
-		wake_simple_worker(list[i]);
-}
-
-
-/* this function must not be called on worker nodes :
- * because this wouldn't have sense
- * and should dead lock
- */
-void starpu_sched_node_wake_available_worker(struct starpu_sched_node * node, struct starpu_task * task)
-{
-	(void)node;
-	STARPU_ASSERT(node);
-	STARPU_ASSERT(!starpu_sched_node_is_worker(node));
-#ifndef STARPU_NON_BLOCKING_DRIVERS
-	int i;
-	unsigned nimpl;
-	for(i = starpu_bitmap_first(node->workers_in_ctx);
-	    i != -1;
-	    i = starpu_bitmap_next(node->workers_in_ctx, i))
-	{
-		for (nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
-		{
-			if (starpu_worker_can_execute_task(i, task, nimpl))
-			{
-				if(i < (int) starpu_worker_get_count())
-					wake_simple_worker(i);
-				else
-					wake_combined_worker(i);
-				goto out;
-			}
-		}
-	}
-out:
-#endif
-}
-
-
-/* this function must not be called on worker nodes :
- * because this wouldn't have sense
- * and should dead lock
- */
-void starpu_sched_node_available(struct starpu_sched_node * node)
-{
-	(void)node;
-	STARPU_ASSERT(node);
-	STARPU_ASSERT(!starpu_sched_node_is_worker(node));
-#ifndef STARPU_NON_BLOCKING_DRIVERS
-	int i;
-	for(i = starpu_bitmap_first(node->workers_in_ctx);
-	    i != -1;
-	    i = starpu_bitmap_next(node->workers_in_ctx, i))
-	{
-		if(i < (int) starpu_worker_get_count())
-			wake_simple_worker(i);
-		else
-			wake_combined_worker(i);
-	}
-#endif
-}
-
 /* default implementation for node->pop_task()
  * just perform a recursive call on father
  */
@@ -140,32 +46,6 @@ static struct starpu_task * pop_task_node(struct starpu_sched_node * node)
 	return task;
 }
 
-void starpu_sched_node_add_father(struct starpu_sched_node* node, struct starpu_sched_node * father)
-{
-	STARPU_ASSERT(node && father);
-	int i;
-	for(i = 0; i < node->nfathers; i++){
-		STARPU_ASSERT(node->fathers[i] != node);
-		STARPU_ASSERT(node->fathers[i] != NULL);
-	}
-
-	node->fathers = realloc(node->fathers, sizeof(struct starpu_sched_node *) * (node->nfathers + 1));
-	node->fathers[node->nfathers] = father;
-	node->nfathers++;
-}
-
-void starpu_sched_node_remove_father(struct starpu_sched_node * node, struct starpu_sched_node * father)
-{
-	STARPU_ASSERT(node && father);
-	int pos;
-	for(pos = 0; pos < node->nfathers; pos++)
-		if(node->fathers[pos] == father)
-			break;
-	STARPU_ASSERT(pos != node->nfathers);
-	node->fathers[pos] = node->fathers[--node->nfathers];
-}
-
-
 /******************************************************************************
  *          functions for struct starpu_sched_policy interface                *
  ******************************************************************************/
@@ -240,9 +120,6 @@ void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, uns
 	STARPU_PTHREAD_MUTEX_UNLOCK(&t->lock);
 }
 
-
-
-
 void starpu_sched_node_destroy_rec(struct starpu_sched_node * node)
 {
 	if(node == NULL)
@@ -279,7 +156,7 @@ void starpu_sched_tree_destroy(struct starpu_sched_tree * tree)
 	free(tree);
 }
 
-void starpu_sched_node_add_child(struct starpu_sched_node* node, struct starpu_sched_node * child)
+static void starpu_sched_node_add_child(struct starpu_sched_node* node, struct starpu_sched_node * child)
 {
 	STARPU_ASSERT(node && child);
 	STARPU_ASSERT(!starpu_sched_node_is_worker(node));
@@ -293,7 +170,8 @@ void starpu_sched_node_add_child(struct starpu_sched_node* node, struct starpu_s
 	node->childs[node->nchilds] = child;
 	node->nchilds++;
 }
-void starpu_sched_node_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
+
+static void starpu_sched_node_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
 {
 	STARPU_ASSERT(node && child);
 	STARPU_ASSERT(!starpu_sched_node_is_worker(node));
@@ -305,6 +183,31 @@ void starpu_sched_node_remove_child(struct starpu_sched_node * node, struct star
 	node->childs[pos] = node->childs[--node->nchilds];
 }
 
+static void starpu_sched_node_add_father(struct starpu_sched_node* node, struct starpu_sched_node * father)
+{
+	STARPU_ASSERT(node && father);
+	int i;
+	for(i = 0; i < node->nfathers; i++){
+		STARPU_ASSERT(node->fathers[i] != node);
+		STARPU_ASSERT(node->fathers[i] != NULL);
+	}
+
+	node->fathers = realloc(node->fathers, sizeof(struct starpu_sched_node *) * (node->nfathers + 1));
+	node->fathers[node->nfathers] = father;
+	node->nfathers++;
+}
+
+static void starpu_sched_node_remove_father(struct starpu_sched_node * node, struct starpu_sched_node * father)
+{
+	STARPU_ASSERT(node && father);
+	int pos;
+	for(pos = 0; pos < node->nfathers; pos++)
+		if(node->fathers[pos] == father)
+			break;
+	STARPU_ASSERT(pos != node->nfathers);
+	node->fathers[pos] = node->fathers[--node->nfathers];
+}
+
 struct starpu_bitmap * _starpu_get_worker_mask(unsigned sched_ctx_id)
 {
 	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
@@ -371,10 +274,6 @@ int starpu_sched_node_execute_preds(struct starpu_sched_node * node, struct star
 					d = starpu_task_expected_length(task, archtype, nimpl);
 				if(isnan(d))
 				{
-					/* TODO: this is not supposed to
-					 * happen, the perfmodel selector
-					 * should have forced it to a proper
-					 * worker already */
 					*length = d;
 					return can_execute;
 						
@@ -395,8 +294,6 @@ int starpu_sched_node_execute_preds(struct starpu_sched_node * node, struct star
 	}
 
 	if(len == DBL_MAX) /* we dont have perf model */
-		/* TODO: this is not supposed to happen, the perfmodel selector
-		 * should have forced it to a proper worker already */
 		len = 0.0; 
 	if(length)
 		*length = len;
@@ -478,7 +375,7 @@ void starpu_sched_node_prefetch_on_node(struct starpu_sched_node * node, struct
  * A personally-made room in a node (like in prio nodes) is necessary to catch
  * this recursive call somewhere, if the user wants to exploit it.
  */
-int starpu_sched_node_room(struct starpu_sched_node * node)
+static int starpu_sched_node_room(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node);
 	int ret = 0;
@@ -501,22 +398,37 @@ int starpu_sched_node_room(struct starpu_sched_node * node)
  * node. It is currenly called by nodes which holds a queue (like fifo and prio
  * nodes) to signify its childs that a task has been pushed on its local queue.
  */
-int starpu_sched_node_avail(struct starpu_sched_node * node)
+static void starpu_sched_node_avail(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node);
-	int ret;
-	if(node->nchilds > 0)
-	{
-		int i;
-		for(i = 0; i < node->nchilds; i++)
-		{
-			struct starpu_sched_node * child = node->childs[i];
-			ret = child->avail(child);
-			if(ret)
-				break;
-		}
-	}
-	return 0;
+	STARPU_ASSERT(!starpu_sched_node_is_worker(node));
+	int i;
+	for(i = 0; i < node->nchilds; i++)
+		node->childs[i]->avail(node->childs[i]);
+}
+
+/* Allows a worker to lock/unlock scheduling mutexes. Currently used in 
+ * self-defined room calls to allow avail calls to take those mutexes while the 
+ * current worker is pushing tasks on other workers (or itself). 
+ */
+void _starpu_sched_node_lock_scheduling(void)
+{
+	int workerid = starpu_worker_get_id();
+	starpu_pthread_mutex_t *sched_mutex;
+	starpu_pthread_cond_t *sched_cond;
+	starpu_worker_get_sched_condition(workerid, &sched_mutex, &sched_cond);
+	_starpu_sched_node_lock_worker(workerid);	
+	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
+}
+
+void _starpu_sched_node_unlock_scheduling(void)
+{
+	int workerid = starpu_worker_get_id();
+	starpu_pthread_mutex_t *sched_mutex;
+	starpu_pthread_cond_t *sched_cond;
+	starpu_worker_get_sched_condition(workerid, &sched_mutex, &sched_cond);
+	STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
+	_starpu_sched_node_unlock_worker(workerid);	
 }
 
 void take_node_and_does_nothing(struct starpu_sched_node * node STARPU_ATTRIBUTE_UNUSED)

+ 3 - 4
src/sched_policies/node_work_stealing.c

@@ -229,8 +229,7 @@ static int push_task(struct starpu_sched_node * node, struct starpu_task * task)
 	STARPU_PTHREAD_MUTEX_UNLOCK(wsd->mutexes[i]);
 
 	wsd->last_push_child = i;
-//	node->available(node);
-	starpu_sched_node_available(node);
+	node->avail(node);
 	return ret;
 }
 
@@ -274,7 +273,7 @@ int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task)
 				node->childs[j]->available(node->childs[j]);
 			}
 */
-			starpu_sched_node_available(node);
+			node->avail(node);
 			return ret;
 		}
 	}
@@ -287,7 +286,7 @@ int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task)
 void _ws_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
 {
 	struct _starpu_work_stealing_data * wsd = node->data;
-	starpu_sched_node_add_child(node, child);
+	node->add_child(node, child);
 	if(wsd->size < node->nchilds)
 	{
 		STARPU_ASSERT(wsd->size == node->nchilds - 1);

+ 115 - 33
src/sched_policies/node_worker.c

@@ -92,6 +92,13 @@ struct _starpu_worker_task_list
 	starpu_pthread_mutex_t mutex;
 };
 
+enum _starpu_worker_node_status
+{
+	NODE_STATUS_SLEEPING,
+	NODE_STATUS_RESET,
+	NODE_STATUS_CHANGED
+};
+
 struct _starpu_worker_node_data
 {
 	union 
@@ -104,6 +111,7 @@ struct _starpu_worker_node_data
 		struct _starpu_combined_worker * combined_worker;
 	};
 	struct _starpu_worker_task_list * list;
+	enum _starpu_worker_node_status status;
 };
 
 /* this array store worker nodes */
@@ -310,26 +318,89 @@ enum starpu_perfmodel_archtype starpu_sched_node_worker_get_perf_arch(struct sta
 }
 */
 
-static int simple_worker_available(struct starpu_sched_node * worker_node)
+static void _starpu_sched_node_worker_set_sleep_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	data->status = NODE_STATUS_SLEEPING;
+}
+
+static void _starpu_sched_node_worker_set_changed_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	data->status = NODE_STATUS_CHANGED;
+}
+
+static void _starpu_sched_node_worker_reset_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	data->status = NODE_STATUS_RESET;
+}
+
+static int _starpu_sched_node_worker_is_reset_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	return (data->status == NODE_STATUS_RESET);
+}
+
+static int _starpu_sched_node_worker_is_changed_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	return (data->status == NODE_STATUS_CHANGED);
+}
+
+static int _starpu_sched_node_worker_is_sleeping_status(struct starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_worker(worker_node));
+	struct _starpu_worker_node_data * data = worker_node->data;
+	return (data->status == NODE_STATUS_SLEEPING);
+}
+
+void _starpu_sched_node_lock_worker(int workerid)
+{
+	STARPU_ASSERT(0 <= workerid && workerid < (int) starpu_worker_get_count());
+	struct _starpu_worker_node_data * data = starpu_sched_node_worker_create(workerid)->data;
+	STARPU_PTHREAD_MUTEX_LOCK(&data->lock);
+}
+void _starpu_sched_node_unlock_worker(int workerid)
+{
+	STARPU_ASSERT(0 <= workerid && workerid < (int)starpu_worker_get_count());
+	struct _starpu_worker_node_data * data = starpu_sched_node_worker_create(workerid)->data;
+	STARPU_PTHREAD_MUTEX_UNLOCK(&data->lock);
+}
+
+static void simple_worker_available(struct starpu_sched_node * worker_node)
 {
 	(void) worker_node;
-#ifndef STARPU_NON_BLOCKING_DRIVERS
 	struct _starpu_worker * w = _starpu_sched_node_worker_get_worker(worker_node);
+	_starpu_sched_node_lock_worker(w->workerid);
+	if(_starpu_sched_node_worker_is_reset_status(worker_node))
+		_starpu_sched_node_worker_set_changed_status(worker_node);
+
 	if(w->workerid == starpu_worker_get_id())
-		return 1;
-	starpu_pthread_mutex_t *sched_mutex = &w->sched_mutex;
-	starpu_pthread_cond_t *sched_cond = &w->sched_cond;
-	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
-	STARPU_PTHREAD_COND_SIGNAL(sched_cond);
-	STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
-#endif
-	return 1;
+	{
+		_starpu_sched_node_unlock_worker(w->workerid);
+		return;
+	}
+	if(_starpu_sched_node_worker_is_sleeping_status(worker_node))
+	{
+		starpu_pthread_mutex_t *sched_mutex;
+		starpu_pthread_cond_t *sched_cond;
+		starpu_worker_get_sched_condition(w->workerid, &sched_mutex, &sched_cond);
+		_starpu_sched_node_unlock_worker(w->workerid);
+		starpu_wakeup_worker(w->workerid, sched_cond, sched_mutex);
+	}
+	else
+		_starpu_sched_node_unlock_worker(w->workerid);
 }
 
-static int combined_worker_available(struct starpu_sched_node * node)
+static void combined_worker_available(struct starpu_sched_node * node)
 {
 	(void) node;
-#ifndef STARPU_NON_BLOCKING_DRIVERS
 	STARPU_ASSERT(starpu_sched_node_is_combined_worker(node));
 	struct _starpu_worker_node_data * data = node->data;
 	int workerid = starpu_worker_get_id();
@@ -339,15 +410,19 @@ static int combined_worker_available(struct starpu_sched_node * node)
 		if(i == workerid)
 			continue;
 		int worker = data->combined_worker->combined_workerid[i];
-		starpu_pthread_mutex_t *sched_mutex;
-		starpu_pthread_cond_t *sched_cond;
-		starpu_worker_get_sched_condition(worker, &sched_mutex, &sched_cond);
-		STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
-		STARPU_PTHREAD_COND_SIGNAL(sched_cond);
-		STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
+		_starpu_sched_node_lock_worker(worker);
+		if(_starpu_sched_node_worker_is_sleeping_status(node))
+		{
+			starpu_pthread_mutex_t *sched_mutex;
+			starpu_pthread_cond_t *sched_cond;
+			starpu_worker_get_sched_condition(worker, &sched_mutex, &sched_cond);
+			starpu_wakeup_worker(worker, sched_cond, sched_mutex);
+		}
+		if(_starpu_sched_node_worker_is_reset_status(node))
+			_starpu_sched_node_worker_set_changed_status(node);
+
+		_starpu_sched_node_unlock_worker(worker);
 	}
-#endif
-	return 1;
 }
 
 static int simple_worker_push_task(struct starpu_sched_node * node, struct starpu_task *task)
@@ -388,6 +463,7 @@ struct starpu_task * simple_worker_pop_task(struct starpu_sched_node *node)
 	}
 	STARPU_PTHREAD_MUTEX_LOCK(&data->lock);
 	int i;
+	_starpu_sched_node_worker_reset_status(node);
 	for(i=0; i < node->nfathers; i++)
 	{
 		if(node->fathers[i] == NULL)
@@ -399,6 +475,22 @@ struct starpu_task * simple_worker_pop_task(struct starpu_sched_node *node)
 				break;
 		}
 	}
+	if((!task) && _starpu_sched_node_worker_is_changed_status(node))
+	{
+		for(i=0; i < node->nfathers; i++)
+		{
+			if(node->fathers[i] == NULL)
+				continue;
+			else
+			{
+				task = node->fathers[i]->pop_task(node->fathers[i]);
+				if(task)
+					break;
+			}
+		}
+		STARPU_ASSERT(task);
+	}
+	_starpu_sched_node_worker_set_sleep_status(node);
 	STARPU_PTHREAD_MUTEX_UNLOCK(&data->lock);
 	if(!task)
 		return NULL;
@@ -433,19 +525,6 @@ void starpu_sched_node_worker_destroy(struct starpu_sched_node *node)
 	_worker_nodes[id] = NULL;
 }
 
-void _starpu_sched_node_lock_worker(int workerid)
-{
-	STARPU_ASSERT(0 <= workerid && workerid < (int) starpu_worker_get_count());
-	struct _starpu_worker_node_data * data = starpu_sched_node_worker_create(workerid)->data;
-	STARPU_PTHREAD_MUTEX_LOCK(&data->lock);
-}
-void _starpu_sched_node_unlock_worker(int workerid)
-{
-	STARPU_ASSERT(0 <= workerid && workerid < (int)starpu_worker_get_count());
-	struct _starpu_worker_node_data * data = starpu_sched_node_worker_create(workerid)->data;
-	STARPU_PTHREAD_MUTEX_UNLOCK(&data->lock);
-}
-
 void _starpu_sched_node_lock_all_workers(void)
 {
 	unsigned i;
@@ -649,11 +728,13 @@ static struct starpu_sched_node * starpu_sched_node_worker_create(int workerid)
 
 	data->worker = worker;
 	STARPU_PTHREAD_MUTEX_INIT(&data->lock,NULL);
+	data->status = NODE_STATUS_SLEEPING;
 	data->list = _starpu_worker_task_list_create();
 	node->data = data;
 
 	node->push_task = simple_worker_push_task;
 	node->pop_task = simple_worker_pop_task;
+	node->avail = simple_worker_available;
 	node->estimated_end = simple_worker_estimated_end;
 	node->estimated_load = simple_worker_estimated_load;
 	node->deinit_data = _worker_node_deinit_data;
@@ -687,6 +768,7 @@ static struct starpu_sched_node  * starpu_sched_node_combined_worker_create(int
 	struct _starpu_worker_node_data * data = malloc(sizeof(*data));
 	memset(data, 0, sizeof(*data));
 	data->combined_worker = combined_worker;
+	data->status = NODE_STATUS_SLEEPING;
 
 	node->data = data;
 	node->push_task = combined_worker_push_task;

+ 2 - 0
src/sched_policies/sched_node.h

@@ -25,6 +25,8 @@ void _starpu_sched_node_lock_all_workers(void);
 void _starpu_sched_node_unlock_all_workers(void);
 void _starpu_sched_node_lock_worker(int workerid);
 void _starpu_sched_node_unlock_worker(int workerid);
+void _starpu_sched_node_lock_scheduling(void);
+void _starpu_sched_node_unlock_scheduling(void);
 
 
 struct _starpu_worker * _starpu_sched_node_worker_get_worker(struct starpu_sched_node *);

+ 2 - 2
src/sched_policies/tree_eager.c

@@ -27,7 +27,7 @@ static void initialize_eager_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_fifo_create(NULL);
 	struct starpu_sched_node * eager_node = starpu_sched_node_eager_create(NULL);
 	t->root->add_child(t->root, eager_node);
-	starpu_sched_node_add_father(eager_node, t->root);
+	eager_node->add_father(eager_node, t->root);
 
 	unsigned i;
 	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
@@ -36,7 +36,7 @@ static void initialize_eager_center_policy(unsigned sched_ctx_id)
 		STARPU_ASSERT(worker_node);
 
 		eager_node->add_child(eager_node, worker_node);
-		starpu_sched_node_add_father(worker_node, eager_node);
+		worker_node->add_father(worker_node, eager_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 3 - 3
src/sched_policies/tree_eager_prefetching.c

@@ -42,7 +42,7 @@ static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_fifo_create(NULL);
 	struct starpu_sched_node * eager_node = starpu_sched_node_eager_create(NULL);
 	t->root->add_child(t->root, eager_node);
-	starpu_sched_node_add_father(eager_node, t->root);
+	eager_node->add_father(eager_node, t->root);
 
 	struct starpu_fifo_data fifo_data =
 		{
@@ -58,10 +58,10 @@ static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
 
 		struct starpu_sched_node * fifo_node = starpu_sched_node_fifo_create(&fifo_data);
 		fifo_node->add_child(fifo_node, worker_node);
-		starpu_sched_node_add_father(worker_node, fifo_node);
+		worker_node->add_father(worker_node, fifo_node);
 
 		eager_node->add_child(eager_node, fifo_node);
-		starpu_sched_node_add_father(fifo_node, eager_node);
+		fifo_node->add_father(fifo_node, eager_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 12 - 12
src/sched_policies/tree_heft.c

@@ -90,14 +90,14 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
 
 	struct starpu_sched_node * perfmodel_select_node = starpu_sched_node_perfmodel_select_create(&perfmodel_select_data);
 	window_node->add_child(window_node, perfmodel_select_node);
-	starpu_sched_node_add_father(perfmodel_select_node, window_node);
+	perfmodel_select_node->add_father(perfmodel_select_node, window_node);
 
 	perfmodel_select_node->add_child(perfmodel_select_node, calibrator_node);
-	starpu_sched_node_add_father(calibrator_node, perfmodel_select_node);
+	calibrator_node->add_father(calibrator_node, perfmodel_select_node);
 	perfmodel_select_node->add_child(perfmodel_select_node, perfmodel_node);
-	starpu_sched_node_add_father(perfmodel_node, perfmodel_select_node);
+	perfmodel_node->add_father(perfmodel_node, perfmodel_select_node);
 	perfmodel_select_node->add_child(perfmodel_select_node, no_perfmodel_node);
-	starpu_sched_node_add_father(no_perfmodel_node, perfmodel_select_node);
+	no_perfmodel_node->add_father(no_perfmodel_node, perfmodel_select_node);
 
 	struct starpu_prio_data prio_data =
 		{
@@ -111,20 +111,20 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
 		struct starpu_sched_node * worker_node = starpu_sched_node_worker_get(i);
 		STARPU_ASSERT(worker_node);
 
-		struct starpu_sched_node * prio = starpu_sched_node_prio_create(&prio_data);
-		prio->add_child(prio, worker_node);
-		starpu_sched_node_add_father(worker_node, prio);
+		struct starpu_sched_node * prio_node = starpu_sched_node_prio_create(&prio_data);
+		prio_node->add_child(prio_node, worker_node);
+		worker_node->add_father(worker_node, prio_node);
 
 		struct starpu_sched_node * impl_node = starpu_sched_node_best_implementation_create(NULL);
-		impl_node->add_child(impl_node, prio);
-		starpu_sched_node_add_father(prio, impl_node);
+		impl_node->add_child(impl_node, prio_node);
+		prio_node->add_father(prio_node, impl_node);
 
 		perfmodel_node->add_child(perfmodel_node, impl_node);
-		starpu_sched_node_add_father(impl_node, perfmodel_node);
+		impl_node->add_father(impl_node, perfmodel_node);
 		no_perfmodel_node->add_child(no_perfmodel_node, impl_node);
-		starpu_sched_node_add_father(impl_node, no_perfmodel_node);
+		impl_node->add_father(impl_node, no_perfmodel_node);
 		calibrator_node->add_child(calibrator_node, impl_node);
-		starpu_sched_node_add_father(impl_node, calibrator_node);
+		impl_node->add_father(impl_node, calibrator_node);
 	}
 
 	starpu_sched_tree_update_workers(t);

+ 12 - 12
src/sched_policies/tree_heft2.c

@@ -64,14 +64,14 @@ static void initialize_heft2_center_policy(unsigned sched_ctx_id)
 
 	struct starpu_sched_node * perfmodel_select_node = starpu_sched_node_perfmodel_select_create(&perfmodel_select_data);
 	window_node->add_child(window_node, perfmodel_select_node);
-	starpu_sched_node_add_father(perfmodel_select_node, window_node);
+	perfmodel_select_node->add_father(perfmodel_select_node, window_node);
 
 	perfmodel_select_node->add_child(perfmodel_select_node, calibrator_node);
-	starpu_sched_node_add_father(calibrator_node, perfmodel_select_node);
+	calibrator_node->add_father(calibrator_node, perfmodel_select_node);
 	perfmodel_select_node->add_child(perfmodel_select_node, perfmodel_node);
-	starpu_sched_node_add_father(perfmodel_node, perfmodel_select_node);
+	perfmodel_node->add_father(perfmodel_node, perfmodel_select_node);
 	perfmodel_select_node->add_child(perfmodel_select_node, no_perfmodel_node);
-	starpu_sched_node_add_father(no_perfmodel_node, perfmodel_select_node);
+	no_perfmodel_node->add_father(no_perfmodel_node, perfmodel_select_node);
 
 	struct starpu_prio_data prio_data =
 		{
@@ -85,20 +85,20 @@ static void initialize_heft2_center_policy(unsigned sched_ctx_id)
 		struct starpu_sched_node * worker_node = starpu_sched_node_worker_get(i);
 		STARPU_ASSERT(worker_node);
 
-		struct starpu_sched_node * prio = starpu_sched_node_prio_create(&prio_data);
-		prio->add_child(prio, worker_node);
-		starpu_sched_node_add_father(worker_node, prio);
+		struct starpu_sched_node * prio_node = starpu_sched_node_prio_create(&prio_data);
+		prio_node->add_child(prio_node, worker_node);
+		worker_node->add_father(worker_node, prio_node);
 
 		struct starpu_sched_node * impl_node = starpu_sched_node_best_implementation_create(NULL);
-		impl_node->add_child(impl_node, prio);
-		starpu_sched_node_add_father(prio, impl_node);
+		impl_node->add_child(impl_node, prio_node);
+		prio_node->add_father(prio_node, impl_node);
 
 		perfmodel_node->add_child(perfmodel_node, impl_node);
-		starpu_sched_node_add_father(impl_node, perfmodel_node);
+		impl_node->add_father(impl_node, perfmodel_node);
 		no_perfmodel_node->add_child(no_perfmodel_node, impl_node);
-		starpu_sched_node_add_father(impl_node, no_perfmodel_node);
+		impl_node->add_father(impl_node, no_perfmodel_node);
 		calibrator_node->add_child(calibrator_node, impl_node);
-		starpu_sched_node_add_father(impl_node, calibrator_node);
+		impl_node->add_father(impl_node, calibrator_node);
 	}
 
 	starpu_sched_tree_update_workers(t);

+ 2 - 2
src/sched_policies/tree_prio.c

@@ -24,7 +24,7 @@ static void initialize_prio_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_prio_create(NULL);
 	struct starpu_sched_node * eager_node = starpu_sched_node_eager_create(NULL);
 	t->root->add_child(t->root, eager_node);
-	starpu_sched_node_add_father(eager_node, t->root);
+	eager_node->add_father(eager_node, t->root);
 
 	unsigned i;
 	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
@@ -33,7 +33,7 @@ static void initialize_prio_center_policy(unsigned sched_ctx_id)
 		STARPU_ASSERT(worker_node);
 
 		eager_node->add_child(eager_node, worker_node);
-		starpu_sched_node_add_father(worker_node, eager_node);
+		worker_node->add_father(worker_node, eager_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 3 - 3
src/sched_policies/tree_prio_prefetching.c

@@ -38,7 +38,7 @@ static void initialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_prio_create(NULL);
 	struct starpu_sched_node * eager_node = starpu_sched_node_eager_create(NULL);
 	t->root->add_child(t->root, eager_node);
-	starpu_sched_node_add_father(eager_node, t->root);
+	eager_node->add_father(eager_node, t->root);
 
 	struct starpu_prio_data prio_data =
 		{
@@ -54,10 +54,10 @@ static void initialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
 
 		struct starpu_sched_node * prio_node = starpu_sched_node_prio_create(&prio_data);
 		prio_node->add_child(prio_node, worker_node);
-		starpu_sched_node_add_father(worker_node, prio_node);
+		worker_node->add_father(worker_node, prio_node);
 
 		eager_node->add_child(eager_node, prio_node);
-		starpu_sched_node_add_father(prio_node, eager_node);
+		prio_node->add_father(prio_node, eager_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 4 - 4
src/sched_policies/tree_random.c

@@ -27,7 +27,7 @@ static void initialize_random_fifo_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_fifo_create(NULL);
 	struct starpu_sched_node * random_node = starpu_sched_node_random_create(NULL);
 	t->root->add_child(t->root, random_node);
-	starpu_sched_node_add_father(random_node, t->root);
+	random_node->add_father(random_node, t->root);
 
 	unsigned i;
 	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
@@ -36,7 +36,7 @@ static void initialize_random_fifo_center_policy(unsigned sched_ctx_id)
 		STARPU_ASSERT(worker_node);
 
 		random_node->add_child(random_node, worker_node);
-		starpu_sched_node_add_father(worker_node, random_node);
+		worker_node->add_father(worker_node, random_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
@@ -73,7 +73,7 @@ static void initialize_random_prio_center_policy(unsigned sched_ctx_id)
  	t->root = starpu_sched_node_prio_create(NULL);
 	struct starpu_sched_node * random_node = starpu_sched_node_random_create(NULL);
 	t->root->add_child(t->root, random_node);
-	starpu_sched_node_add_father(random_node, t->root);
+	random_node->add_father(random_node, t->root);
 
 	unsigned i;
 	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
@@ -82,7 +82,7 @@ static void initialize_random_prio_center_policy(unsigned sched_ctx_id)
 		STARPU_ASSERT(worker_node);
 
 		random_node->add_child(random_node, worker_node);
-		starpu_sched_node_add_father(worker_node, random_node);
+		worker_node->add_father(worker_node, random_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 6 - 6
src/sched_policies/tree_random_prefetching.c

@@ -41,7 +41,7 @@ static void initialize_random_fifo_prefetching_center_policy(unsigned sched_ctx_
  	t->root = starpu_sched_node_fifo_create(NULL);
 	struct starpu_sched_node * random_node = starpu_sched_node_random_create(NULL);
 	t->root->add_child(t->root, random_node);
-	starpu_sched_node_add_father(random_node, t->root);
+	random_node->add_father(random_node, t->root);
 
 	struct starpu_fifo_data fifo_data =
 		{
@@ -57,10 +57,10 @@ static void initialize_random_fifo_prefetching_center_policy(unsigned sched_ctx_
 
 		struct starpu_sched_node * fifo_node = starpu_sched_node_fifo_create(&fifo_data);
 		fifo_node->add_child(fifo_node, worker_node);
-		starpu_sched_node_add_father(worker_node, fifo_node);
+		worker_node->add_father(worker_node, fifo_node);
 
 		random_node->add_child(random_node, fifo_node);
-		starpu_sched_node_add_father(fifo_node, random_node);
+		fifo_node->add_father(fifo_node, random_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
@@ -108,7 +108,7 @@ static void initialize_random_prio_prefetching_center_policy(unsigned sched_ctx_
  	t->root = starpu_sched_node_prio_create(NULL);
 	struct starpu_sched_node * random_node = starpu_sched_node_random_create(NULL);
 	t->root->add_child(t->root, random_node);
-	starpu_sched_node_add_father(random_node, t->root);
+	random_node->add_father(random_node, t->root);
 
 	struct starpu_prio_data prio_data =
 		{
@@ -124,10 +124,10 @@ static void initialize_random_prio_prefetching_center_policy(unsigned sched_ctx_
 
 		struct starpu_sched_node * prio_node = starpu_sched_node_prio_create(&prio_data);
 		prio_node->add_child(prio_node, worker_node);
-		starpu_sched_node_add_father(worker_node, prio_node);
+		worker_node->add_father(worker_node, prio_node);
 
 		random_node->add_child(random_node, prio_node);
-		starpu_sched_node_add_father(prio_node, random_node);
+		prio_node->add_father(prio_node, random_node);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 1 - 1
src/sched_policies/tree_ws.c

@@ -31,7 +31,7 @@ static void initialize_ws_center_policy(unsigned sched_ctx_id)
 		STARPU_ASSERT(worker_node);
 
 		t->root->add_child(t->root, worker_node);
-		starpu_sched_node_add_father(worker_node, t->root);
+		worker_node->add_father(worker_node, t->root);
 	}
 	starpu_sched_tree_update_workers(t);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);

+ 6 - 2
tests/main/driver_api/init_run_deinit.c

@@ -49,8 +49,12 @@ run(struct starpu_task *task, struct starpu_driver *d)
 	int ret;
 	ret = starpu_task_submit(task);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
-	ret = starpu_driver_run_once(d);
-	STARPU_CHECK_RETURN_VALUE(ret, "starpu_driver_run_once");
+	int i;
+	for (i = 0; i < NTASKS; i++)
+	{
+		ret = starpu_driver_run_once(d);
+		STARPU_CHECK_RETURN_VALUE(ret, "starpu_driver_run_once");
+	}
 	ret = starpu_task_wait(task);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_wait");
 }