Преглед на файлове

Also check that we don't synchronize with a tag while blocking is prohibited.

Cédric Augonnet преди 15 години
родител
ревизия
499cbfed6a
променени са 3 файла, в които са добавени 35 реда и са изтрити 9 реда
  1. 2 2
      include/starpu-task.h
  2. 10 4
      src/core/dependencies/tags.c
  3. 23 3
      tests/errorcheck/invalid_blocking_calls.c

+ 2 - 2
include/starpu-task.h

@@ -164,8 +164,8 @@ struct starpu_task {
 void starpu_tag_declare_deps(starpu_tag_t id, unsigned ndeps, ...);
 void starpu_tag_declare_deps_array(starpu_tag_t id, unsigned ndeps, starpu_tag_t *array);
 
-void starpu_tag_wait(starpu_tag_t id);
-void starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id);
+int starpu_tag_wait(starpu_tag_t id);
+int starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id);
 
 /* The application can feed a tag explicitely */
 void starpu_tag_notify_from_apps(starpu_tag_t id);

+ 10 - 4
src/core/dependencies/tags.c

@@ -362,13 +362,17 @@ void starpu_tag_declare_deps(starpu_tag_t id, unsigned ndeps, ...)
 }
 
 /* this function may be called by the application (outside callbacks !) */
-void starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id)
+int starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id)
 {
 	unsigned i;
 	unsigned current;
 
 	struct tag_s *tag_array[ntags];
 
+	/* It is forbidden to block within callbacks or codelets */
+	if (STARPU_UNLIKELY(!worker_may_perform_blocking_calls()))
+		return -EDEADLK;
+
 	/* only wait the tags that are not done yet */
 	for (i = 0, current = 0; i < ntags; i++)
 	{
@@ -391,7 +395,7 @@ void starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id)
 	if (current == 0)
 	{
 		/* all deps are already fulfilled */
-		return;
+		return 0;
 	}
 	
 	/* there is at least one task that is not finished */
@@ -414,9 +418,11 @@ void starpu_tag_wait_array(unsigned ntags, starpu_tag_t *id)
 	pthread_cond_destroy(&cg->cg_cond);
 
 	free(cg);
+
+	return 0;
 }
 
-void starpu_tag_wait(starpu_tag_t id)
+int starpu_tag_wait(starpu_tag_t id)
 {
-	starpu_tag_wait_array(1, &id);
+	return starpu_tag_wait_array(1, &id);
 }

+ 23 - 3
tests/errorcheck/invalid_blocking_calls.c

@@ -16,14 +16,22 @@
 
 #include <starpu.h>
 
+#define TAG	0x42
+
 static starpu_data_handle handle;
 static unsigned data = 42;
 
 static void wrong_func(starpu_data_interface_t *descr, void *arg)
 {
+	int ret;
+
 	/* try to fetch data in the RAM while we are in a codelet, such a
 	 * blocking call is forbidden */
-	int ret = starpu_sync_data_with_mem(handle);
+	ret = starpu_sync_data_with_mem(handle);
+	if (ret != -EDEADLK)
+		exit(-1);
+
+	ret = starpu_tag_wait(TAG);
 	if (ret != -EDEADLK)
 		exit(-1);
 }
@@ -39,7 +47,13 @@ static starpu_codelet wrong_codelet =
 
 static void wrong_callback(void *arg)
 {
-	int ret = starpu_sync_data_with_mem(handle);
+	int ret;
+
+	ret  = starpu_sync_data_with_mem(handle);
+	if (ret != -EDEADLK)
+		exit(-1);
+
+	ret = starpu_tag_wait(TAG);
 	if (ret != -EDEADLK)
 		exit(-1);
 }
@@ -61,13 +75,19 @@ int main(int argc, char **argv)
 	task->buffers[0].handle = handle;
 	task->buffers[0].mode = STARPU_RW;
 
+	task->use_tag = 1;
+	task->tag_id = TAG;
+
 	task->callback_func = wrong_callback;
 
-	task->synchronous = 1;
 	ret = starpu_submit_task(task);
 	if (ret == -ENODEV)
 		goto enodev;
 
+	ret = starpu_tag_wait(TAG);
+	if (ret)
+		return -1;
+
 	/* This call is valid as it is done by the application outside a
 	 * callback */
 	ret = starpu_sync_data_with_mem(handle);