Pārlūkot izejas kodu

- prepare job structure for preemption support

Olivier Aumage 11 gadi atpakaļ
vecāks
revīzija
b892c5e00e
2 mainītis faili ar 62 papildinājumiem un 3 dzēšanām
  1. 27 0
      src/core/jobs.h
  2. 35 3
      src/util/openmp_runtime_support.c

+ 27 - 0
src/core/jobs.h

@@ -60,6 +60,28 @@ struct _starpu_data_descr {
 	int node;
 };
 
+#ifdef STARPU_OPENMP
+enum _starpu_job_preemption_state {
+	/* Job has never met any preemption event. */
+	_starpu_job_preemption_state_clear                    = 0,
+	/* Job has gone through the preemption preparation step
+	 * and is ready to be preempted. */
+	_starpu_job_preemption_state_prepared_for_preemption  = 1 << 0,
+	/* Job has just been preempted and is being temporarily removed from
+	 * its worker. If this bit is unset and the job is being removed from
+	 * its worker, it means that the job is simply terminating */
+	_starpu_job_preemption_state_is_preempted             = 1 << 1,
+	/* Preempted job has just been unlocked and is being put back on a
+	 * worker. If this bit is unset and the job is being put on a worker,
+	 * it means that the job is simply starting */
+	_starpu_job_preemption_state_is_restarted             = 1 << 2,
+	/* Job was preempted at least once in its life time. Useful for
+	 * determinating whether profiling data should be cumulated with
+	 * previous runs */
+	_starpu_job_preemption_state_was_preempted            = 1 << 3
+};
+#endif
+
 /* A job is the internal representation of a task. */
 LIST_TYPE(_starpu_job,
 
@@ -108,6 +130,11 @@ LIST_TYPE(_starpu_job,
 	 * not. */
 	unsigned terminated;
 
+#ifdef STARPU_OPENMP
+	/* Job preemption state and history. */
+	unsigned preemption_state;
+#endif
+
 	/* Should that task appear in the debug tools ? (eg. the DAG generated
 	 * with dot) */
         unsigned exclude_from_dag;

+ 35 - 3
src/util/openmp_runtime_support.c

@@ -37,6 +37,15 @@ static starpu_pthread_key_t omp_task_key;
 struct starpu_omp_global *_starpu_omp_global_state = NULL;
 double _starpu_omp_clock_ref = 0.0; /* clock reference for starpu_omp_get_wtick */
 
+static struct starpu_omp_device *create_omp_device_struct(void);
+static void destroy_omp_device_struct(struct starpu_omp_device *device);
+static struct starpu_omp_region *create_omp_region_struct(struct starpu_omp_region *parent_region, struct starpu_omp_device *owner_device);
+static void destroy_omp_region_struct(struct starpu_omp_region *region);
+static struct starpu_omp_thread *create_omp_thread_struct(struct starpu_omp_region *owner_region);
+static void destroy_omp_thread_struct(struct starpu_omp_thread *thread);
+static struct starpu_omp_task *create_omp_task_struct(struct starpu_omp_task *parent_task,
+		struct starpu_omp_thread *owner_thread, struct starpu_omp_region *owner_region, int is_implicit);
+static void destroy_omp_task_struct(struct starpu_omp_task *task);
 
 static struct starpu_omp_device *create_omp_device_struct(void)
 {
@@ -169,6 +178,16 @@ static void starpu_omp_task_preempt(void)
 }
 
 /*
+ * set a flag in starpu_task to indicate that the terminating/destroying sequence should not be applied on this task upon return,
+ * the preempting sequence should be performed instead
+ */
+static void _starpu_task_set_preempted(struct starpu_task *starpu_task)
+{
+	(void)starpu_task;
+	abort();/* TODO: implement */
+}
+
+/*
  * wrap a task function to allow the task to be preempted
  */
 static void starpu_omp_task_exec(void *buffers[], void *cl_arg)
@@ -228,6 +247,20 @@ static void starpu_omp_task_exec(void *buffers[], void *cl_arg)
 	}
 
 	/* TODO: analyse the cause of the return and take appropriate steps */
+	if (task->state == starpu_omp_task_state_terminated)
+	{
+		if (!task->is_implicit)
+		{
+			destroy_omp_task_struct(task);
+			task = NULL;
+		}
+	}
+	else if (task->state == starpu_omp_task_state_preempted)
+	{
+		_starpu_task_set_preempted(task->starpu_task);
+	}
+	else
+		_STARPU_ERROR("invalid omp task state");
 }
 
 /*
@@ -239,8 +272,9 @@ static void starpu_omp_task_exec(void *buffers[], void *cl_arg)
  */
 static void _starpu_task_prepare_for_preemption(struct starpu_task *starpu_task)
 {
-	/* TODO: implement funciton */
+	/* TODO: implement function */
 	(void)starpu_task;
+	abort();/* TODO: implement */
 }
 
 static struct starpu_omp_task *create_omp_task_struct(struct starpu_omp_task *parent_task,
@@ -296,12 +330,10 @@ static void destroy_omp_task_struct(struct starpu_omp_task *task)
 {
 	STARPU_ASSERT(task->state == starpu_omp_task_state_terminated);
 	STARPU_ASSERT(task->starpu_task == NULL);
-
 	if (task->stack != NULL)
 	{
 		free(task->stack);
 	}
-
 	memset(task, 0, sizeof(*task));
 	free(task);
 }