浏览代码

Some refactoring on src/sched_policies

Marc Sergent 11 年之前
父节点
当前提交
333ea340f1

+ 136 - 82
include/starpu_sched_component.h

@@ -24,6 +24,15 @@
 #include <hwloc.h>
 #endif
 
+enum starpu_sched_component_properties
+{
+	STARPU_SCHED_COMPONENT_HOMOGENEOUS = (1<<0),
+	STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE = (1<<1)
+};
+
+#define STARPU_SCHED_COMPONENT_IS_HOMOGENEOUS(component) ((component)->properties & STARPU_SCHED_COMPONENT_HOMOGENEOUS)
+#define STARPU_SCHED_COMPONENT_IS_SINGLE_MEMORY_NODE(component) ((component)->properties & STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE)
+
 /* struct starpu_sched_component are scheduler modules, a scheduler is a tree-like
  * structure of them, some parts of scheduler can be shared by several contexes
  * to perform some local optimisations, so, for all components, a list of parent is
@@ -34,72 +43,55 @@
  */
 struct starpu_sched_component
 {
-	/* component->push_task(component, task)
-	 * this function is called to push a task on component subtree, this can either
-	 * perform a recursive call on a child or store the task in the component, then
-	 * it will be returned by a further pop_task call
-	 *
-	 * the caller must ensure that component is able to execute task
+	/* the set of workers in the component's subtree
 	 */
-	int (*push_task)(struct starpu_sched_component *,
-			 struct starpu_task *);
-	/* this function is called by workers to get a task on them parents
-	 * this function should first return a localy stored task or perform
-	 * a recursive call on parent
-	 *
-	 * a default implementation simply do a recursive call on parent
+	struct starpu_bitmap * workers;
+	/* the workers available in context
+	 * this member is set with : 
+	 * component->workers UNION tree->workers UNION
+	 * component->child[i]->workers_in_ctx iff exist x such as component->children[i]->parents[x] == component
 	 */
-	struct starpu_task * (*pop_task)(struct starpu_sched_component *);
-
-	/* this function is an heuristic that compute load of subtree, basicaly
-	 * it compute
-	 * estimated_load(component) = sum(estimated_load(component_children)) +
-	 *          nb_local_tasks / average(relative_speedup(underlying_worker))
+	struct starpu_bitmap * workers_in_ctx;
+	
+	/* component's private data, no restriction on use
 	 */
-	double (*estimated_load)(struct starpu_sched_component * component);
+	void * data;
 
-	double (*estimated_end)(struct starpu_sched_component * component);
 	/* the numbers of component's children
 	 */
 	int nchildren;
 	/* the vector of component's children
 	 */
 	struct starpu_sched_component ** children;
+	/* the numbers of component's parents
+	 */
+	int nparents;
 	/* may be shared by several contexts
 	 * so we need several parents
 	 */
 	struct starpu_sched_component ** parents;
-	int nparents;
-	/* the set of workers in the component's subtree
-	 */
-	struct starpu_bitmap * workers;
-	/* the workers available in context
-	 * this member is set with : 
-	 * component->workers UNION tree->workers UNION
-	 * component->child[i]->workers_in_ctx iff exist x such as component->children[i]->parents[x] == component
-	 */
-	struct starpu_bitmap * workers_in_ctx;
-	
-	/* component's private data, no restriction on use
-	 */
-	void * data;
 
 	void (*add_child)(struct starpu_sched_component * component, struct starpu_sched_component * child);
 	void (*remove_child)(struct starpu_sched_component * component, struct starpu_sched_component * child);
 	void (*add_parent)(struct starpu_sched_component * component, struct starpu_sched_component * parent);
 	void (*remove_parent)(struct starpu_sched_component * component, struct starpu_sched_component * parent);
 
-	/* this function is called for each component when workers are added or removed from a context
-	 */
-	void (*notify_change_workers)(struct starpu_sched_component * component);
-
-	/* this function is called by starpu_sched_component_destroy just before freeing component
+	/* component->push_task(component, task)
+	 * this function is called to push a task on component subtree, this can either
+	 * perform a recursive call on a child or store the task in the component, then
+	 * it will be returned by a further pop_task call
+	 *
+	 * the caller must ensure that component is able to execute task
 	 */
-	void (*deinit_data)(struct starpu_sched_component * component);
-	/* is_homogeneous is 0 iff workers in the component's subtree are heterogeneous,
-	 * this field is set and updated automaticaly, you shouldn't write on it
+	int (*push_task)(struct starpu_sched_component *,
+			 struct starpu_task *);
+	/* this function is called by workers to get a task on them parents
+	 * this function should first return a localy stored task or perform
+	 * a recursive call on parent
+	 *
+	 * a default implementation simply do a recursive call on parent
 	 */
-	int properties;
+	struct starpu_task * (*pop_task)(struct starpu_sched_component *);
 
 	/* This function is called by a component which implements a queue, allowing it to
 	 * signify to its parents that an empty slot is available in its queue.
@@ -117,6 +109,26 @@ struct starpu_sched_component
 	 */
 	void (*can_pull)(struct starpu_sched_component * component);
 
+	/* this function is an heuristic that compute load of subtree, basicaly
+	 * it compute
+	 * estimated_load(component) = sum(estimated_load(component_children)) +
+	 *          nb_local_tasks / average(relative_speedup(underlying_worker))
+	 */
+	double (*estimated_load)(struct starpu_sched_component * component);
+	double (*estimated_end)(struct starpu_sched_component * component);
+
+	/* this function is called by starpu_sched_component_destroy just before freeing component
+	 */
+	void (*deinit_data)(struct starpu_sched_component * component);
+	/* this function is called for each component when workers are added or removed from a context
+	 */
+	void (*notify_change_workers)(struct starpu_sched_component * component);
+
+	/* is_homogeneous is 0 if workers in the component's subtree are heterogeneous,
+	 * this field is set and updated automaticaly, you shouldn't write on it
+	 */
+	int properties;
+
 #ifdef STARPU_HAVE_HWLOC
 	/* in case of a hierarchical scheduler, this is set to the part of
 	 * topology that is binded to this component, eg: a numa node for a ws
@@ -125,14 +137,6 @@ struct starpu_sched_component
 	hwloc_obj_t obj;
 #endif
 };
-enum starpu_sched_component_properties
-{
-	STARPU_SCHED_COMPONENT_HOMOGENEOUS = (1<<0),
-	STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE = (1<<1)
-};
-
-#define STARPU_SCHED_COMPONENT_IS_HOMOGENEOUS(component) ((component)->properties & STARPU_SCHED_COMPONENT_HOMOGENEOUS)
-#define STARPU_SCHED_COMPONENT_IS_SINGLE_MEMORY_NODE(component) ((component)->properties & STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE)
 
 struct starpu_sched_tree
 {
@@ -146,8 +150,38 @@ struct starpu_sched_tree
 	starpu_pthread_mutex_t lock;
 };
 
-struct starpu_sched_component * starpu_sched_component_create(void);
+/*******************************************************************************
+ *							Scheduling Tree's Interface 					   *
+ ******************************************************************************/
+
+/* create an empty tree
+ */
+struct starpu_sched_tree * starpu_sched_tree_create(unsigned sched_ctx_id);
+void starpu_sched_tree_destroy(struct starpu_sched_tree * tree);
+
+/* destroy component and all his child
+ * except if they are shared between several contexts
+ */
+void starpu_sched_component_destroy_rec(struct starpu_sched_component * component);
+
+/* update all the component->workers member recursively
+ */
+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);
+
+int starpu_sched_tree_push_task(struct starpu_task * task);
+struct starpu_task * starpu_sched_tree_pop_task();
+
+void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
+void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
+
+/*******************************************************************************
+ *					Generic Scheduling Component's Interface 				   *
+ ******************************************************************************/
 
+struct starpu_sched_component * starpu_sched_component_create(void);
 void starpu_sched_component_destroy(struct starpu_sched_component * component);
 
 int starpu_sched_component_can_execute_task(struct starpu_sched_component * component, struct starpu_task * task);
