Andra Hugo 13 lat temu
rodzic
commit
ebfb583c37

+ 2 - 0
sched_ctx_hypervisor/examples/cholesky/cholesky_implicit.c

@@ -331,10 +331,12 @@ int main(int argc, char **argv)
 		execute_cholesky(mat, size, nblocks);
 	}
 
+
 	starpu_helper_cublas_shutdown();
 	starpu_shutdown();
 
 	if(with_ctxs)
 		end_contexts();
+
 	return 0;
 }

+ 167 - 88
sched_ctx_hypervisor/examples/sched_ctx_utils/sched_ctx_utils.c

@@ -17,8 +17,8 @@ typedef struct {
 	unsigned id;
 	unsigned ctx;
 	int the_other_ctx;
-	int *procs;
-	int nprocs;
+	int *workers;
+	int nworkers;
 	void (*bench)(float*, unsigned, unsigned);
 	unsigned size;
 	unsigned nblocks;
@@ -35,6 +35,7 @@ pthread_mutex_t mut;
 retvals rv[2];
 params p1, p2;
 int it = 0;
+int it2 = 0;
 
 struct sched_ctx_hypervisor_reply reply1[NSAMPLES*2*2];
 struct sched_ctx_hypervisor_reply reply2[NSAMPLES*2*2];
@@ -85,17 +86,6 @@ void* start_bench(void *val){
 	for(i = 0; i < NSAMPLES; i++)
 		p->bench(p->mat[i], p->size, p->nblocks);
 	
-	/* if(p->ctx != 0) */
-	/* { */
-	/* 	pthread_mutex_lock(&mut); */
-	/* 	if(first){ */
-	/* 		sched_ctx_hypervisor_ignore_ctx(p->ctx); */
-	/* 		starpu_delete_sched_ctx(p->ctx, p->the_other_ctx); */
-	/* 	} */
-		
-	/* 	first = 0; */
-	/* 	pthread_mutex_unlock(&mut); */
-	/* } */
 	sched_ctx_hypervisor_stop_resize(p->the_other_ctx);
 	rv[p->id].flops /= NSAMPLES;
 	rv[p->id].avg_timing /= NSAMPLES;
@@ -222,136 +212,225 @@ void start_2ndbench(void (*bench)(float*, unsigned, unsigned))
 void construct_contexts(void (*bench)(float*, unsigned, unsigned))
 {
 	struct starpu_sched_ctx_hypervisor_criteria *criteria = sched_ctx_hypervisor_init(SIMPLE_POLICY);
-	int nprocs1 = cpu1 + gpu + gpu1;
-	int nprocs2 = cpu2 + gpu + gpu2;
+	int nworkers1 = cpu1 + gpu + gpu1;
+	int nworkers2 = cpu2 + gpu + gpu2;
 	unsigned n_all_gpus = gpu + gpu1 + gpu2;
 
 
 	int i;
 	int k = 0;
+	nworkers1 = 12;
+	p1.workers = (int*)malloc(nworkers1*sizeof(int));
 
-	p1.procs = (int*)malloc(nprocs1*sizeof(int));
+	/* for(i = 0; i < gpu; i++) */
+	/* 	p1.workers[k++] = i; */
 
-	for(i = 0; i < gpu; i++)
-		p1.procs[k++] = i;
+	/* for(i = gpu; i < gpu + gpu1; i++) */
+	/* 	p1.workers[k++] = i; */
 
-	for(i = gpu; i < gpu + gpu1; i++)
-		p1.procs[k++] = i;
 
+	/* for(i = n_all_gpus; i < n_all_gpus + cpu1; i++) */
+	/* 	p1.workers[k++] = i; */
 
-	for(i = n_all_gpus; i < n_all_gpus + cpu1; i++)
-		p1.procs[k++] = i;
 
+	for(i = 0; i < 12; i++)
+		p1.workers[i] = i; 
 
-	p1.ctx = starpu_create_sched_ctx_with_criteria("heft", p1.procs, nprocs1, "sched_ctx1", criteria);
+	p1.ctx = starpu_create_sched_ctx_with_criteria("heft", p1.workers, nworkers1, "sched_ctx1", criteria);
 	p2.the_other_ctx = (int)p1.ctx;
-	p1.nprocs = nprocs1;
+	p1.nworkers = nworkers1;
 	sched_ctx_hypervisor_handle_ctx(p1.ctx);
 	
+	/* sched_ctx_hypervisor_ioctl(p1.ctx, */
+	/* 			   HYPERVISOR_MAX_IDLE, p1.workers, p1.nworkers, 5000.0, */
+	/* 			   HYPERVISOR_MAX_IDLE, p1.workers, gpu+gpu1, 100000.0, */
+	/* 			   HYPERVISOR_EMPTY_CTX_MAX_IDLE, p1.workers, p1.nworkers, 500000.0, */
+	/* 			   HYPERVISOR_GRANULARITY, 2, */
+	/* 			   HYPERVISOR_MIN_TASKS, 1000, */
+	/* 			   HYPERVISOR_NEW_WORKERS_MAX_IDLE, 100000.0, */
+	/* 			   HYPERVISOR_MIN_WORKERS, 6, */
+	/* 			   HYPERVISOR_MAX_WORKERS, 12, */
+	/* 			   NULL); */
+
 	sched_ctx_hypervisor_ioctl(p1.ctx,
-				   HYPERVISOR_MAX_IDLE, p1.procs, p1.nprocs, 5000.0,
-				   HYPERVISOR_MAX_IDLE, p1.procs, gpu+gpu1, 100000.0,
-				   HYPERVISOR_GRANULARITY, 4,
+				   HYPERVISOR_GRANULARITY, 2,
 				   HYPERVISOR_MIN_TASKS, 1000,
-				   HYPERVISOR_NEW_WORKERS_MAX_IDLE, 100000.0,
+				   HYPERVISOR_MIN_WORKERS, 12,
+				   HYPERVISOR_MAX_WORKERS, 12,
 				   NULL);
 
 	k = 0;
-	p2.procs = (int*)malloc(nprocs2*sizeof(int));
+	p2.workers = (int*)malloc(nworkers2*sizeof(int));
 
-	for(i = 0; i < gpu; i++)
-		p2.procs[k++] = i;
+	/* for(i = 0; i < gpu; i++) */
+	/* 	p2.workers[k++] = i; */
 
-	for(i = gpu + gpu1; i < gpu + gpu1 + gpu2; i++)
-		p2.procs[k++] = i;
+	/* for(i = gpu + gpu1; i < gpu + gpu1 + gpu2; i++) */
+	/* 	p2.workers[k++] = i; */
 
-	for(i = n_all_gpus  + cpu1; i < n_all_gpus + cpu1 + cpu2; i++)
-		p2.procs[k++] = i;
+	/* for(i = n_all_gpus  + cpu1; i < n_all_gpus + cpu1 + cpu2; i++) */
+	/* 	p2.workers[k++] = i; */
 
-	p2.ctx = starpu_create_sched_ctx_with_criteria("heft", p2.procs, nprocs2, "sched_ctx2", criteria);
+	p2.ctx = starpu_create_sched_ctx_with_criteria("heft", p2.workers, 0, "sched_ctx2", criteria);
 	p1.the_other_ctx = (int)p2.ctx;
-	p2.nprocs = nprocs2;
+	p2.nworkers = 0;
 	sched_ctx_hypervisor_handle_ctx(p2.ctx);
 	
+	/* sched_ctx_hypervisor_ioctl(p2.ctx, */
+	/* 			   HYPERVISOR_MAX_IDLE, p2.workers, p2.nworkers, 2000.0, */
+	/* 			   HYPERVISOR_MAX_IDLE, p2.workers, gpu+gpu2, 5000.0, */
+	/* 			   HYPERVISOR_EMPTY_CTX_MAX_IDLE, p1.workers, p1.nworkers, 500000.0, */
+	/* 			   HYPERVISOR_GRANULARITY, 2, */
+	/* 			   HYPERVISOR_MIN_TASKS, 500, */
+	/* 			   HYPERVISOR_NEW_WORKERS_MAX_IDLE, 1000.0, */
+	/* 			   HYPERVISOR_MIN_WORKERS, 4, */
+	/* 			   HYPERVISOR_MAX_WORKERS, 8, */
+	/* 			   NULL); */
+
 	sched_ctx_hypervisor_ioctl(p2.ctx,
-				   HYPERVISOR_MAX_IDLE, p2.procs, p2.nprocs, 2000.0,
-				   HYPERVISOR_MAX_IDLE, p2.procs, gpu+gpu2, 5000.0,
-				   HYPERVISOR_GRANULARITY, 4,
+				   HYPERVISOR_GRANULARITY, 2,
 				   HYPERVISOR_MIN_TASKS, 500,
-				   HYPERVISOR_NEW_WORKERS_MAX_IDLE, 1000.0,
+				   HYPERVISOR_MIN_WORKERS, 0,
+				   HYPERVISOR_MAX_WORKERS, 0,
 				   NULL);
+
 }
 
 void set_hypervisor_conf(int event, int task_tag)
 {
 	unsigned *id = pthread_getspecific(key);
-
-	if(*id == 1)
+	if(*id == 0)
 	{
-		if(event == START_BENCH)
-		{
-			int procs[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-			sched_ctx_hypervisor_ioctl(p1.ctx,
-						   HYPERVISOR_MAX_IDLE, procs, 12, 500.0,
-						   HYPERVISOR_MAX_IDLE, procs, 3, 100.0,
-						   HYPERVISOR_TIME_TO_APPLY, task_tag,
-						   NULL);
-		}
-		else
-		{
-			/* int procs[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
-			/* sched_ctx_hypervisor_ioctl(p2.ctx, */
-			/* 			   HYPERVISOR_MAX_IDLE, procs, 12, 800.0, */
-			/* 			   HYPERVISOR_MAX_IDLE, procs, 3, 100.0, */
-			/* 			   HYPERVISOR_TIME_TO_APPLY, task_tag, */
-			/* 			   NULL); */
-		}
-		
-	} else {
-		if(event == START_BENCH)
-		{
-			int procs[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-			sched_ctx_hypervisor_ioctl(p1.ctx,
-						   HYPERVISOR_MAX_IDLE, procs, 12, 500.0,
-//						   HYPERVISOR_MAX_IDLE, procs, 3, 1000.0,
-						   HYPERVISOR_TIME_TO_APPLY, task_tag,
-						   HYPERVISOR_GRANULARITY, 2,
-						   NULL);
-		}
 		if(event == END_BENCH)
 		{
-			if(it < 3)
+			if(it < 2)
 			{
-				int procs[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+				sched_ctx_hypervisor_ioctl(p2.ctx,
+							   HYPERVISOR_MIN_WORKERS, 2,
+							   HYPERVISOR_MAX_WORKERS, 4,
+							   HYPERVISOR_TIME_TO_APPLY, task_tag,
+							   NULL);
+
 				sched_ctx_hypervisor_ioctl(p1.ctx,
-							   HYPERVISOR_MAX_IDLE, procs, 12, 300.0,
-							   HYPERVISOR_MAX_IDLE, procs, 3, 800.0,
+							   HYPERVISOR_MIN_WORKERS, 6,
+							   HYPERVISOR_MAX_WORKERS, 8,
 							   HYPERVISOR_TIME_TO_APPLY, task_tag,
-							   HYPERVISOR_GRANULARITY, 4,
 							   NULL);
+				sched_ctx_hypervisor_resize(p1.ctx, task_tag);
 			}
-			if(it == 4)
+			if(it == 2)
 			{
-				int procs[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-				sched_ctx_hypervisor_ioctl(p1.ctx,
-							   HYPERVISOR_MAX_IDLE, procs, 12, 200.0,
-							   HYPERVISOR_MAX_IDLE, procs, 3, 10000.0,
+				sched_ctx_hypervisor_ioctl(p2.ctx,
+							   HYPERVISOR_MIN_WORKERS, 10,
+							   HYPERVISOR_MAX_WORKERS, 12,
 							   HYPERVISOR_TIME_TO_APPLY, task_tag,
-							   HYPERVISOR_GRANULARITY, 2,
 							   NULL);
 
+				sched_ctx_hypervisor_ioctl(p1.ctx,
+							   HYPERVISOR_MIN_WORKERS, 0,
+							   HYPERVISOR_MAX_WORKERS, 0,
+							   HYPERVISOR_TIME_TO_APPLY, task_tag,
+							   NULL);
+				sched_ctx_hypervisor_resize(p1.ctx, task_tag);
 			}
-			
 			it++;
+				
 		}
-
 	}
+	else
+	{
+		if(event == END_BENCH)
+		{
+			sched_ctx_hypervisor_ioctl(p1.ctx,
+						   HYPERVISOR_MIN_WORKERS, 10,
+						   HYPERVISOR_MAX_WORKERS, 12,
+						   HYPERVISOR_TIME_TO_APPLY, task_tag,
+						   NULL);
+			
+			sched_ctx_hypervisor_ioctl(p2.ctx,
+						   HYPERVISOR_MIN_WORKERS, 0,
+						   HYPERVISOR_MAX_WORKERS, 0,
+						   HYPERVISOR_TIME_TO_APPLY, task_tag,
+						   NULL);
+			sched_ctx_hypervisor_resize(p2.ctx, task_tag);
+		}
+	}
+
+	/* if(*id == 1) */
+	/* { */
+	/* 	if(event == START_BENCH) */
+	/* 	{ */
+	/* 		int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 		sched_ctx_hypervisor_ioctl(p1.ctx, */
+	/* 					   HYPERVISOR_MAX_IDLE, workers, 12, 800000.0, */
+	/* 					   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 					   NULL); */
+	/* 	} */
+	/* 	else */
+	/* 	{ */
+	/* 		if(it2 < 2) */
+	/* 		{ */
+	/* 			int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 			sched_ctx_hypervisor_ioctl(p2.ctx, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 12, 500.0, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 3, 200.0, */
+	/* 						   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 						   NULL); */
+	/* 		} */
+	/* 		if(it2 == 2) */
+	/* 		{ */
+	/* 			int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 			sched_ctx_hypervisor_ioctl(p2.ctx, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 12, 1000.0, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 3, 500.0, */
+	/* 						   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 						   HYPERVISOR_MAX_WORKERS, 12, */
+	/* 						   NULL); */
+	/* 		} */
+	/* 		it2++; */
+	/* 	} */
+		
+	/* } else { */
+	/* 	if(event == START_BENCH) */
+	/* 	{ */
+	/* 		int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 		sched_ctx_hypervisor_ioctl(p1.ctx, */
+	/* 					   HYPERVISOR_MAX_IDLE, workers, 12, 1500.0, */
+	/* 					   HYPERVISOR_MAX_IDLE, workers, 3, 4000.0, */
+	/* 					   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 					   NULL); */
+	/* 	} */
+	/* 	if(event == END_BENCH) */
+	/* 	{ */
+	/* 		if(it < 2) */
+	/* 		{ */
+	/* 			int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 			sched_ctx_hypervisor_ioctl(p1.ctx, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 12, 100.0, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 3, 5000.0, */
+	/* 						   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 						   NULL); */
+	/* 		} */
+	/* 		if(it == 2) */
+	/* 		{ */
+	/* 			int workers[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; */
+	/* 			sched_ctx_hypervisor_ioctl(p1.ctx, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 12, 5000.0, */
+	/* 						   HYPERVISOR_MAX_IDLE, workers, 3, 10000.0, */
+	/* 						   HYPERVISOR_TIME_TO_APPLY, task_tag, */
+	/* 						   NULL); */
+	/* 		} */
+			
+	/* 		it++; */
+	/* 	} */
+
+	/* } */
 }
 
 void end_contexts()
 {
-	free(p1.procs);
-	free(p2.procs);
+	free(p1.workers);
+	free(p2.workers);
 	sched_ctx_hypervisor_shutdown();
 }
 

+ 17 - 15
sched_ctx_hypervisor/include/sched_ctx_hypervisor.h

@@ -4,16 +4,17 @@
 #include <pthread.h>
 
 /* ioctl properties*/
-#define HYPERVISOR_MAX_IDLE (1<<1)
-#define HYPERVISOR_MIN_WORKING (1<<2)
-#define HYPERVISOR_PRIORITY (1<<3)
-#define HYPERVISOR_MIN_PROCS (1<<4)
-#define HYPERVISOR_MAX_PROCS (1<<5)
-#define HYPERVISOR_GRANULARITY (1<<6)
-#define HYPERVISOR_FIXED_PROCS (1<<7)
-#define HYPERVISOR_MIN_TASKS (1<<8)
-#define HYPERVISOR_NEW_WORKERS_MAX_IDLE (1<<9)
-#define HYPERVISOR_TIME_TO_APPLY (1<<10)
+#define HYPERVISOR_MAX_IDLE -1
+#define HYPERVISOR_MIN_WORKING -2
+#define HYPERVISOR_PRIORITY -3
+#define HYPERVISOR_MIN_WORKERS -4
+#define HYPERVISOR_MAX_WORKERS -5
+#define HYPERVISOR_GRANULARITY -6
+#define HYPERVISOR_FIXED_WORKERS -7
+#define HYPERVISOR_MIN_TASKS -8
+#define HYPERVISOR_NEW_WORKERS_MAX_IDLE -9
+#define HYPERVISOR_TIME_TO_APPLY -10
+#define HYPERVISOR_EMPTY_CTX_MAX_IDLE -11
 
 struct sched_ctx_hypervisor_reply{
 	int procs[STARPU_NMAXWORKERS];
@@ -29,7 +30,9 @@ void sched_ctx_hypervisor_handle_ctx(unsigned sched_ctx);
 
 void sched_ctx_hypervisor_ignore_ctx(unsigned sched_ctx);
 
-void sched_ctx_hypervisor_resize(unsigned sender_sched_ctx, unsigned receier_sched_ctx, int *workers_to_move, unsigned nworkers_to_movex);
+unsigned sched_ctx_hypervisor_resize(unsigned sched_ctx, int task_tag);
+
+void sched_ctx_hypervisor_move_workers(unsigned sender_sched_ctx, unsigned receier_sched_ctx, int *workers_to_move, unsigned nworkers_to_movex);
 
 void sched_ctx_hypervisor_stop_resize(unsigned sched_ctx);
 
@@ -41,9 +44,7 @@ void* sched_ctx_hypervisor_get_config(unsigned sched_ctx);
 
 void sched_ctx_hypervisor_ioctl(unsigned sched_ctx, ...);
 
-void sched_ctx_hypervisor_advise(unsigned sched_ctx, int *workers, int nworkers, int task_tag);
-
-void sched_ctx_hypervisor_request(unsigned sched_ctx, int *workers, int nworkers, int task_tag);
+void sched_ctx_hypervisor_steal_workers(unsigned sched_ctx, int *workers, int nworkers, int task_tag);
 
 /* hypervisor policies */
 #define SIMPLE_POLICY 1
@@ -54,6 +55,7 @@ struct hypervisor_policy {
 	void (*add_sched_ctx)(unsigned sched_ctx);
 	void(*remove_sched_ctx)(unsigned sched_ctx);
 	void* (*ioctl)(unsigned sched_ctx, va_list varg_list, unsigned later);
-	unsigned (*manage_idle_time)(unsigned req_sched_ctx, int *sched_ctxs, unsigned nsched_ctxs, int worker, double idle_time);
+	void (*manage_idle_time)(unsigned req_sched_ctx, int *sched_ctxs, unsigned nsched_ctxs, int worker, double idle_time);
+	unsigned (*resize)(unsigned sched_ctx, int *sched_ctxs, unsigned nsched_ctxs);
 	void (*update_config)(void* old_config, void* new_config);
 };

+ 154 - 86
sched_ctx_hypervisor/src/hypervisor_policies/simple_policy.c

@@ -6,13 +6,13 @@
 
 struct simple_policy_config {
 	/* underneath this limit we cannot resize */
-	unsigned min_nprocs;
+	int min_nworkers;
 
 	/* above this limit we cannot resize */
-	unsigned max_nprocs;
+	int max_nworkers;
 	
 	/*resize granularity */
-	unsigned granularity;
+	int granularity;
 
 	/* priority for a worker to stay in this context */
 	/* the smaller the priority the faster it will be moved */
@@ -26,27 +26,31 @@ struct simple_policy_config {
 	double min_working[STARPU_NMAXWORKERS];
 
 	/* workers that will not move */
-	unsigned fixed_procs[STARPU_NMAXWORKERS];
+	int fixed_workers[STARPU_NMAXWORKERS];
 
 	/* max idle for the workers that will be added during the resizing process*/
 	double new_workers_max_idle;
+
+	/* above this context we allow removing all workers */
+	double empty_ctx_max_idle[STARPU_NMAXWORKERS];
 };
 
 static struct simple_policy_config* _create_config(void)
 {
 	struct simple_policy_config *config = (struct simple_policy_config *)malloc(sizeof(struct simple_policy_config));
-	config->min_nprocs = 0;
-	config->max_nprocs = 0;	
-	config->new_workers_max_idle = MAX_IDLE_TIME;
+	config->min_nworkers = -1;
+	config->max_nworkers = -1;	
+	config->new_workers_max_idle = -1.0;
 
 	int i;
 	for(i = 0; i < STARPU_NMAXWORKERS; i++)
 	{
-		config->granularity = 1;
-		config->priority[i] = 0;
-		config->fixed_procs[i] = 0;
-		config->max_idle[i] = MAX_IDLE_TIME;
-		config->min_working[i] = MIN_WORKING_TIME;
+		config->granularity = -1;
+		config->priority[i] = -1;
+		config->fixed_workers[i] = -1;
+		config->max_idle[i] = -1.0;
+		config->empty_ctx_max_idle[i] = -1.0;
+		config->min_working[i] = -1.0;
 	}
 	
 	return config;
@@ -55,6 +59,21 @@ static struct simple_policy_config* _create_config(void)
 static void simple_add_sched_ctx(unsigned sched_ctx)
 {
 	struct simple_policy_config *config = _create_config();
+	config->min_nworkers = 0;
+	config->max_nworkers = 0;	
+	config->new_workers_max_idle = MAX_IDLE_TIME;
+
+	int i;
+	for(i = 0; i < STARPU_NMAXWORKERS; i++)
+	{
+		config->granularity = 1;
+		config->priority[i] = 0;
+		config->fixed_workers[i] = 0;
+		config->max_idle[i] = MAX_IDLE_TIME;
+		config->empty_ctx_max_idle[i] = MAX_IDLE_TIME;
+		config->min_working[i] = MIN_WORKING_TIME;
+	}
+
 	sched_ctx_hypervisor_set_config(sched_ctx, config);
 }
 
@@ -81,22 +100,29 @@ static int _compute_priority(unsigned sched_ctx)
 	return total_priority;
 }
 
-static unsigned _get_highest_priority_sched_ctx(unsigned req_sched_ctx, int *sched_ctxs, int nsched_ctxs)
+static unsigned _find_poor_sched_ctx(unsigned req_sched_ctx, int *sched_ctxs, int nsched_ctxs, int nworkers_to_move)
 {
 	int i;
 	int highest_priority = -1;
 	int current_priority = 0;
 	unsigned sched_ctx = STARPU_NMAX_SCHED_CTXS;
 
+	struct simple_policy_config *config = NULL;
+
 	for(i = 0; i < nsched_ctxs; i++)
 	{
 		if(sched_ctxs[i] != STARPU_NMAX_SCHED_CTXS && sched_ctxs[i] != req_sched_ctx)
 		{
-			current_priority = _compute_priority(sched_ctxs[i]);
-			if (highest_priority < current_priority)
+			unsigned nworkers = starpu_get_nworkers_of_sched_ctx(sched_ctxs[i]);
+			config  = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctxs[i]);
+			if((nworkers + nworkers_to_move) <= config->max_nworkers)
 			{
-				highest_priority = current_priority;
-				sched_ctx = sched_ctxs[i];
+				current_priority = _compute_priority(sched_ctxs[i]);
+				if (highest_priority < current_priority)
+				{
+					highest_priority = current_priority;
+					sched_ctx = sched_ctxs[i];
+				}
 			}
 		}
 	}
@@ -104,13 +130,13 @@ static unsigned _get_highest_priority_sched_ctx(unsigned req_sched_ctx, int *sch
 	return sched_ctx;
 }
 
-int* _get_first_workers(unsigned sched_ctx, int nworkers)
+int* _get_first_workers(unsigned sched_ctx, int *nworkers)
 {
 	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctx);
 
-	int *curr_workers = (int*)malloc(nworkers * sizeof(int));
+	int *curr_workers = (int*)malloc((*nworkers) * sizeof(int));
 	int i;
-	for(i = 0; i < nworkers; i++)
+	for(i = 0; i < *nworkers; i++)
 		curr_workers[i] = -1;
 
 	struct worker_collection *workers = starpu_get_worker_collection_of_sched_ctx(sched_ctx);
@@ -121,13 +147,13 @@ int* _get_first_workers(unsigned sched_ctx, int nworkers)
 	if(workers->init_cursor)
 		workers->init_cursor(workers);
 
-	for(index = 0; index < nworkers; index++)
+	for(index = 0; index < *nworkers; index++)
 	{
 		while(workers->has_next(workers))
 		{
 			considered = 0;
 			worker = workers->get_next(workers);
-			if(!config->fixed_procs[worker])
+			if(!config->fixed_workers[worker])
 			{
 				for(i = 0; i < index; i++)
 				{
@@ -146,7 +172,10 @@ int* _get_first_workers(unsigned sched_ctx, int nworkers)
 		}
 
 		if(curr_workers[index] < 0)
+		{
+			*nworkers = index;
 			break;
+		}
 	}
 
 	if(workers->init_cursor)
@@ -155,11 +184,11 @@ int* _get_first_workers(unsigned sched_ctx, int nworkers)
 	return curr_workers;
 }
 
-static int _get_potential_nworkers(struct simple_policy_config *config, unsigned sched_ctx)
+static unsigned _get_potential_nworkers(struct simple_policy_config *config, unsigned sched_ctx)
 {
 	struct worker_collection *workers = starpu_get_worker_collection_of_sched_ctx(sched_ctx);
 
-	int potential_workers = 0;
+	unsigned potential_workers = 0;
 	int worker;
 
 	if(workers->init_cursor)
@@ -167,7 +196,7 @@ static int _get_potential_nworkers(struct simple_policy_config *config, unsigned
 	while(workers->has_next(workers))
 	{
 		worker = workers->get_next(workers);
-		if(!config->fixed_procs[worker])
+		if(!config->fixed_workers[worker])
 			potential_workers++;
 	}
 	if(workers->init_cursor)
@@ -176,59 +205,86 @@ static int _get_potential_nworkers(struct simple_policy_config *config, unsigned
 	return potential_workers;
 }
 
-static unsigned simple_manage_idle_time(unsigned req_sched_ctx, int *sched_ctxs, int nsched_ctxs, int worker, double idle_time)
+static unsigned _get_nworkers_to_move(unsigned req_sched_ctx)
 {
        	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(req_sched_ctx);
-
-	if(config != NULL && idle_time > config->max_idle[worker])
+	unsigned nworkers = starpu_get_nworkers_of_sched_ctx(req_sched_ctx);
+	unsigned nworkers_to_move = 0;
+	
+	unsigned potential_moving_workers = _get_potential_nworkers(config, req_sched_ctx);
+	if(potential_moving_workers > 0)
 	{
-		int ret = pthread_mutex_trylock(&act_hypervisor_mutex);
-		if(ret != EBUSY)
-		{					
+		if(potential_moving_workers <= config->min_nworkers)
+			/* if we have to give more than min better give it all */ 
+			/* => empty ctx will block until having the required workers */
 			
-			unsigned nworkers = starpu_get_nworkers_of_sched_ctx(req_sched_ctx);
-			unsigned nworkers_to_move = 0;
-			
-			/* leave at least one */
-			int potential_moving_workers = _get_potential_nworkers(config, req_sched_ctx);
-			if(potential_moving_workers > 0)
-			{
-				if(potential_moving_workers > config->granularity)
-				{
-					if((nworkers - config->granularity) > config->min_nprocs)	
-						nworkers_to_move = config->granularity;
-				}
-				else
-				{
-					int nfixed_workers = nworkers - potential_moving_workers;
-					if(nfixed_workers >= config->min_nprocs)
-						nworkers_to_move = potential_moving_workers;
-					else
-						nworkers_to_move = potential_moving_workers - (config->min_nprocs - nfixed_workers);	
-				}
-			}
-
-			if(nworkers_to_move > 0)
-			{
-				unsigned prio_sched_ctx = _get_highest_priority_sched_ctx(req_sched_ctx, sched_ctxs, nsched_ctxs);
-				if(prio_sched_ctx != STARPU_NMAX_SCHED_CTXS)
-				{					
-					int *workers_to_move = _get_first_workers(req_sched_ctx, nworkers_to_move);
-					sched_ctx_hypervisor_resize(req_sched_ctx, prio_sched_ctx, workers_to_move, nworkers_to_move);
-
-					struct simple_policy_config *prio_config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(prio_sched_ctx);
-					int i;
-					for(i = 0; i < nworkers_to_move; i++)
-						prio_config->max_idle[workers_to_move[i]] = prio_config->max_idle[workers_to_move[i]] !=MAX_IDLE_TIME ? prio_config->max_idle[workers_to_move[i]] :  prio_config->new_workers_max_idle;
-					
-					free(workers_to_move);
-				}
-			}	
-			pthread_mutex_unlock(&act_hypervisor_mutex);
-			return 0;
+			nworkers_to_move = potential_moving_workers; 
+		else if(potential_moving_workers > config->max_nworkers)
+		{
+			if((potential_moving_workers - config->granularity) > config->max_nworkers)
+				nworkers_to_move = config->granularity;
+			else
+				nworkers_to_move = potential_moving_workers - config->max_nworkers;
+ 
+		}
+		else if(potential_moving_workers > config->granularity)
+		{
+			if((nworkers - config->granularity) > config->min_nworkers)	
+				nworkers_to_move = config->granularity;
+			else
+				nworkers_to_move = potential_moving_workers - config->min_nworkers;
+		}
+		else
+		{
+			int nfixed_workers = nworkers - potential_moving_workers;
+			if(nfixed_workers >= config->min_nworkers)
+				nworkers_to_move = potential_moving_workers;
+			else
+				nworkers_to_move = potential_moving_workers - (config->min_nworkers - nfixed_workers);	
 		}
+		if((nworkers - nworkers_to_move) > config->max_nworkers)
+			nworkers_to_move = nworkers - config->max_nworkers;
 	}
-	return 1;
+	return nworkers_to_move;
+}
+
+static unsigned simple_resize(unsigned req_sched_ctx, int *sched_ctxs, int nsched_ctxs)
+{
+	int ret = pthread_mutex_trylock(&act_hypervisor_mutex);
+	if(ret != EBUSY)
+	{					
+		unsigned nworkers_to_move = _get_nworkers_to_move(req_sched_ctx);
+		
+		if(nworkers_to_move > 0)
+		{
+			unsigned poor_sched_ctx = _find_poor_sched_ctx(req_sched_ctx, sched_ctxs, nsched_ctxs, nworkers_to_move);
+			if(poor_sched_ctx != STARPU_NMAX_SCHED_CTXS)
+			{					
+				int *workers_to_move = _get_first_workers(req_sched_ctx, &nworkers_to_move);
+				sched_ctx_hypervisor_move_workers(req_sched_ctx, poor_sched_ctx, workers_to_move, nworkers_to_move);
+				
+				struct simple_policy_config *new_config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(poor_sched_ctx);
+				int i;
+				for(i = 0; i < nworkers_to_move; i++)
+					new_config->max_idle[workers_to_move[i]] = new_config->max_idle[workers_to_move[i]] !=MAX_IDLE_TIME ? new_config->max_idle[workers_to_move[i]] :  new_config->new_workers_max_idle;
+				
+				free(workers_to_move);
+			}
+		}	
+		pthread_mutex_unlock(&act_hypervisor_mutex);
+		return 1;
+	}
+	return 0;
+
+}
+
+static void simple_manage_idle_time(unsigned req_sched_ctx, int *sched_ctxs, int nsched_ctxs, int worker, double idle_time)
+{
+       	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(req_sched_ctx);
+
+	if(config != NULL && idle_time > config->max_idle[worker])
+		simple_resize(req_sched_ctx, sched_ctxs, nsched_ctxs);
+	return;
 }
 
 static void* simple_ioctl(unsigned sched_ctx, va_list varg_list, unsigned later)
@@ -261,6 +317,16 @@ static void* simple_ioctl(unsigned sched_ctx, va_list varg_list, unsigned later)
 
 			break;
 
+		case HYPERVISOR_EMPTY_CTX_MAX_IDLE:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+			double empty_ctx_max_idle = va_arg(varg_list, double);
+			
+			for(i = 0; i < nworkers; i++)
+				config->empty_ctx_max_idle[workerids[i]] = empty_ctx_max_idle;
+
+			break;
+
 		case HYPERVISOR_MIN_WORKING:
 			workerids = va_arg(varg_list, int*);
 			nworkers = va_arg(varg_list, int);
@@ -280,24 +346,24 @@ static void* simple_ioctl(unsigned sched_ctx, va_list varg_list, unsigned later)
 				config->priority[workerids[i]] = priority;
 			break;
 
-		case HYPERVISOR_MIN_PROCS:
-			config->min_nprocs = va_arg(varg_list, unsigned);
+		case HYPERVISOR_MIN_WORKERS:
+			config->min_nworkers = va_arg(varg_list, unsigned);
 			break;
 
-		case HYPERVISOR_MAX_PROCS:
-			config->max_nprocs = va_arg(varg_list, unsigned);
+		case HYPERVISOR_MAX_WORKERS:
+			config->max_nworkers = va_arg(varg_list, unsigned);
 			break;
 
 		case HYPERVISOR_GRANULARITY:
 			config->granularity = va_arg(varg_list, unsigned);
 			break;
 
-		case HYPERVISOR_FIXED_PROCS:
+		case HYPERVISOR_FIXED_WORKERS:
 			workerids = va_arg(varg_list, int*);
 			nworkers = va_arg(varg_list, int);
 
 			for(i = 0; i < nworkers; i++)
-				config->fixed_procs[workerids[i]] = 1;
+				config->fixed_workers[workerids[i]] = 1;
 			break;
 
 		case HYPERVISOR_NEW_WORKERS_MAX_IDLE:
@@ -326,18 +392,19 @@ static void simple_update_config(void *old_config, void* config)
 	struct simple_policy_config *old = (struct simple_policy_config*)old_config;
 	struct simple_policy_config *new = (struct simple_policy_config*)config;
 
-	old->min_nprocs = new->min_nprocs != 0 ? new->min_nprocs : old->min_nprocs ;
-	old->max_nprocs = new->max_nprocs != 0 ? new->max_nprocs : old->max_nprocs ;
-	old->new_workers_max_idle = new->new_workers_max_idle != MAX_IDLE_TIME ? new->new_workers_max_idle : old->new_workers_max_idle;
-	old->granularity = new->min_nprocs != 1 ? new->granularity : old->granularity;
+	old->min_nworkers = new->min_nworkers != -1 ? new->min_nworkers : old->min_nworkers ;
+	old->max_nworkers = new->max_nworkers != -1 ? new->max_nworkers : old->max_nworkers ;
+	old->new_workers_max_idle = new->new_workers_max_idle != -1.0 ? new->new_workers_max_idle : old->new_workers_max_idle;
+	old->granularity = new->granularity != -1 ? new->granularity : old->granularity;
 
 	int i;
 	for(i = 0; i < STARPU_NMAXWORKERS; i++)
 	{
-		old->priority[i] = new->priority[i] != 0 ? new->priority[i] : old->priority[i];
-		old->fixed_procs[i] = new->fixed_procs[i] != 0 ? new->fixed_procs[i] : old->fixed_procs[i];
-		old->max_idle[i] = new->max_idle[i] != MAX_IDLE_TIME ? new->max_idle[i] : old->max_idle[i];;
-		old->min_working[i] = new->min_working[i] != MIN_WORKING_TIME ? new->min_working[i] : old->min_working[i];
+		old->priority[i] = new->priority[i] != -1 ? new->priority[i] : old->priority[i];
+		old->fixed_workers[i] = new->fixed_workers[i] != -1 ? new->fixed_workers[i] : old->fixed_workers[i];
+		old->max_idle[i] = new->max_idle[i] != -1.0 ? new->max_idle[i] : old->max_idle[i];
+		old->empty_ctx_max_idle[i] = new->empty_ctx_max_idle[i] != -1.0 ? new->empty_ctx_max_idle[i] : old->empty_ctx_max_idle[i];
+		old->min_working[i] = new->min_working[i] != -1.0 ? new->min_working[i] : old->min_working[i];
 	}
 }
 
@@ -353,5 +420,6 @@ struct hypervisor_policy simple_policy = {
 	.remove_sched_ctx = simple_remove_sched_ctx,
 	.ioctl = simple_ioctl,
 	.manage_idle_time = simple_manage_idle_time,
+	.resize = simple_resize,
 	.update_config = simple_update_config
 };

+ 56 - 76
sched_ctx_hypervisor/src/sched_ctx_hypervisor.c

@@ -23,6 +23,7 @@ static void _load_hypervisor_policy(int type)
 		hypervisor.policy.ioctl = simple_policy.ioctl;
 		hypervisor.policy.manage_idle_time = simple_policy.manage_idle_time;
 		hypervisor.policy.update_config = simple_policy.update_config;
+		hypervisor.policy.resize = simple_policy.resize;
 		break;
 	}
 }
@@ -46,7 +47,6 @@ struct starpu_sched_ctx_hypervisor_criteria* sched_ctx_hypervisor_init(int type)
 			hypervisor.sched_ctx_w[i].current_idle_time[j] = 0.0;
 			hypervisor.sched_ctx_w[i].tasks[j] = 0;
 			hypervisor.sched_ctx_w[i].poped_tasks[j] = 0;
-			hypervisor.sched_ctx_w[i].unsucceded_resizes[j] = 0;
 		}
 	}
 
@@ -63,14 +63,19 @@ struct starpu_sched_ctx_hypervisor_criteria* sched_ctx_hypervisor_init(int type)
 
 void sched_ctx_hypervisor_stop_resize(unsigned sched_ctx)
 {
+	pthread_mutex_lock(&act_hypervisor_mutex);
 	imposed_resize = 1;
 	hypervisor.resize[sched_ctx] = 0;
+	pthread_mutex_unlock(&act_hypervisor_mutex);
+			
 }
 
 void sched_ctx_hypervisor_start_resize(unsigned sched_ctx)
 {
+	pthread_mutex_lock(&act_hypervisor_mutex);	
 	imposed_resize = 1;
 	hypervisor.resize[sched_ctx] = 1;
+	pthread_mutex_unlock(&act_hypervisor_mutex);
 }
 
 void sched_ctx_hypervisor_shutdown(void)
@@ -78,7 +83,7 @@ void sched_ctx_hypervisor_shutdown(void)
 	int i;
 	for(i = 0; i < STARPU_NMAX_SCHED_CTXS; i++)
 	{
-		hypervisor.resize[i] = 0;
+		sched_ctx_hypervisor_stop_resize(hypervisor.sched_ctxs[i]);
                 if(hypervisor.sched_ctxs[i] != STARPU_NMAX_SCHED_CTXS && hypervisor.nsched_ctxs > 0)
 			sched_ctx_hypervisor_ignore_ctx(i);
 	}
@@ -89,8 +94,8 @@ void sched_ctx_hypervisor_shutdown(void)
 void sched_ctx_hypervisor_handle_ctx(unsigned sched_ctx)
 {	
 	hypervisor.configurations[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
-	hypervisor.advices[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
-	hypervisor.requests[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
+	hypervisor.steal_requests[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
+	hypervisor.resize_requests[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
 
 	hypervisor.policy.add_sched_ctx(sched_ctx);
 	hypervisor.sched_ctx_w[sched_ctx].sched_ctx = sched_ctx;
@@ -131,7 +136,6 @@ static void _rearange_sched_ctxs(int *sched_ctxs, int old_nsched_ctxs)
 
 void sched_ctx_hypervisor_ignore_ctx(unsigned sched_ctx)
 {
-	pthread_mutex_lock(&act_hypervisor_mutex);
         unsigned i;
         for(i = 0; i < hypervisor.nsched_ctxs; i++)
         {
@@ -146,10 +150,10 @@ void sched_ctx_hypervisor_ignore_ctx(unsigned sched_ctx)
 	hypervisor.nsched_ctxs--;
 	hypervisor.sched_ctx_w[sched_ctx].sched_ctx = STARPU_NMAX_SCHED_CTXS;
 	hypervisor.policy.remove_sched_ctx(sched_ctx);
+
 	free(hypervisor.configurations[sched_ctx]);
-	free(hypervisor.advices[sched_ctx]);
-	free(hypervisor.requests[sched_ctx]);
-	pthread_mutex_unlock(&act_hypervisor_mutex);
+	free(hypervisor.steal_requests[sched_ctx]);
+	free(hypervisor.resize_requests[sched_ctx]);
 }
 
 void sched_ctx_hypervisor_set_config(unsigned sched_ctx, void *config)
@@ -204,20 +208,6 @@ void sched_ctx_hypervisor_ioctl(unsigned sched_ctx, ...)
 	return;
 }
 
-static void _sched_ctx_hypervisor_resize(unsigned sender_sched_ctx, unsigned receiver_sched_ctx, int* workers_to_move, unsigned nworkers_to_move)
-{
-	/* int i; */
-	/* printf("resize ctx %d with", sender_sched_ctx); */
-	/* for(i = 0; i < nworkers_to_move; i++) */
-	/* 	printf(" %d", workers_to_move[i]); */
-	/* printf("\n"); */
-
-	starpu_remove_workers_from_sched_ctx(workers_to_move, nworkers_to_move, sender_sched_ctx);
-	starpu_add_workers_to_sched_ctx(workers_to_move, nworkers_to_move, receiver_sched_ctx);
-
-	return;
-}
-
 static int get_ntasks( int *tasks)
 {
 	int ntasks = 0;
@@ -236,54 +226,40 @@ static unsigned check_tasks_of_sched_ctx(unsigned sched_ctx)
 	return ntasks > hypervisor.min_tasks;
 }
 
-void sched_ctx_hypervisor_resize(unsigned sender_sched_ctx, unsigned receiver_sched_ctx, int* workers_to_move, unsigned nworkers_to_move)
+void sched_ctx_hypervisor_move_workers(unsigned sender_sched_ctx, unsigned receiver_sched_ctx, int* workers_to_move, unsigned nworkers_to_move)
 {
 	if(hypervisor.resize[sender_sched_ctx])
 	{
-		_sched_ctx_hypervisor_resize(sender_sched_ctx, receiver_sched_ctx, workers_to_move, nworkers_to_move);
+		int j;
+		printf("resize ctx %d with", sender_sched_ctx);
+		for(j = 0; j < nworkers_to_move; j++)
+			printf(" %d", workers_to_move[j]);
+		printf("\n");
+
+		starpu_remove_workers_from_sched_ctx(workers_to_move, nworkers_to_move, sender_sched_ctx);
+		starpu_add_workers_to_sched_ctx(workers_to_move, nworkers_to_move, receiver_sched_ctx);
 
 		int i;
 		for(i = 0; i < nworkers_to_move; i++)
-		{
 			hypervisor.sched_ctx_w[sender_sched_ctx].current_idle_time[workers_to_move[i]] = 0.0;
-			hypervisor.sched_ctx_w[sender_sched_ctx].unsucceded_resizes[workers_to_move[i]] = 0;
-		}
 	}
 
 	return;
 }
 
-void sched_ctx_hypervisor_advise(unsigned sched_ctx, int *workerids, int nworkers, int task_tag)
+unsigned sched_ctx_hypervisor_resize(unsigned sched_ctx, int task_tag)
 {
-	/* do it right now */
-	if(task_tag == -1)	
+	if(task_tag == -1)
 	{
-		pthread_mutex_lock(&act_hypervisor_mutex);
-		
-		if(hypervisor.sched_ctx_w[sched_ctx].sched_ctx != STARPU_NMAX_SCHED_CTXS)
-		{
-			printf("do advice\n");
-			starpu_add_workers_to_sched_ctx(workerids, nworkers, sched_ctx);
-			
-			sched_ctx_hypervisor_ioctl(sched_ctx, 
-						   HYPERVISOR_PRIORITY, workerids, nworkers, 1,
-						   NULL);		
-		}
-		
-		pthread_mutex_unlock(&act_hypervisor_mutex);
+		return hypervisor.policy.resize(sched_ctx, hypervisor.sched_ctxs, hypervisor.nsched_ctxs);
 	}
 	else
-	{
-		struct sched_ctx_hypervisor_adjustment* adjustment = (struct sched_ctx_hypervisor_adjustment*)malloc(sizeof(struct sched_ctx_hypervisor_adjustment));
-		int i;
-		for(i = 0; i < nworkers; i++)
-			adjustment->workerids[i] = workerids[i];
-		adjustment->nworkers = nworkers;
-		
-		_starpu_htbl_insert_32(&hypervisor.advices[sched_ctx], (uint32_t)task_tag, (void*)adjustment);	
+	{	
+		unsigned *sched_ctx_pt = (unsigned*)malloc(sizeof(unsigned));
+		*sched_ctx_pt = sched_ctx;
+		_starpu_htbl_insert_32(&hypervisor.resize_requests[sched_ctx], (uint32_t)task_tag, (void*)sched_ctx_pt);	
+		return 0;
 	}
-
-	return;
 }
 
 void get_overage_workers(unsigned sched_ctx, int *workerids, int nworkers, int *overage_workers, int *noverage_workers)
@@ -312,7 +288,7 @@ void get_overage_workers(unsigned sched_ctx, int *workerids, int nworkers, int *
 		workers->deinit_cursor(workers);
 }
 
-void sched_ctx_hypervisor_request(unsigned sched_ctx, int *workerids, int nworkers, int task_tag)
+void sched_ctx_hypervisor_steal_workers(unsigned sched_ctx, int *workerids, int nworkers, int task_tag)
 {
 	/* do it right now */
 	if(task_tag == -1)	
@@ -351,7 +327,7 @@ void sched_ctx_hypervisor_request(unsigned sched_ctx, int *workerids, int nworke
 			adjustment->workerids[i] = workerids[i];
 		adjustment->nworkers = nworkers;
 		
-		_starpu_htbl_insert_32(&hypervisor.requests[sched_ctx], (uint32_t)task_tag, (void*)adjustment);	
+		_starpu_htbl_insert_32(&hypervisor.steal_requests[sched_ctx], (uint32_t)task_tag, (void*)adjustment);	
 	}
 
 	return ;
@@ -368,18 +344,13 @@ static void idle_time_cb(unsigned sched_ctx, int worker, double idle_time)
 	if(hypervisor.resize[sched_ctx] && hypervisor.nsched_ctxs > 1 && hypervisor.policy.manage_idle_time)
 	{
 		hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker] += idle_time;
-		hypervisor.sched_ctx_w[sched_ctx].unsucceded_resizes[worker] += hypervisor.policy.manage_idle_time(sched_ctx, hypervisor.sched_ctxs, hypervisor.nsched_ctxs, worker, hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker]);
-		if(hypervisor.sched_ctx_w[sched_ctx].unsucceded_resizes[worker] > 5)
-		{
-//			hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker] -= idle_time;
-			hypervisor.sched_ctx_w[sched_ctx].unsucceded_resizes[worker] = 0;
-//			printf("%d: reseted idle time\n", worker);
-		}
+		hypervisor.policy.manage_idle_time(sched_ctx, hypervisor.sched_ctxs, hypervisor.nsched_ctxs, worker, hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker]);
+
 	}
 	return;
 }
 
-static void working_time_cb(unsigned sched_ctx, int worker, double working_time, unsigned current_nprocs)
+static void working_time_cb(unsigned sched_ctx, int worker, double working_time, unsigned current_nworkers)
 {
 	return;
 }
@@ -409,25 +380,34 @@ static void post_exec_hook_cb(unsigned sched_ctx, int task_tag)
 
 	if(hypervisor.nsched_ctxs > 1)
 	{
-		void *config = _starpu_htbl_search_32(hypervisor.configurations[sched_ctx], (uint32_t)task_tag);
-		if(config)
-		{	
-			sched_ctx_hypervisor_set_config(sched_ctx, config);
-			free(config);
-		}
+		unsigned conf_sched_ctx;
+		int i;
+		for(i = 0; i < hypervisor.nsched_ctxs; i++)
+		{
+			conf_sched_ctx = hypervisor.sched_ctxs[i];
+			void *config = _starpu_htbl_search_32(hypervisor.configurations[conf_sched_ctx], (uint32_t)task_tag);
+			if(config && config != hypervisor.configurations[conf_sched_ctx])
+			{
+				sched_ctx_hypervisor_set_config(conf_sched_ctx, config);
+				free(config);
+				_starpu_htbl_insert_32(&hypervisor.configurations[sched_ctx], (uint32_t)task_tag, NULL);
+			}
+		}	
 		
-		struct sched_ctx_hypervisor_adjustment *adjustment = (struct sched_ctx_hypervisor_adjustment*) _starpu_htbl_search_32(hypervisor.advices[sched_ctx], (uint32_t)task_tag);
-		if(adjustment)
+		struct sched_ctx_hypervisor_adjustment *adjustment = (struct sched_ctx_hypervisor_adjustment*) _starpu_htbl_search_32(hypervisor.steal_requests[sched_ctx], (uint32_t)task_tag);
+		if(adjustment && adjustment != hypervisor.steal_requests[sched_ctx])
 		{
-			sched_ctx_hypervisor_advise(sched_ctx, adjustment->workerids, adjustment->nworkers, -1);
+			sched_ctx_hypervisor_steal_workers(sched_ctx, adjustment->workerids, adjustment->nworkers, -1);
 			free(adjustment);
+			_starpu_htbl_insert_32(&hypervisor.steal_requests[sched_ctx], (uint32_t)task_tag, NULL);
 		}
 		
-		adjustment = (struct sched_ctx_hypervisor_adjustment*) _starpu_htbl_search_32(hypervisor.requests[sched_ctx], (uint32_t)task_tag);
-		if(adjustment)
+		unsigned *sched_ctx_pt = _starpu_htbl_search_32(hypervisor.resize_requests[sched_ctx], (uint32_t)task_tag);
+		if(sched_ctx_pt && sched_ctx_pt != hypervisor.resize_requests[sched_ctx])
 		{
-			sched_ctx_hypervisor_request(sched_ctx, adjustment->workerids, adjustment->nworkers, -1);
-			free(adjustment);
+			sched_ctx_hypervisor_resize(sched_ctx, -1);
+			free(sched_ctx_pt);
+			_starpu_htbl_insert_32(&hypervisor.resize_requests[sched_ctx], (uint32_t)task_tag, NULL);
 		}
 	}
 }

+ 2 - 3
sched_ctx_hypervisor/src/sched_ctx_hypervisor_intern.h

@@ -6,7 +6,6 @@ struct sched_ctx_wrapper {
 	double current_idle_time[STARPU_NMAXWORKERS];
 	int tasks[STARPU_NMAXWORKERS];
 	int poped_tasks[STARPU_NMAXWORKERS];
-	int unsucceded_resizes[STARPU_NMAXWORKERS];
 };
 
 struct sched_ctx_hypervisor {
@@ -17,8 +16,8 @@ struct sched_ctx_hypervisor {
 	int min_tasks;
 	struct hypervisor_policy policy;
 	struct starpu_htbl32_node_s *configurations[STARPU_NMAX_SCHED_CTXS];
-	struct starpu_htbl32_node_s *advices[STARPU_NMAX_SCHED_CTXS];
-	struct starpu_htbl32_node_s *requests[STARPU_NMAX_SCHED_CTXS];
+	struct starpu_htbl32_node_s *steal_requests[STARPU_NMAX_SCHED_CTXS];
+	struct starpu_htbl32_node_s *resize_requests[STARPU_NMAX_SCHED_CTXS];
 };
 
 struct sched_ctx_hypervisor_adjustment {

+ 1 - 1
src/core/sched_ctx.c

@@ -277,7 +277,7 @@ void starpu_delete_sched_ctx(unsigned sched_ctx_id, unsigned inheritor_sched_ctx
 	struct starpu_machine_config_s *config = (struct starpu_machine_config_s *)_starpu_get_machine_config();
 	int nworkers = config->topology.nworkers;
 
-	if(!(sched_ctx->workers->nworkers == nworkers && sched_ctx->workers->nworkers == inheritor_sched_ctx->workers->nworkers) && sched_ctx->workers->nworkers > 0 && inheritor_sched_ctx != STARPU_NMAX_SCHED_CTXS)
+	if(!(sched_ctx->workers->nworkers == nworkers && sched_ctx->workers->nworkers == inheritor_sched_ctx->workers->nworkers) && sched_ctx->workers->nworkers > 0 && inheritor_sched_ctx_id != STARPU_NMAX_SCHED_CTXS)
 		starpu_add_workers_to_sched_ctx(sched_ctx->workers->workerids, sched_ctx->workers->nworkers, inheritor_sched_ctx_id);
 	
 	if(!starpu_wait_for_all_tasks_of_sched_ctx(sched_ctx_id))

+ 2 - 2
src/core/sched_policy.c

@@ -293,9 +293,9 @@ int _starpu_push_task(starpu_job_t j, unsigned job_is_already_locked)
 	unsigned no_workers = 0;
 	unsigned nworkers; 
        
-	PTHREAD_MUTEX_LOCK(&sched_ctx->changing_ctx_mutex);
+//	PTHREAD_MUTEX_LOCK(&sched_ctx->changing_ctx_mutex);
 	nworkers = sched_ctx->workers->nworkers;
-	PTHREAD_MUTEX_UNLOCK(&sched_ctx->changing_ctx_mutex);
+//	PTHREAD_MUTEX_UNLOCK(&sched_ctx->changing_ctx_mutex);
 
 	if(nworkers == 0)
 	{