Browse Source

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 11 years ago
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");
 }