@@ -155,16 +189,25 @@ int STARPU_WARN_UNUSED_RESULT starpu_sched_component_execute_preds(struct starpu
 double starpu_sched_component_transfer_length(struct starpu_sched_component * component, struct starpu_task * task);
 void starpu_sched_component_prefetch_on_node(struct starpu_sched_component * component, struct starpu_task * task);
 
+/*******************************************************************************
+ *							Worker Component's Interface 				   	   *
+ ******************************************************************************/
 
 /* no public create function for workers because we dont want to have several component_worker for a single workerid */
 struct starpu_sched_component * starpu_sched_component_worker_get(int workerid);
-
+int starpu_sched_component_worker_get_workerid(struct starpu_sched_component * worker_component);
 
 /* this function compare the available function of the component with the standard available for worker components*/
 int starpu_sched_component_is_worker(struct starpu_sched_component * component);
 int starpu_sched_component_is_simple_worker(struct starpu_sched_component * component);
 int starpu_sched_component_is_combined_worker(struct starpu_sched_component * component);
-int starpu_sched_component_worker_get_workerid(struct starpu_sched_component * worker_component);
+
+void starpu_sched_component_worker_pre_exec_hook(struct starpu_task * task);
+void starpu_sched_component_worker_post_exec_hook(struct starpu_task * task);
+
+/*******************************************************************************
+ *					Flow-control Fifo Component's Interface 				   *
+ ******************************************************************************/
 
 struct starpu_fifo_data
 {
@@ -175,6 +218,10 @@ struct starpu_fifo_data
 struct starpu_sched_component * starpu_sched_component_fifo_create(struct starpu_fifo_data * fifo_data);
 int starpu_sched_component_is_fifo(struct starpu_sched_component * component);
 
+/*******************************************************************************
+ *					Flow-control Prio Component's Interface 				   *
+ ******************************************************************************/
+
 struct starpu_prio_data
 {
 	unsigned ntasks_threshold;
@@ -184,19 +231,38 @@ struct starpu_prio_data
 struct starpu_sched_component * starpu_sched_component_prio_create(struct starpu_prio_data * prio_data);
 int starpu_sched_component_is_prio(struct starpu_sched_component * component);
 
+/*******************************************************************************
+ *			Resource-mapping Work-Stealing Component's Interface 			   *
+ ******************************************************************************/
+
 struct starpu_sched_component * starpu_sched_component_work_stealing_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int starpu_sched_component_is_work_stealing(struct starpu_sched_component * component);
 int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task);
 
+/*******************************************************************************
+ *				Resource-mapping Random Component's Interface 			   	   *
+ ******************************************************************************/
+
 struct starpu_sched_component * starpu_sched_component_random_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int starpu_sched_component_is_random(struct starpu_sched_component *);
 
+/*******************************************************************************
+ *				Resource-mapping Eager Component's Interface 				   *
+ ******************************************************************************/
+
 struct starpu_sched_component * starpu_sched_component_eager_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int starpu_sched_component_is_eager(struct starpu_sched_component *);
 
+/*******************************************************************************
+ *			Resource-mapping Eager-Calibration Component's Interface 		   *
+ ******************************************************************************/
+
 struct starpu_sched_component * starpu_sched_component_eager_calibration_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int starpu_sched_component_is_eager_calibration(struct starpu_sched_component *);
 
+/*******************************************************************************
+ *				Resource-mapping MCT Component's Interface 					   *
+ ******************************************************************************/
 
 struct starpu_mct_data
 {
@@ -211,13 +277,19 @@ struct starpu_mct_data
    the mct component doesnt do anything but pushing tasks on no_perf_model_component and calibrating_component
 */
 struct starpu_sched_component * starpu_sched_component_mct_create(struct starpu_mct_data * mct_data);
-
 int starpu_sched_component_is_mct(struct starpu_sched_component * component);
 
-struct starpu_sched_component * starpu_sched_component_heft_create(struct starpu_mct_data * mct_data);
+/*******************************************************************************
+ *				Resource-mapping HEFT Component's Interface 				   *
+ ******************************************************************************/
 
+struct starpu_sched_component * starpu_sched_component_heft_create(struct starpu_mct_data * mct_data);
 int starpu_sched_component_is_heft(struct starpu_sched_component * component);
 
+/*******************************************************************************
+ *		Special-purpose Best_Implementation Component's Interface 			   *
+ ******************************************************************************/
+
 /* this component select the best implementation for the first worker in context that can execute task.
  * and fill task->predicted and task->predicted_transfer
  * cannot have several child if push_task is called
@@ -231,34 +303,16 @@ struct starpu_perfmodel_select_data
 	struct starpu_sched_component * perfmodel_component;
 };
 
+/*******************************************************************************
+ *			Special-purpose Perfmodel_Select Component's Interface	 		   *
+ ******************************************************************************/
+
 struct starpu_sched_component * starpu_sched_component_perfmodel_select_create(struct starpu_perfmodel_select_data * perfmodel_select_data);
 int starpu_sched_component_is_perfmodel_select(struct starpu_sched_component * component);
 
-/*create an empty tree
- */
-struct starpu_sched_tree * starpu_sched_tree_create(unsigned sched_ctx_id);
-void starpu_sched_tree_destroy(struct starpu_sched_tree * tree);
-
-/* destroy component and all his child
- * except if they are shared between several contexts
- */
-void starpu_sched_component_destroy_rec(struct starpu_sched_component * component);
-
-/* update all the component->workers member recursively
- */
-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);
-
-int starpu_sched_tree_push_task(struct starpu_task * task);
-struct starpu_task * starpu_sched_tree_pop_task();
-void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
-void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
-void starpu_sched_component_worker_pre_exec_hook(struct starpu_task * task);
-void starpu_sched_component_worker_post_exec_hook(struct starpu_task * task);
-
-
+/*******************************************************************************
+ *						Recipe Component's Interface	 					   *
+ ******************************************************************************/
 
 struct starpu_sched_component_composed_recipe;
 

+ 9 - 6
src/sched_policies/component_best_implementation.c

@@ -20,7 +20,6 @@
 
 #include <float.h>
 
-
 /* return true if workerid can execute task, and fill task->predicted and task->predicted_transfer
  *  according to best implementation predictions
  */
@@ -72,15 +71,19 @@ static void select_best_implementation_and_set_preds(struct starpu_bitmap * work
 			break;
 }
 
-
-static int select_best_implementation_push_task(struct starpu_sched_component * component, struct starpu_task * task)
+static int best_implementation_push_task(struct starpu_sched_component * component, struct starpu_task * task)
 {
 	STARPU_ASSERT(component->nchildren == 1);
 	select_best_implementation_and_set_preds(component->workers_in_ctx, task);
 	return component->children[0]->push_task(component->children[0],task);
 }
 
-static struct starpu_task * select_best_implementation_pop_task(struct starpu_sched_component * component)
+int starpu_sched_component_is_best_implementation(struct starpu_sched_component * component)
+{
+	return component->push_task == best_implementation_push_task;
+}
+
+static struct starpu_task * best_implementation_pop_task(struct starpu_sched_component * component)
 {
 	struct starpu_task * task = NULL;
 	int i;
@@ -104,7 +107,7 @@ static struct starpu_task * select_best_implementation_pop_task(struct starpu_sc
 struct starpu_sched_component * starpu_sched_component_best_implementation_create(void * ARG STARPU_ATTRIBUTE_UNUSED)
 {
 	struct starpu_sched_component * component = starpu_sched_component_create();
-	component->push_task = select_best_implementation_push_task;
-	component->pop_task = select_best_implementation_pop_task;
+	component->push_task = best_implementation_push_task;
+	component->pop_task = best_implementation_pop_task;
 	return component;
 }

+ 6 - 7
src/sched_policies/component_fifo.c

@@ -21,7 +21,6 @@
 #include "fifo_queues.h"
 #include "sched_component.h"
 
-
 struct _starpu_fifo_data
 {
 	struct _starpu_fifo_taskq * fifo;
@@ -30,7 +29,7 @@ struct _starpu_fifo_data
 	double exp_len_threshold;
 };
 
-void fifo_component_deinit_data(struct starpu_sched_component * component)
+static void fifo_component_deinit_data(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component && component->data);
 	struct _starpu_fifo_data * f = component->data;
@@ -153,11 +152,6 @@ static int fifo_push_task(struct starpu_sched_component * component, struct star
 	return fifo_push_local_task(component, task, 0);
 }
 
-int starpu_sched_component_is_fifo(struct starpu_sched_component * component)
-{
-	return component->push_task == fifo_push_task;
-}
-
 static struct starpu_task * fifo_pop_task(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component && component->data);
@@ -237,6 +231,11 @@ static int fifo_can_push(struct starpu_sched_component * component)
 	return res;
 }
 
+int starpu_sched_component_is_fifo(struct starpu_sched_component * component)
+{
+	return component->push_task == fifo_push_task;
+}
+
 struct starpu_sched_component * starpu_sched_component_fifo_create(struct starpu_fifo_data * params)
 {
 	struct starpu_sched_component * component = starpu_sched_component_create();

+ 17 - 19
src/sched_policies/component_heft.c

@@ -36,24 +36,6 @@ struct _starpu_heft_data
 	struct _starpu_mct_data *mct_data;
 };
 
-static void heft_progress(struct starpu_sched_component *component);
-
-static int heft_push_task(struct starpu_sched_component * component, struct starpu_task * task)
-{
-	STARPU_ASSERT(component && task && starpu_sched_component_is_heft(component));
-	struct _starpu_heft_data * data = component->data;
-	struct _starpu_prio_deque * prio = &data->prio;
-	starpu_pthread_mutex_t * mutex = &data->mutex;
-
-	STARPU_PTHREAD_MUTEX_LOCK(mutex);
-	_starpu_prio_deque_push_task(prio,task);
-	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
-
-	heft_progress(component);
-
-	return 0;
-}
-
 static int heft_progress_one(struct starpu_sched_component *component)
 {
 	struct _starpu_heft_data * data = component->data;
@@ -196,6 +178,22 @@ static void heft_progress(struct starpu_sched_component *component)
 		;
 }
 
+static int heft_push_task(struct starpu_sched_component * component, struct starpu_task * task)
+{
+	STARPU_ASSERT(component && task && starpu_sched_component_is_heft(component));
+	struct _starpu_heft_data * data = component->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+
+	STARPU_PTHREAD_MUTEX_LOCK(mutex);
+	_starpu_prio_deque_push_task(prio,task);
+	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+	heft_progress(component);
+
+	return 0;
+}
+
 static int heft_can_push(struct starpu_sched_component *component)
 {
 	_starpu_sched_component_unlock_scheduling();
@@ -216,7 +214,7 @@ static int heft_can_push(struct starpu_sched_component *component)
 	return ret;
 }
 
-void heft_component_deinit_data(struct starpu_sched_component * component)
+static void heft_component_deinit_data(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_heft(component));
 	struct _starpu_mct_data * d = component->data;

+ 1 - 1
src/sched_policies/component_mct.c

@@ -106,7 +106,7 @@ static int mct_push_task(struct starpu_sched_component * component, struct starp
 	return ret;
 }
 
-void mct_component_deinit_data(struct starpu_sched_component * component)
+static void mct_component_deinit_data(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_mct(component));
 	struct _starpu_mct_data * d = component->data;

+ 6 - 32
src/sched_policies/component_perfmodel_select.c

@@ -54,43 +54,18 @@ static int perfmodel_select_push_task(struct starpu_sched_component * component,
 
 }
 
-int starpu_sched_component_is_perfmodel_select(struct starpu_sched_component * component)
-{
-	return component->push_task == perfmodel_select_push_task;
-}
-
-static void perfmodel_select_notify_change_in_workers(struct starpu_sched_component * component)
-{
-	STARPU_ASSERT(starpu_sched_component_is_perfmodel_select(component));
-	struct _starpu_perfmodel_select_data * data = component->data;
-
-	starpu_bitmap_unset_all(data->no_perfmodel_component->workers_in_ctx);
-	starpu_bitmap_unset_all(data->no_perfmodel_component->workers);
-	starpu_bitmap_or(data->no_perfmodel_component->workers_in_ctx, component->workers_in_ctx);
-	starpu_bitmap_or(data->no_perfmodel_component->workers, component->workers);
-	data->no_perfmodel_component->properties = component->properties;
-
-	starpu_bitmap_unset_all(data->perfmodel_component->workers_in_ctx);
-	starpu_bitmap_unset_all(data->perfmodel_component->workers);
-	starpu_bitmap_or(data->perfmodel_component->workers_in_ctx, component->workers_in_ctx);
-	starpu_bitmap_or(data->perfmodel_component->workers, component->workers);
-	data->perfmodel_component->properties = component->properties;
-
-	starpu_bitmap_unset_all(data->calibrator_component->workers_in_ctx);
-	starpu_bitmap_unset_all(data->calibrator_component->workers);
-	starpu_bitmap_or(data->calibrator_component->workers_in_ctx, component->workers_in_ctx);
-	starpu_bitmap_or(data->calibrator_component->workers, component->workers);
-	data->calibrator_component->properties = component->properties;
-}
-
-void perfmodel_select_component_deinit_data(struct starpu_sched_component * component)
-
+static void perfmodel_select_component_deinit_data(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component && component->data);
 	struct _starpu_perfmodel_select_data * d = component->data;
 	free(d);
 }
 
+int starpu_sched_component_is_perfmodel_select(struct starpu_sched_component * component)
+{
+	return component->push_task == perfmodel_select_push_task;
+}
+
 struct starpu_sched_component * starpu_sched_component_perfmodel_select_create(struct starpu_perfmodel_select_data * params)
 {
 	STARPU_ASSERT(params);
@@ -105,7 +80,6 @@ struct starpu_sched_component * starpu_sched_component_perfmodel_select_create(s
 	component->data = data;
 	component->push_task = perfmodel_select_push_task;
 	component->deinit_data = perfmodel_select_component_deinit_data;
-	component->notify_change_workers = perfmodel_select_notify_change_in_workers;
 
 	return component;
 }

+ 6 - 7
src/sched_policies/component_prio.c

@@ -34,7 +34,6 @@
 	_STARPU_TRACE_SCHED_COMPONENT_POP_PRIO(workerid, ntasks, exp_len); \
 } while (0)
 
-
 struct _starpu_prio_data
 {
 	struct _starpu_prio_deque prio;
@@ -43,7 +42,7 @@ struct _starpu_prio_data
 	double exp_len_threshold;
 };
 
-void prio_component_deinit_data(struct starpu_sched_component * component)
+static void prio_component_deinit_data(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component && component->data);
 	struct _starpu_prio_data * f = component->data;
@@ -167,11 +166,6 @@ static int prio_push_task(struct starpu_sched_component * component, struct star
 	return ret;
 }
 
-int starpu_sched_component_is_prio(struct starpu_sched_component * component)
-{
-	return component->push_task == prio_push_task;
-}
-
 static struct starpu_task * prio_pop_task(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component && component->data);
@@ -253,6 +247,11 @@ static int prio_can_push(struct starpu_sched_component * component)
 	return res;
 }
 
+int starpu_sched_component_is_prio(struct starpu_sched_component * component)
+{
+	return component->push_task == prio_push_task;
+}
+
 struct starpu_sched_component * starpu_sched_component_prio_create(struct starpu_prio_data * params)
 {
 	struct starpu_sched_component * component = starpu_sched_component_create();

+ 7 - 7
src/sched_policies/component_random.c

@@ -34,7 +34,6 @@ static double compute_relative_speedup(struct starpu_sched_component * component
 	return sum;
 }
 
-
 static int random_push_task(struct starpu_sched_component * component, struct starpu_task * task)
 {
 	STARPU_ASSERT(component->nchildren > 0);
@@ -97,10 +96,11 @@ static int random_push_task(struct starpu_sched_component * component, struct st
 
 	return ret_val;
 }
+
 /* taking the min of estimated_end not seems to be a good value to return here
  * as random scheduler balance between childs very poorly
  */
-double random_estimated_end(struct starpu_sched_component * component)
+static double random_estimated_end(struct starpu_sched_component * component)
 {
 	double sum = 0.0;
 	int i;
@@ -109,6 +109,11 @@ double random_estimated_end(struct starpu_sched_component * component)
 	return sum / component->nchildren;
 }
 
+int starpu_sched_component_is_random(struct starpu_sched_component *component)
+{
+	return component->push_task == random_push_task;
+}
+
 struct starpu_sched_component * starpu_sched_component_random_create(void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 	struct starpu_sched_component * component = starpu_sched_component_create();
@@ -116,8 +121,3 @@ struct starpu_sched_component * starpu_sched_component_random_create(void * arg
 	component->push_task = random_push_task;
 	return component;
 }
-
-int starpu_sched_component_is_random(struct starpu_sched_component *component)
-{
-	return component->push_task == random_push_task;
-}

+ 333 - 303
src/sched_policies/component_sched.c

@@ -24,222 +24,36 @@
 
 #include "sched_component.h"
 
-/* default implementation for component->pop_task()
- * just perform a recursive call on parent
- */
-static struct starpu_task * pop_task_component(struct starpu_sched_component * component)
-{
-	STARPU_ASSERT(component);
-	struct starpu_task * task = NULL;
-	int i;
-	for(i=0; i < component->nparents; i++)
-	{
-		if(component->parents[i] == NULL)
-			continue;
-		else
-		{
-			task = component->parents[i]->pop_task(component->parents[i]);
-			if(task)
-				break;
-		}
-	}
-	return task;
-}
+
 
 /******************************************************************************
- *          functions for struct starpu_sched_policy interface                *
+ *				Generic Scheduling Components' helper functions        		  *
  ******************************************************************************/
-int starpu_sched_tree_push_task(struct starpu_task * task)
-{
-	STARPU_ASSERT(task);
-	unsigned sched_ctx_id = task->sched_ctx;
-	struct starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	int workerid = starpu_worker_get_id();
-	/* application should take tree->lock to prevent concurent acces from hypervisor
-	 * worker take they own mutexes
-	 */
-	if(-1 == workerid)
-		STARPU_PTHREAD_MUTEX_LOCK(&tree->lock);
-	else
-		_starpu_sched_component_lock_worker(workerid);
-		
-	int ret_val = tree->root->push_task(tree->root,task);
-	if(-1 == workerid)
-		STARPU_PTHREAD_MUTEX_UNLOCK(&tree->lock);
-	else
-		_starpu_sched_component_unlock_worker(workerid);
-	return ret_val;
-}
-
-struct starpu_task * starpu_sched_tree_pop_task(unsigned sched_ctx STARPU_ATTRIBUTE_UNUSED)
-{
-	int workerid = starpu_worker_get_id();
-	struct starpu_sched_component * component = starpu_sched_component_worker_get(workerid);
-
-	/* _starpu_sched_component_lock_worker(workerid) is called by component->pop_task()
-	 */
-	struct starpu_task * task = component->pop_task(component);
-	return task;
-}
-
-void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
-{
-	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
-	STARPU_ASSERT(workerids);
-	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-
-	STARPU_PTHREAD_MUTEX_LOCK(&t->lock);
-	_starpu_sched_component_lock_all_workers();
-
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-		starpu_bitmap_set(t->workers, workerids[i]);
-
-	starpu_sched_tree_update_workers_in_ctx(t);
-
-	_starpu_sched_component_unlock_all_workers();
-	STARPU_PTHREAD_MUTEX_UNLOCK(&t->lock);
-}
-
-void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
-{
-	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
-	STARPU_ASSERT(workerids);
-	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-
-	STARPU_PTHREAD_MUTEX_LOCK(&t->lock);
-	_starpu_sched_component_lock_all_workers();
-
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-		starpu_bitmap_unset(t->workers, workerids[i]);
-
-	starpu_sched_tree_update_workers_in_ctx(t);
-
-	_starpu_sched_component_unlock_all_workers();
-	STARPU_PTHREAD_MUTEX_UNLOCK(&t->lock);
-}
-
-void starpu_sched_component_destroy_rec(struct starpu_sched_component * component)
-{
-	if(component == NULL)
-		return;
-
-	int i;
-	if(component->nchildren > 0)
-	{
-		for(i=0; i < component->nchildren; i++)
-			starpu_sched_component_destroy_rec(component->children[i]);
-	}
-
-	starpu_sched_component_destroy(component);
-}
-
-struct starpu_sched_tree * starpu_sched_tree_create(unsigned sched_ctx_id)
-{
-	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
-	struct starpu_sched_tree * t = malloc(sizeof(*t));
-	memset(t, 0, sizeof(*t));
-	t->sched_ctx_id = sched_ctx_id;
-	t->workers = starpu_bitmap_create();
-	STARPU_PTHREAD_MUTEX_INIT(&t->lock,NULL);
-	return t;
-}
-
-void starpu_sched_tree_destroy(struct starpu_sched_tree * tree)
-{
-	STARPU_ASSERT(tree);
-	if(tree->root)
-		starpu_sched_component_destroy_rec(tree->root);
-	starpu_bitmap_destroy(tree->workers);
-	STARPU_PTHREAD_MUTEX_DESTROY(&tree->lock);
-	free(tree);
-}
-
-static void starpu_sched_component_add_child(struct starpu_sched_component* component, struct starpu_sched_component * child)
-{
-	STARPU_ASSERT(component && child);
-	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
-	int i;
-	for(i = 0; i < component->nchildren; i++){
-		STARPU_ASSERT(component->children[i] != component);
-		STARPU_ASSERT(component->children[i] != NULL);
-	}
-
-	component->children = realloc(component->children, sizeof(struct starpu_sched_component *) * (component->nchildren + 1));
-	component->children[component->nchildren] = child;
-	component->nchildren++;
-}
-
-static void starpu_sched_component_remove_child(struct starpu_sched_component * component, struct starpu_sched_component * child)
-{
-	STARPU_ASSERT(component && child);
-	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
-	int pos;
-	for(pos = 0; pos < component->nchildren; pos++)
-		if(component->children[pos] == child)
-			break;
-	STARPU_ASSERT(pos != component->nchildren);
-	component->children[pos] = component->children[--component->nchildren];
-}
-
-static void starpu_sched_component_add_parent(struct starpu_sched_component* component, struct starpu_sched_component * parent)
-{
-	STARPU_ASSERT(component && parent);
-	int i;
-	for(i = 0; i < component->nparents; i++){
-		STARPU_ASSERT(component->parents[i] != component);
-		STARPU_ASSERT(component->parents[i] != NULL);
-	}
-
-	component->parents = realloc(component->parents, sizeof(struct starpu_sched_component *) * (component->nparents + 1));
-	component->parents[component->nparents] = parent;
-	component->nparents++;
-}
 
-static void starpu_sched_component_remove_parent(struct starpu_sched_component * component, struct starpu_sched_component * parent)
-{
-	STARPU_ASSERT(component && parent);
-	int pos;
-	for(pos = 0; pos < component->nparents; pos++)
-		if(component->parents[pos] == parent)
-			break;
-	STARPU_ASSERT(pos != component->nparents);
-	component->parents[pos] = component->parents[--component->nparents];
-}
 
-struct starpu_bitmap * _starpu_get_worker_mask(unsigned sched_ctx_id)
-{
-	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
-	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	STARPU_ASSERT(t);
-	return t->workers;
-}
 
-static double estimated_load(struct starpu_sched_component * component)
+/* Allows a worker to lock/unlock scheduling mutexes. Currently used in 
+ * self-defined can_push calls to allow can_pull calls to take those mutexes while the 
+ * current worker is pushing tasks on other workers (or itself). 
+ */
+void _starpu_sched_component_lock_scheduling(void)
 {
-	double sum = 0.0;
-	int i;
-	for( i = 0; i < component->nchildren; i++)
-	{
-		struct starpu_sched_component * c = component->children[i];
-		sum += c->estimated_load(c);
-	}
-	return sum;
+	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_component_lock_worker(workerid);	
+	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
 }
 
-static double _starpu_sched_component_estimated_end_min(struct starpu_sched_component * component)
+void _starpu_sched_component_unlock_scheduling(void)
 {
-	STARPU_ASSERT(component);
-	double min = DBL_MAX;
-	int i;
-	for(i = 0; i < component->nchildren; i++)
-	{
-		double tmp = component->children[i]->estimated_end(component->children[i]);
-		if(tmp < min)
-			min = tmp;
-	}
-	return min;
+	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_component_unlock_worker(workerid);	
 }
 
 /* this function find the best implementation or an implementation that need to be calibrated for a worker available
@@ -371,106 +185,22 @@ void starpu_sched_component_prefetch_on_node(struct starpu_sched_component * com
 	}
 }
 
-/* The default implementation of the can_push function is a recursive call to its parents.
- * A personally-made can_push in a component (like in prio components) is necessary to catch
- * this recursive call somewhere, if the user wants to exploit it.
+/* remove all child
+ * for all child of component, if child->parents[x] == component, set child->parents[x] to null 
+ * call component->deinit_data
  */
-static int starpu_sched_component_can_push(struct starpu_sched_component * component)
+void starpu_sched_component_destroy(struct starpu_sched_component *component)
 {
 	STARPU_ASSERT(component);
-	int ret = 0;
-	if(component->nparents > 0)
+	if(starpu_sched_component_is_worker(component))
+		return;
+	int i,j;
+	for(i = 0; i < component->nchildren; i++)
 	{
-		int i;
-		for(i=0; i < component->nparents; i++)
-		{
-			struct starpu_sched_component * parent = component->parents[i];
-			if(parent != NULL)
-				ret = parent->can_push(parent);
-			if(ret)
-				break;
-		}
-	}
-	return ret;
-}
-
-/* A can_pull call will try to wake up one worker associated to the childs of the
- * component. It is currenly called by components which holds a queue (like fifo and prio
- * components) to signify its childs that a task has been pushed on its local queue.
- */
-static void starpu_sched_component_can_pull(struct starpu_sched_component * component)
-{
-	STARPU_ASSERT(component);
-	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
-	int i;
-	for(i = 0; i < component->nchildren; i++)
-		component->children[i]->can_pull(component->children[i]);
-}
-
-/* Allows a worker to lock/unlock scheduling mutexes. Currently used in 
- * self-defined can_push calls to allow can_pull calls to take those mutexes while the 
- * current worker is pushing tasks on other workers (or itself). 
- */
-void _starpu_sched_component_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_component_lock_worker(workerid);	
-	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
-}
-
-void _starpu_sched_component_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_component_unlock_worker(workerid);	
-}
-
-void take_component_and_does_nothing(struct starpu_sched_component * component STARPU_ATTRIBUTE_UNUSED)
-{
-}
-
-struct starpu_sched_component * starpu_sched_component_create(void)
-{
-	struct starpu_sched_component * component = malloc(sizeof(*component));
-	memset(component,0,sizeof(*component));
-	component->workers = starpu_bitmap_create();
-	component->workers_in_ctx = starpu_bitmap_create();
-	component->add_child = starpu_sched_component_add_child;
-	component->remove_child = starpu_sched_component_remove_child;
-	component->add_parent = starpu_sched_component_add_parent;
-	component->remove_parent = starpu_sched_component_remove_parent;
-	component->pop_task = pop_task_component;
-	component->can_push = starpu_sched_component_can_push;
-	component->can_pull = starpu_sched_component_can_pull;
-	component->estimated_load = estimated_load;
-	component->estimated_end = _starpu_sched_component_estimated_end_min;
-	component->deinit_data = take_component_and_does_nothing;
-	component->notify_change_workers = take_component_and_does_nothing;
-	return component;
-}
-
-/* remove all child
- * for all child of component, if child->parents[x] == component, set child->parents[x] to null 
- * call component->deinit_data
- */
-void starpu_sched_component_destroy(struct starpu_sched_component *component)
-{
-	STARPU_ASSERT(component);
-	if(starpu_sched_component_is_worker(component))
-		return;
-	int i,j;
-	for(i = 0; i < component->nchildren; i++)
-	{
-		struct starpu_sched_component * child = component->children[i];
-		for(j = 0; j < child->nparents; j++)
-			if(child->parents[j] == component)
-				child->remove_parent(child,component);
+		struct starpu_sched_component * child = component->children[i];
+		for(j = 0; j < child->nparents; j++)
+			if(child->parents[j] == component)
+				child->remove_parent(child,component);
 
 	}
 	while(component->nchildren != 0)
@@ -493,7 +223,22 @@ void starpu_sched_component_destroy(struct starpu_sched_component *component)
 	free(component);
 }
 
-static void set_properties(struct starpu_sched_component * component)
+void starpu_sched_component_destroy_rec(struct starpu_sched_component * component)
+{
+	if(component == NULL)
+		return;
+
+	int i;
+	if(component->nchildren > 0)
+	{
+		for(i=0; i < component->nchildren; i++)
+			starpu_sched_component_destroy_rec(component->children[i]);
+	}
+
+	starpu_sched_component_destroy(component);
+}
+
+void set_properties(struct starpu_sched_component * component)
 {
 	STARPU_ASSERT(component);
 	component->properties = 0;
@@ -565,6 +310,22 @@ void _starpu_sched_component_update_workers_in_ctx(struct starpu_sched_component
 	component->notify_change_workers(component);
 }
 
+
+
+/******************************************************************************
+ *          			Scheduling Trees' helper functions        			  *
+ ******************************************************************************/
+
+
+
+struct starpu_bitmap * _starpu_get_worker_mask(unsigned sched_ctx_id)
+{
+	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
+	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	STARPU_ASSERT(t);
+	return t->workers;
+}
+
 void starpu_sched_tree_update_workers_in_ctx(struct starpu_sched_tree * t)
 {
 	STARPU_ASSERT(t);
@@ -576,3 +337,272 @@ void starpu_sched_tree_update_workers(struct starpu_sched_tree * t)
 	STARPU_ASSERT(t);
 	_starpu_sched_component_update_workers(t->root);
 }
+
+
+
+/******************************************************************************
+ *          			Scheduling Trees' Functions                			  *
+ *  	Most of them are used to define the starpu_sched_policy interface     *
+ ******************************************************************************/
+
+
+
+int starpu_sched_tree_push_task(struct starpu_task * task)
+{
+	STARPU_ASSERT(task);
+	unsigned sched_ctx_id = task->sched_ctx;
+	struct starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	int workerid = starpu_worker_get_id();
+	/* application should take tree->lock to prevent concurent acces from hypervisor
+	 * worker take they own mutexes
+	 */
+	if(-1 == workerid)
+		STARPU_PTHREAD_MUTEX_LOCK(&tree->lock);
+	else
+		_starpu_sched_component_lock_worker(workerid);
+		
+	int ret_val = tree->root->push_task(tree->root,task);
+	if(-1 == workerid)
+		STARPU_PTHREAD_MUTEX_UNLOCK(&tree->lock);
+	else
+		_starpu_sched_component_unlock_worker(workerid);
+	return ret_val;
+}
+
+struct starpu_task * starpu_sched_tree_pop_task(unsigned sched_ctx STARPU_ATTRIBUTE_UNUSED)
+{
+	int workerid = starpu_worker_get_id();
+	struct starpu_sched_component * component = starpu_sched_component_worker_get(workerid);
+
+	/* _starpu_sched_component_lock_worker(workerid) is called by component->pop_task()
+	 */
+	struct starpu_task * task = component->pop_task(component);
+	return task;
+}
+
+void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
+{
+	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
+	STARPU_ASSERT(workerids);
+	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+
+	STARPU_PTHREAD_MUTEX_LOCK(&t->lock);
+	_starpu_sched_component_lock_all_workers();
+
+	unsigned i;
+	for(i = 0; i < nworkers; i++)
+		starpu_bitmap_set(t->workers, workerids[i]);
+
+	starpu_sched_tree_update_workers_in_ctx(t);
+
+	_starpu_sched_component_unlock_all_workers();
+	STARPU_PTHREAD_MUTEX_UNLOCK(&t->lock);
+}
+
+void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
+{
+	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
+	STARPU_ASSERT(workerids);
+	struct starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+
+	STARPU_PTHREAD_MUTEX_LOCK(&t->lock);
+	_starpu_sched_component_lock_all_workers();
+
+	unsigned i;
+	for(i = 0; i < nworkers; i++)
+		starpu_bitmap_unset(t->workers, workerids[i]);
+
+	starpu_sched_tree_update_workers_in_ctx(t);
+
+	_starpu_sched_component_unlock_all_workers();
+	STARPU_PTHREAD_MUTEX_UNLOCK(&t->lock);
+}
+
+struct starpu_sched_tree * starpu_sched_tree_create(unsigned sched_ctx_id)
+{
+	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
+	struct starpu_sched_tree * t = malloc(sizeof(*t));
+	memset(t, 0, sizeof(*t));
+	t->sched_ctx_id = sched_ctx_id;
+	t->workers = starpu_bitmap_create();
+	STARPU_PTHREAD_MUTEX_INIT(&t->lock,NULL);
+	return t;
+}
+
+void starpu_sched_tree_destroy(struct starpu_sched_tree * tree)
+{
+	STARPU_ASSERT(tree);
+	if(tree->root)
+		starpu_sched_component_destroy_rec(tree->root);
+	starpu_bitmap_destroy(tree->workers);
+	STARPU_PTHREAD_MUTEX_DESTROY(&tree->lock);
+	free(tree);
+}
+
+
+
+/******************************************************************************
+ *          Interface Functions for Generic Scheduling Components             *
+ ******************************************************************************/
+
+
+
+static void starpu_sched_component_add_child(struct starpu_sched_component* component, struct starpu_sched_component * child)
+{
+	STARPU_ASSERT(component && child);
+	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
+	int i;
+	for(i = 0; i < component->nchildren; i++){
+		STARPU_ASSERT(component->children[i] != component);
+		STARPU_ASSERT(component->children[i] != NULL);
+	}
+
+	component->children = realloc(component->children, sizeof(struct starpu_sched_component *) * (component->nchildren + 1));
+	component->children[component->nchildren] = child;
+	component->nchildren++;
+}
+
+static void starpu_sched_component_remove_child(struct starpu_sched_component * component, struct starpu_sched_component * child)
+{
+	STARPU_ASSERT(component && child);
+	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
+	int pos;
+	for(pos = 0; pos < component->nchildren; pos++)
+		if(component->children[pos] == child)
+			break;
+	STARPU_ASSERT(pos != component->nchildren);
+	component->children[pos] = component->children[--component->nchildren];
+}
+
+static void starpu_sched_component_add_parent(struct starpu_sched_component* component, struct starpu_sched_component * parent)
+{
+	STARPU_ASSERT(component && parent);
+	int i;
+	for(i = 0; i < component->nparents; i++){
+		STARPU_ASSERT(component->parents[i] != component);
+		STARPU_ASSERT(component->parents[i] != NULL);
+	}
+
+	component->parents = realloc(component->parents, sizeof(struct starpu_sched_component *) * (component->nparents + 1));
+	component->parents[component->nparents] = parent;
+	component->nparents++;
+}
+
+static void starpu_sched_component_remove_parent(struct starpu_sched_component * component, struct starpu_sched_component * parent)
+{
+	STARPU_ASSERT(component && parent);
+	int pos;
+	for(pos = 0; pos < component->nparents; pos++)
+		if(component->parents[pos] == parent)
+			break;
+	STARPU_ASSERT(pos != component->nparents);
+	component->parents[pos] = component->parents[--component->nparents];
+}
+
+/* default implementation for component->pop_task()
+ * just perform a recursive call on parent
+ */
+static struct starpu_task * starpu_sched_component_pop_task(struct starpu_sched_component * component)
+{
+	STARPU_ASSERT(component);
+	struct starpu_task * task = NULL;
+	int i;
+	for(i=0; i < component->nparents; i++)
+	{
+		if(component->parents[i] == NULL)
+			continue;
+		else
+		{
+			task = component->parents[i]->pop_task(component->parents[i]);
+			if(task)
+				break;
+		}
+	}
+	return task;
+}
+
+/* The default implementation of the can_push function is a recursive call to its parents.
+ * A personally-made can_push in a component (like in prio components) is necessary to catch
+ * this recursive call somewhere, if the user wants to exploit it.
+ */
+static int starpu_sched_component_can_push(struct starpu_sched_component * component)
+{
+	STARPU_ASSERT(component);
+	int ret = 0;
+	if(component->nparents > 0)
+	{
+		int i;
+		for(i=0; i < component->nparents; i++)
+		{
+			struct starpu_sched_component * parent = component->parents[i];
+			if(parent != NULL)
+				ret = parent->can_push(parent);
+			if(ret)
+				break;
+		}
+	}
+	return ret;
+}
+
+/* A can_pull call will try to wake up one worker associated to the childs of the
+ * component. It is currenly called by components which holds a queue (like fifo and prio
+ * components) to signify its childs that a task has been pushed on its local queue.
+ */
+static void starpu_sched_component_can_pull(struct starpu_sched_component * component)
+{
+	STARPU_ASSERT(component);
+	STARPU_ASSERT(!starpu_sched_component_is_worker(component));
+	int i;
+	for(i = 0; i < component->nchildren; i++)
+		component->children[i]->can_pull(component->children[i]);
+}
+
+static double starpu_sched_component_estimated_load(struct starpu_sched_component * component)
+{
+	double sum = 0.0;
+	int i;
+	for( i = 0; i < component->nchildren; i++)
+	{
+		struct starpu_sched_component * c = component->children[i];
+		sum += c->estimated_load(c);
+	}
+	return sum;
+}
+
+static double starpu_sched_component_estimated_end_min(struct starpu_sched_component * component)
+{
+	STARPU_ASSERT(component);
+	double min = DBL_MAX;
+	int i;
+	for(i = 0; i < component->nchildren; i++)
+	{
+		double tmp = component->children[i]->estimated_end(component->children[i]);
+		if(tmp < min)
+			min = tmp;
+	}
+	return min;
+}
+
+static void take_component_and_does_nothing(struct starpu_sched_component * component STARPU_ATTRIBUTE_UNUSED)
+{
+}
+
+struct starpu_sched_component * starpu_sched_component_create(void)
+{
+	struct starpu_sched_component * component = malloc(sizeof(*component));
+	memset(component,0,sizeof(*component));
+	component->workers = starpu_bitmap_create();
+	component->workers_in_ctx = starpu_bitmap_create();
+	component->add_child = starpu_sched_component_add_child;
+	component->remove_child = starpu_sched_component_remove_child;
+	component->add_parent = starpu_sched_component_add_parent;
+	component->remove_parent = starpu_sched_component_remove_parent;
+	component->pop_task = starpu_sched_component_pop_task;
+	component->can_push = starpu_sched_component_can_push;
+	component->can_pull = starpu_sched_component_can_pull;
+	component->estimated_load = starpu_sched_component_estimated_load;
+	component->estimated_end = starpu_sched_component_estimated_end_min;
+	component->deinit_data = take_component_and_does_nothing;
+	component->notify_change_workers = take_component_and_does_nothing;
+	return component;
+}

+ 245 - 295
src/sched_policies/component_worker.c

@@ -57,6 +57,13 @@
  */
 
 
+
+/******************************************************************************
+ *					  Worker Components' Data Structures					  *
+ *****************************************************************************/
+
+
+
 struct _starpu_task_grid
 {
 	/* this member may be NULL if a worker have poped it but its a
@@ -117,6 +124,14 @@ struct _starpu_worker_component_data
 /* this array store worker components */
 static struct starpu_sched_component * _worker_components[STARPU_NMAXWORKERS];
 	
+struct starpu_sched_component * starpu_sched_component_worker_get(int workerid);
+
+
+/******************************************************************************
+ *				Worker Components' Task List and Grid Functions				  *
+ *****************************************************************************/
+
+
 
 static struct _starpu_worker_task_list * _starpu_worker_task_list_create(void)
 {
@@ -127,16 +142,27 @@ static struct _starpu_worker_task_list * _starpu_worker_task_list_create(void)
 	STARPU_PTHREAD_MUTEX_INIT(&l->mutex,NULL);
 	return l;
 }
+
 static struct _starpu_task_grid * _starpu_task_grid_create(void)
 {
 	struct _starpu_task_grid * t = malloc(sizeof(*t));
 	memset(t, 0, sizeof(*t));
 	return t;
 }
+
+static struct _starpu_worker_task_list * _worker_get_list(void)
+{
+	int workerid = starpu_worker_get_id();
+	STARPU_ASSERT(0 <= workerid && workerid < (int) starpu_worker_get_count());
+	struct _starpu_worker_component_data * d = starpu_sched_component_worker_get(workerid)->data;
+	return d->list;
+}
+
 static void _starpu_task_grid_destroy(struct _starpu_task_grid * t)
 {
 	free(t);
 }
+
 static void _starpu_worker_task_list_destroy(struct _starpu_worker_task_list * l)
 {
 	if(l)
@@ -272,51 +298,11 @@ static inline struct starpu_task * _starpu_worker_task_list_pop(struct _starpu_w
 
 
 
+/******************************************************************************
+ *				Worker Components' Private Helper Functions			      	  *
+ *****************************************************************************/
 
 
-static struct starpu_sched_component * starpu_sched_component_worker_create(int workerid);
-static struct starpu_sched_component * starpu_sched_component_combined_worker_create(int workerid);
-struct starpu_sched_component * starpu_sched_component_worker_get(int workerid)
-{
-	STARPU_ASSERT(workerid >= 0 && workerid < STARPU_NMAXWORKERS);
-	/* we may need to take a mutex here */
-	if(_worker_components[workerid])
-		return _worker_components[workerid];
-	else
-	{
-		struct starpu_sched_component * component;
-		if(workerid < (int) starpu_worker_get_count())
-			component = starpu_sched_component_worker_create(workerid);
-		else
-			component = starpu_sched_component_combined_worker_create(workerid);
-		_worker_components[workerid] = component;
-		return component;
-	}
-}
-
-struct _starpu_worker * _starpu_sched_component_worker_get_worker(struct starpu_sched_component * worker_component)
-{
-	STARPU_ASSERT(starpu_sched_component_is_simple_worker(worker_component));
-	struct _starpu_worker_component_data * data = worker_component->data;
-	return data->worker;
-}
-struct _starpu_combined_worker * _starpu_sched_component_combined_worker_get_combined_worker(struct starpu_sched_component * worker_component)
-{
-	STARPU_ASSERT(starpu_sched_component_is_combined_worker(worker_component));
-	struct _starpu_worker_component_data * data = worker_component->data;
-	return data->combined_worker;
-}
-
-/*
-enum starpu_perfmodel_archtype starpu_sched_component_worker_get_perf_arch(struct starpu_sched_component * worker_component)
-{
-	STARPU_ASSERT(starpu_sched_component_is_worker(worker_component));
-	if(starpu_sched_component_is_simple_worker(worker_component))
-		return _starpu_sched_component_worker_get_worker(worker_component)->perf_arch;
-	else
-		return _starpu_sched_component_combined_worker_get_combined_worker(worker_component)->perf_arch;
-}
-*/
 
 static void _starpu_sched_component_worker_set_sleep_status(struct starpu_sched_component * worker_component)
 {
@@ -324,14 +310,12 @@ static void _starpu_sched_component_worker_set_sleep_status(struct starpu_sched_
 	struct _starpu_worker_component_data * data = worker_component->data;
 	data->status = COMPONENT_STATUS_SLEEPING;
 }
-
 static void _starpu_sched_component_worker_set_changed_status(struct starpu_sched_component * worker_component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_worker(worker_component));
 	struct _starpu_worker_component_data * data = worker_component->data;
 	data->status = COMPONENT_STATUS_CHANGED;
 }
-
 static void _starpu_sched_component_worker_reset_status(struct starpu_sched_component * worker_component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_worker(worker_component));
@@ -345,14 +329,12 @@ static int _starpu_sched_component_worker_is_reset_status(struct starpu_sched_co
 	struct _starpu_worker_component_data * data = worker_component->data;
 	return (data->status == COMPONENT_STATUS_RESET);
 }
-
 static int _starpu_sched_component_worker_is_changed_status(struct starpu_sched_component * worker_component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_worker(worker_component));
 	struct _starpu_worker_component_data * data = worker_component->data;
 	return (data->status == COMPONENT_STATUS_CHANGED);
 }
-
 static int _starpu_sched_component_worker_is_sleeping_status(struct starpu_sched_component * worker_component)
 {
 	STARPU_ASSERT(starpu_sched_component_is_worker(worker_component));
@@ -360,19 +342,69 @@ static int _starpu_sched_component_worker_is_sleeping_status(struct starpu_sched
 	return (data->status == COMPONENT_STATUS_SLEEPING);
 }
 
+#ifndef STARPU_NO_ASSERT
+static int _worker_consistant(struct starpu_sched_component * component)
+{
+	int is_a_worker = 0;
+	int i;
+	for(i = 0; i<STARPU_NMAXWORKERS; i++)
+		if(_worker_components[i] == component)
+			is_a_worker = 1;
+	if(!is_a_worker)
+		return 0;
+	struct _starpu_worker_component_data * data = component->data;
+	if(data->worker)
+	{
+		int id = data->worker->workerid;
+		return  (_worker_components[id] == component)
+			&&  component->nchildren == 0;
+	}
+	return 1;
+}
+#endif
+
+
+
+/******************************************************************************
+ *			Worker Components' Public Helper Functions (Part 1)		     	  *
+ *****************************************************************************/
+
+
+
+struct _starpu_worker * _starpu_sched_component_worker_get_worker(struct starpu_sched_component * worker_component)
+{
+	STARPU_ASSERT(starpu_sched_component_is_simple_worker(worker_component));
+	struct _starpu_worker_component_data * data = worker_component->data;
+	return data->worker;
+}
+struct _starpu_combined_worker * _starpu_sched_component_combined_worker_get_combined_worker(struct starpu_sched_component * worker_component)
+{
+	STARPU_ASSERT(starpu_sched_component_is_combined_worker(worker_component));
+	struct _starpu_worker_component_data * data = worker_component->data;
+	return data->combined_worker;
+}
+
 void _starpu_sched_component_lock_worker(int workerid)
 {
 	STARPU_ASSERT(0 <= workerid && workerid < (int) starpu_worker_get_count());
-	struct _starpu_worker_component_data * data = starpu_sched_component_worker_create(workerid)->data;
+	struct _starpu_worker_component_data * data = starpu_sched_component_worker_get(workerid)->data;
 	STARPU_PTHREAD_MUTEX_LOCK(&data->lock);
 }
 void _starpu_sched_component_unlock_worker(int workerid)
 {
 	STARPU_ASSERT(0 <= workerid && workerid < (int)starpu_worker_get_count());
-	struct _starpu_worker_component_data * data = starpu_sched_component_worker_create(workerid)->data;
+	struct _starpu_worker_component_data * data = starpu_sched_component_worker_get(workerid)->data;
 	STARPU_PTHREAD_MUTEX_UNLOCK(&data->lock);
 }
 
+
+
+/******************************************************************************
+ *				Simple Worker Components' Interface Functions			      *
+ *****************************************************************************/
+
+
+
 static void simple_worker_can_pull(struct starpu_sched_component * worker_component)
 {
 	(void) worker_component;
@@ -398,33 +430,6 @@ static void simple_worker_can_pull(struct starpu_sched_component * worker_compon
 		_starpu_sched_component_unlock_worker(w->workerid);
 }
 
-static void combined_worker_can_pull(struct starpu_sched_component * component)
-{
-	(void) component;
-	STARPU_ASSERT(starpu_sched_component_is_combined_worker(component));
-	struct _starpu_worker_component_data * data = component->data;
-	int workerid = starpu_worker_get_id();
-	int i;
-	for(i = 0; i < data->combined_worker->worker_size; i++)
-	{
-		if(i == workerid)
-			continue;
-		int worker = data->combined_worker->combined_workerid[i];
-		_starpu_sched_component_lock_worker(worker);
-		if(_starpu_sched_component_worker_is_sleeping_status(component))
-		{
-			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_component_worker_is_reset_status(component))
-			_starpu_sched_component_worker_set_changed_status(component);
-
-		_starpu_sched_component_unlock_worker(worker);
-	}
-}
-
 static int simple_worker_push_task(struct starpu_sched_component * component, struct starpu_task *task)
 {
 	STARPU_ASSERT(starpu_sched_component_is_worker(component));
@@ -449,7 +454,7 @@ static int simple_worker_push_task(struct starpu_sched_component * component, st
 	return 0;
 }
 
-struct starpu_task * simple_worker_pop_task(struct starpu_sched_component *component)
+static struct starpu_task * simple_worker_pop_task(struct starpu_sched_component *component)
 {
 	struct _starpu_worker_component_data * data = component->data;
 	struct _starpu_worker_task_list * list = data->list;
@@ -499,73 +504,7 @@ struct starpu_task * simple_worker_pop_task(struct starpu_sched_component *compo
 		starpu_push_task_end(task);
 	return task;
 }
-void starpu_sched_component_worker_destroy(struct starpu_sched_component *component)
-{
-	struct _starpu_worker * worker = _starpu_sched_component_worker_get_worker(component);
-	unsigned id = worker->workerid;
-	assert(_worker_components[id] == component);
-	int i;
-	for(i = 0; i < STARPU_NMAX_SCHED_CTXS ; i++)
-		if(component->parents[i] != NULL)
-			return;//this component is shared between several contexts
-	starpu_sched_component_destroy(component);
-	_worker_components[id] = NULL;
-}
 
-void _starpu_sched_component_lock_all_workers(void)
-{
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count(); i++)
-		_starpu_sched_component_lock_worker(i);
-}
-void _starpu_sched_component_unlock_all_workers(void)
-{
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count(); i++)
-		_starpu_sched_component_unlock_worker(i);
-}
-
-
-/*
-  dont know if this may be usefull…
-static double worker_estimated_finish_time(struct _starpu_worker * worker)
-{
-	STARPU_PTHREAD_MUTEX_LOCK(&worker->mutex);
-	double sum = 0.0;
-	struct starpu_task_list list = worker->local_tasks;
-	struct starpu_task * task;
-	for(task = starpu_task_list_front(&list);
-	    task != starpu_task_list_end(&list);
-	    task = starpu_task_list_next(task))
-		if(!isnan(task->predicted))
-		   sum += task->predicted;
-	if(worker->current_task)
-	{
-		struct starpu_task * t = worker->current_task;
-		if(t && !isnan(t->predicted))
-			sum += t->predicted/2;
-	}
-	STARPU_PTHREAD_MUTEX_UNLOCK(&worker->mutex);
-	return sum + starpu_timing_now();
-}
-*/
-static double combined_worker_estimated_end(struct starpu_sched_component * component)
-{
-	STARPU_ASSERT(starpu_sched_component_is_combined_worker(component));
-	struct _starpu_worker_component_data * data = component->data;
-	struct _starpu_combined_worker * combined_worker = data->combined_worker;
-	double max = 0.0;
-	int i;
-	for(i = 0; i < combined_worker->worker_size; i++)
-	{
-		data = _worker_components[combined_worker->combined_workerid[i]]->data;
-		STARPU_PTHREAD_MUTEX_LOCK(&data->list->mutex);
-		double tmp = data->list->exp_end;
-		STARPU_PTHREAD_MUTEX_UNLOCK(&data->list->mutex);
-		max = tmp > max ? tmp : max;
-	}
-	return max;
-}
 static double simple_worker_estimated_end(struct starpu_sched_component * component)
 {
 	struct _starpu_worker_component_data * data = component->data;
@@ -576,8 +515,6 @@ static double simple_worker_estimated_end(struct starpu_sched_component * compon
 	return tmp;
 }
 
-
-
 static double simple_worker_estimated_load(struct starpu_sched_component * component)
 {
 	struct _starpu_worker * worker = _starpu_sched_component_worker_get_worker(component);
@@ -598,18 +535,96 @@ static double simple_worker_estimated_load(struct starpu_sched_component * compo
 				starpu_worker_get_perf_archtype(starpu_bitmap_first(component->workers)));
 }
 
-static double combined_worker_estimated_load(struct starpu_sched_component * component)
+static void _worker_component_deinit_data(struct starpu_sched_component * component)
 {
 	struct _starpu_worker_component_data * d = component->data;
-	struct _starpu_combined_worker * c = d->combined_worker;
-	double load = 0;
+	_starpu_worker_task_list_destroy(d->list);
+	if(starpu_sched_component_is_simple_worker(component))
+		STARPU_PTHREAD_MUTEX_DESTROY(&d->lock);
 	int i;
-	for(i = 0; i < c->worker_size; i++)
+	for(i = 0; i < STARPU_NMAXWORKERS; i++)
+		if(_worker_components[i] == component)
+		{
+			_worker_components[i] = NULL;
+			return;
+		}
+	free(d);
+}
+
+static struct starpu_sched_component * starpu_sched_component_worker_create(int workerid)
+{
+	STARPU_ASSERT(0 <=  workerid && workerid < (int) starpu_worker_get_count());
+
+	if(_worker_components[workerid])
+		return _worker_components[workerid];
+
+	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
+	if(worker == NULL)
+		return NULL;
+	struct starpu_sched_component * component = starpu_sched_component_create();
+	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
+	memset(data, 0, sizeof(*data));
+
+	data->worker = worker;
+	STARPU_PTHREAD_MUTEX_INIT(&data->lock,NULL);
+	data->status = COMPONENT_STATUS_SLEEPING;
+	data->list = _starpu_worker_task_list_create();
+	component->data = data;
+
+	component->push_task = simple_worker_push_task;
+	component->pop_task = simple_worker_pop_task;
+	component->can_pull = simple_worker_can_pull;
+	component->estimated_end = simple_worker_estimated_end;
+	component->estimated_load = simple_worker_estimated_load;
+	component->deinit_data = _worker_component_deinit_data;
+	starpu_bitmap_set(component->workers, workerid);
+	starpu_bitmap_or(component->workers_in_ctx, component->workers);
+	_worker_components[workerid] = component;
+
+#ifdef STARPU_HAVE_HWLOC
+	struct _starpu_machine_config *config = _starpu_get_machine_config();
+	struct _starpu_machine_topology *topology = &config->topology;
+	hwloc_obj_t obj = hwloc_get_obj_by_depth(topology->hwtopology, config->cpu_depth, worker->bindid);
+	STARPU_ASSERT(obj);
+	component->obj = obj;
+#endif
+
+	return component;
+}
+
+
+
+/******************************************************************************
+ *				Combined Worker Components' Interface Functions			      *
+ *****************************************************************************/
+
+
+
+static void combined_worker_can_pull(struct starpu_sched_component * component)
+{
+	(void) component;
+	STARPU_ASSERT(starpu_sched_component_is_combined_worker(component));
+	struct _starpu_worker_component_data * data = component->data;
+	int workerid = starpu_worker_get_id();
+	int i;
+	for(i = 0; i < data->combined_worker->worker_size; i++)
 	{
-		struct starpu_sched_component * n = starpu_sched_component_worker_get(c->combined_workerid[i]);
-		load += n->estimated_load(n);
+		if(i == workerid)
+			continue;
+		int worker = data->combined_worker->combined_workerid[i];
+		_starpu_sched_component_lock_worker(worker);
+		if(_starpu_sched_component_worker_is_sleeping_status(component))
+		{
+			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_component_worker_is_reset_status(component))
+			_starpu_sched_component_worker_set_changed_status(component);
+
+		_starpu_sched_component_unlock_worker(worker);
 	}
-	return load;
 }
 
 static int combined_worker_push_task(struct starpu_sched_component * component, struct starpu_task *task)
@@ -683,64 +698,38 @@ static int combined_worker_push_task(struct starpu_sched_component * component,
 	return 0;
 }
 
-void _worker_component_deinit_data(struct starpu_sched_component * component)
+static double combined_worker_estimated_end(struct starpu_sched_component * component)
 {
-	struct _starpu_worker_component_data * d = component->data;
-	_starpu_worker_task_list_destroy(d->list);
-	if(starpu_sched_component_is_simple_worker(component))
-		STARPU_PTHREAD_MUTEX_DESTROY(&d->lock);
+	STARPU_ASSERT(starpu_sched_component_is_combined_worker(component));
+	struct _starpu_worker_component_data * data = component->data;
+	struct _starpu_combined_worker * combined_worker = data->combined_worker;
+	double max = 0.0;
 	int i;
-	for(i = 0; i < STARPU_NMAXWORKERS; i++)
-		if(_worker_components[i] == component)
-		{
-			_worker_components[i] = NULL;
-			return;
-		}
-	free(d);
+	for(i = 0; i < combined_worker->worker_size; i++)
+	{
+		data = _worker_components[combined_worker->combined_workerid[i]]->data;
+		STARPU_PTHREAD_MUTEX_LOCK(&data->list->mutex);
+		double tmp = data->list->exp_end;
+		STARPU_PTHREAD_MUTEX_UNLOCK(&data->list->mutex);
+		max = tmp > max ? tmp : max;
+	}
+	return max;
 }
 
-static struct starpu_sched_component * starpu_sched_component_worker_create(int workerid)
+static double combined_worker_estimated_load(struct starpu_sched_component * component)
 {
-	STARPU_ASSERT(0 <=  workerid && workerid < (int) starpu_worker_get_count());
-
-	if(_worker_components[workerid])
-		return _worker_components[workerid];
-
-	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
-	if(worker == NULL)
-		return NULL;
-	struct starpu_sched_component * component = starpu_sched_component_create();
-	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
-	memset(data, 0, sizeof(*data));
-
-	data->worker = worker;
-	STARPU_PTHREAD_MUTEX_INIT(&data->lock,NULL);
-	data->status = COMPONENT_STATUS_SLEEPING;
-	data->list = _starpu_worker_task_list_create();
-	component->data = data;
-
-	component->push_task = simple_worker_push_task;
-	component->pop_task = simple_worker_pop_task;
-	component->can_pull = simple_worker_can_pull;
-	component->estimated_end = simple_worker_estimated_end;
-	component->estimated_load = simple_worker_estimated_load;
-	component->deinit_data = _worker_component_deinit_data;
-	starpu_bitmap_set(component->workers, workerid);
-	starpu_bitmap_or(component->workers_in_ctx, component->workers);
-	_worker_components[workerid] = component;
-
-#ifdef STARPU_HAVE_HWLOC
-	struct _starpu_machine_config *config = _starpu_get_machine_config();
-	struct _starpu_machine_topology *topology = &config->topology;
-	hwloc_obj_t obj = hwloc_get_obj_by_depth(topology->hwtopology, config->cpu_depth, worker->bindid);
-	STARPU_ASSERT(obj);
-	component->obj = obj;
-#endif
-
-	return component;
+	struct _starpu_worker_component_data * d = component->data;
+	struct _starpu_combined_worker * c = d->combined_worker;
+	double load = 0;
+	int i;
+	for(i = 0; i < c->worker_size; i++)
+	{
+		struct starpu_sched_component * n = starpu_sched_component_worker_get(c->combined_workerid[i]);
+		load += n->estimated_load(n);
+	}
+	return load;
 }
 
-
 static struct starpu_sched_component  * starpu_sched_component_combined_worker_create(int workerid)
 {
 	STARPU_ASSERT(0 <= workerid && workerid <  STARPU_NMAXWORKERS);
@@ -778,43 +767,39 @@ static struct starpu_sched_component  * starpu_sched_component_combined_worker_c
 	return component;
 }
 
-int starpu_sched_component_is_simple_worker(struct starpu_sched_component * component)
-{
-	return component->push_task == simple_worker_push_task;
-}
-int starpu_sched_component_is_combined_worker(struct starpu_sched_component * component)
+
+
+/******************************************************************************
+ *			Worker Components' Public Helper Functions (Part 2)			      *
+ *****************************************************************************/
+
+
+
+void _starpu_sched_component_lock_all_workers(void)
 {
-	return component->push_task == combined_worker_push_task;
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count(); i++)
+		_starpu_sched_component_lock_worker(i);
 }
-
-int starpu_sched_component_is_worker(struct starpu_sched_component * component)
+void _starpu_sched_component_unlock_all_workers(void)
 {
-	return starpu_sched_component_is_simple_worker(component)
-		|| starpu_sched_component_is_combined_worker(component);
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count(); i++)
+		_starpu_sched_component_unlock_worker(i);
 }
 
-
-
-#ifndef STARPU_NO_ASSERT
-static int _worker_consistant(struct starpu_sched_component * component)
+void starpu_sched_component_worker_destroy(struct starpu_sched_component *component)
 {
-	int is_a_worker = 0;
+	struct _starpu_worker * worker = _starpu_sched_component_worker_get_worker(component);
+	unsigned id = worker->workerid;
+	assert(_worker_components[id] == component);
 	int i;
-	for(i = 0; i<STARPU_NMAXWORKERS; i++)
-		if(_worker_components[i] == component)
-			is_a_worker = 1;
-	if(!is_a_worker)
-		return 0;
-	struct _starpu_worker_component_data * data = component->data;
-	if(data->worker)
-	{
-		int id = data->worker->workerid;
-		return  (_worker_components[id] == component)
-			&&  component->nchildren == 0;
-	}
-	return 1;
+	for(i = 0; i < STARPU_NMAX_SCHED_CTXS ; i++)
+		if(component->parents[i] != NULL)
+			return;//this component is shared between several contexts
+	starpu_sched_component_destroy(component);
+	_worker_components[id] = NULL;
 }
-#endif
 
 int starpu_sched_component_worker_get_workerid(struct starpu_sched_component * worker_component)
 {
@@ -825,16 +810,6 @@ int starpu_sched_component_worker_get_workerid(struct starpu_sched_component * w
 	return starpu_bitmap_first(worker_component->workers);
 }
 
-
-static struct _starpu_worker_task_list * _worker_get_list(void)
-{
-	int workerid = starpu_worker_get_id();
-	STARPU_ASSERT(0 <= workerid && workerid < (int) starpu_worker_get_count());
-	struct _starpu_worker_component_data * d = starpu_sched_component_worker_get(workerid)->data;
-	return d->list;
-}
-
-
 void starpu_sched_component_worker_pre_exec_hook(struct starpu_task * task)
 {
 	if(!isnan(task->predicted))
@@ -854,6 +829,7 @@ void starpu_sched_component_worker_pre_exec_hook(struct starpu_task * task)
 		STARPU_PTHREAD_MUTEX_UNLOCK(&list->mutex);
 	}
 }
+
 void starpu_sched_component_worker_post_exec_hook(struct starpu_task * task)
 {
 	if(task->execute_on_a_specific_worker)
@@ -865,63 +841,37 @@ void starpu_sched_component_worker_post_exec_hook(struct starpu_task * task)
 	STARPU_PTHREAD_MUTEX_UNLOCK(&list->mutex);
 }
 
-
-#if 0
-static void starpu_sched_component_worker_push_task_notify(struct starpu_task * task, int workerid, unsigned sched_ctx_id STARPU_ATTRIBUTE_UNUSED)
+int starpu_sched_component_is_simple_worker(struct starpu_sched_component * component)
 {
+	return component->push_task == simple_worker_push_task;
+}
+int starpu_sched_component_is_combined_worker(struct starpu_sched_component * component)
+{
+	return component->push_task == combined_worker_push_task;
+}
 
-	struct starpu_sched_component * worker_component = starpu_sched_component_worker_get(workerid);
-	/* dont work with parallel tasks */
-	if(starpu_sched_component_is_combined_worker(worker_component))
-	   return;
-
-	struct _starpu_worker_component_data * d = worker_component->data;
-	struct _starpu_worker_task_list * list = d->list;
-	/* Compute the expected penality */
-	enum starpu_perfmodel_archtype perf_arch = starpu_worker_get_perf_archtype(workerid);
-	unsigned memory_node = starpu_worker_get_memory_node(workerid);
-
-	double predicted = starpu_task_expected_length(task, perf_arch,
-						       starpu_task_get_implementation(task));
-
-	double predicted_transfer = starpu_task_expected_data_transfer_time(memory_node, task);
-
-	/* Update the predictions */
-	STARPU_PTHREAD_MUTEX_LOCK(&list->mutex);
-	/* Sometimes workers didn't take the tasks as early as we expected */
-	list->exp_start = STARPU_MAX(list->exp_start, starpu_timing_now());
-	list->exp_end = list->exp_start + list->exp_len;
+int starpu_sched_component_is_worker(struct starpu_sched_component * component)
+{
+	return starpu_sched_component_is_simple_worker(component)
+		|| starpu_sched_component_is_combined_worker(component);
+}
 
-	/* If there is no prediction available, we consider the task has a null length */
-	if (!isnan(predicted_transfer))
+/* As Worker Components' creating functions are protected, this function allows
+ * the user to get a Worker Component from a worker id */
+struct starpu_sched_component * starpu_sched_component_worker_get(int workerid)
+{
+	STARPU_ASSERT(workerid >= 0 && workerid < STARPU_NMAXWORKERS);
+	/* we may need to take a mutex here */
+	if(_worker_components[workerid])
+		return _worker_components[workerid];
+	else
 	{
-		if (starpu_timing_now() + predicted_transfer < list->exp_end)
-		{
-			/* We may hope that the transfer will be finshied by
-			 * the start of the task. */
-			predicted_transfer = 0;
-		}
+		struct starpu_sched_component * component;
+		if(workerid < (int) starpu_worker_get_count())
+			component = starpu_sched_component_worker_create(workerid);
 		else
-		{
-			/* The transfer will not be finished by then, take the
-			 * remainder into account */
-			predicted_transfer = (starpu_timing_now() + predicted_transfer) - list->exp_end;
-		}
-		task->predicted_transfer = predicted_transfer;
-		list->exp_end += predicted_transfer;
-		list->exp_len += predicted_transfer;
-	}
-
-	/* If there is no prediction available, we consider the task has a null length */
-	if (!isnan(predicted))
-	{
-		task->predicted = predicted;
-		list->exp_end += predicted;
-		list->exp_len += predicted;
+			component = starpu_sched_component_combined_worker_create(workerid);
+		_worker_components[workerid] = component;
+		return component;
 	}
-
-	list->ntasks++;
-
-	STARPU_PTHREAD_MUTEX_UNLOCK(&list->mutex);
 }
-#endif

+ 74 - 74
src/sched_policies/helper_mct.c

@@ -19,80 +19,6 @@
 #include <starpu_sched_component.h>
 #include "helper_mct.h"
 
-/* compute predicted_end by taking into account the case of the predicted transfer and the predicted_end overlap
- */
-static double compute_expected_time(double now, double predicted_end, double predicted_length, double predicted_transfer)
-{
-	STARPU_ASSERT(!isnan(now + predicted_end + predicted_length + predicted_transfer));
-	STARPU_ASSERT(now >= 0.0 && predicted_end >= 0.0 && predicted_length >= 0.0 && predicted_transfer >= 0.0);
-
-	/* TODO: actually schedule transfers */
-	if (now + predicted_transfer < predicted_end)
-	{
-		/* We may hope that the transfer will be finished by
-		 * the start of the task. */
-		predicted_transfer = 0;
-	}
-	else
-	{
-		/* The transfer will not be finished by then, take the
-		 * remainder into account */
-		predicted_transfer -= (predicted_end - now);
-	}
-
-	predicted_end += predicted_transfer;
-	predicted_end += predicted_length;
-
-	return predicted_end;
-}
-
-double starpu_mct_compute_fitness(struct _starpu_mct_data * d, double exp_end, double min_exp_end, double max_exp_end, double transfer_len, double local_power)
-{
-	/* Note: the expected end includes the data transfer duration, which we want to be able to tune separately */
-
-	return d->alpha * (exp_end - min_exp_end)
-		+ d->beta * transfer_len
-		+ d->gamma * local_power
-		+ d->gamma * d->idle_power * (exp_end - max_exp_end);
-}
-
-int starpu_mct_compute_expected_times(struct starpu_sched_component *component, struct starpu_task *task,
-		double *estimated_lengths, double *estimated_transfer_length, double *estimated_ends_with_task,
-		double *min_exp_end_with_task, double *max_exp_end_with_task, int *suitable_components)
-{
-	int nsuitable_components = 0;
-
-	int i;
-	for(i = 0; i < component->nchildren; i++)
-	{
-		struct starpu_sched_component * c = component->children[i];
-		if(starpu_sched_component_execute_preds(c, task, estimated_lengths + i))
-		{
-			if(isnan(estimated_lengths[i]))
-				/* The perfmodel had been purged since the task was pushed
-				 * onto the mct component. */
-				continue;
-
-			/* Estimated availability of worker */
-			double estimated_end = c->estimated_end(c);
-			double now = starpu_timing_now();
-			if (estimated_end < now)
-				estimated_end = now;
-			estimated_transfer_length[i] = starpu_sched_component_transfer_length(c, task);
-			estimated_ends_with_task[i] = compute_expected_time(now,
-									    estimated_end,
-									    estimated_lengths[i],
-									    estimated_transfer_length[i]);
-			if(estimated_ends_with_task[i] < *min_exp_end_with_task)
-				*min_exp_end_with_task = estimated_ends_with_task[i];
-			if(estimated_ends_with_task[i] > *max_exp_end_with_task)
-				*max_exp_end_with_task = estimated_ends_with_task[i];
-			suitable_components[nsuitable_components++] = i;
-		}
-	}
-	return nsuitable_components;
-}
-
 /* Alpha, Beta and Gamma are MCT-specific values, which allows the
  * user to set more precisely the weight of each computing value.
  * Beta, for example, controls the weight of communications between
@@ -174,3 +100,77 @@ struct _starpu_mct_data *starpu_mct_init_parameters(struct starpu_mct_data *para
 
 	return data;
 }
+
+/* compute predicted_end by taking into account the case of the predicted transfer and the predicted_end overlap
+ */
+static double compute_expected_time(double now, double predicted_end, double predicted_length, double predicted_transfer)
+{
+	STARPU_ASSERT(!isnan(now + predicted_end + predicted_length + predicted_transfer));
+	STARPU_ASSERT(now >= 0.0 && predicted_end >= 0.0 && predicted_length >= 0.0 && predicted_transfer >= 0.0);
+
+	/* TODO: actually schedule transfers */
+	if (now + predicted_transfer < predicted_end)
+	{
+		/* We may hope that the transfer will be finished by
+		 * the start of the task. */
+		predicted_transfer = 0;
+	}
+	else
+	{
+		/* The transfer will not be finished by then, take the
+		 * remainder into account */
+		predicted_transfer -= (predicted_end - now);
+	}
+
+	predicted_end += predicted_transfer;
+	predicted_end += predicted_length;
+
+	return predicted_end;
+}
+
+double starpu_mct_compute_fitness(struct _starpu_mct_data * d, double exp_end, double min_exp_end, double max_exp_end, double transfer_len, double local_power)
+{
+	/* Note: the expected end includes the data transfer duration, which we want to be able to tune separately */
+
+	return d->alpha * (exp_end - min_exp_end)
+		+ d->beta * transfer_len
+		+ d->gamma * local_power
+		+ d->gamma * d->idle_power * (exp_end - max_exp_end);
+}
+
+int starpu_mct_compute_expected_times(struct starpu_sched_component *component, struct starpu_task *task,
+		double *estimated_lengths, double *estimated_transfer_length, double *estimated_ends_with_task,
+		double *min_exp_end_with_task, double *max_exp_end_with_task, int *suitable_components)
+{
+	int nsuitable_components = 0;
+
+	int i;
+	for(i = 0; i < component->nchildren; i++)
+	{
+		struct starpu_sched_component * c = component->children[i];
+		if(starpu_sched_component_execute_preds(c, task, estimated_lengths + i))
+		{
+			if(isnan(estimated_lengths[i]))
+				/* The perfmodel had been purged since the task was pushed
+				 * onto the mct component. */
+				continue;
+
+			/* Estimated availability of worker */
+			double estimated_end = c->estimated_end(c);
+			double now = starpu_timing_now();
+			if (estimated_end < now)
+				estimated_end = now;
+			estimated_transfer_length[i] = starpu_sched_component_transfer_length(c, task);
+			estimated_ends_with_task[i] = compute_expected_time(now,
+									    estimated_end,
+									    estimated_lengths[i],
+									    estimated_transfer_length[i]);
+			if(estimated_ends_with_task[i] < *min_exp_end_with_task)
+				*min_exp_end_with_task = estimated_ends_with_task[i];
+			if(estimated_ends_with_task[i] > *max_exp_end_with_task)
+				*max_exp_end_with_task = estimated_ends_with_task[i];
+			suitable_components[nsuitable_components++] = i;
+		}
+	}
+	return nsuitable_components;
+}

+ 2 - 0
src/sched_policies/helper_mct.h

@@ -23,7 +23,9 @@ struct _starpu_mct_data
 };
 
 struct _starpu_mct_data *starpu_mct_init_parameters(struct starpu_mct_data *params);
+
 int starpu_mct_compute_expected_times(struct starpu_sched_component *component, struct starpu_task *task,
 		double *estimated_lengths, double *estimated_transfer_length, double *estimated_ends_with_task,
 		double *min_exp_end_with_task, double *max_exp_end_with_task, int *suitable_components);
+
 double starpu_mct_compute_fitness(struct _starpu_mct_data * d, double exp_end, double min_exp_end, double max_exp_end, double transfer_len, double local_power);

+ 4 - 3
src/sched_policies/sched_component.h

@@ -25,13 +25,14 @@ void _starpu_sched_component_lock_all_workers(void);
 void _starpu_sched_component_unlock_all_workers(void);
 void _starpu_sched_component_lock_worker(int workerid);
 void _starpu_sched_component_unlock_worker(int workerid);
-void _starpu_sched_component_lock_scheduling(void);
-void _starpu_sched_component_unlock_scheduling(void);
-
 
 struct _starpu_worker * _starpu_sched_component_worker_get_worker(struct starpu_sched_component *);
 struct _starpu_combined_worker * _starpu_sched_component_combined_worker_get_combined_worker(struct starpu_sched_component * worker_component);
 
 struct starpu_bitmap * _starpu_get_worker_mask(unsigned sched_ctx_id);
 
+
+void _starpu_sched_component_lock_scheduling(void);
+void _starpu_sched_component_unlock_scheduling(void);
+
 #endif