Adrien Guilbaud 6 lat temu
rodzic
commit
5f8b265ad5

+ 3 - 0
include/starpu_expert.h

@@ -44,6 +44,9 @@ int starpu_progression_hook_register(unsigned (*func)(void *arg), void *arg);
 */
 void starpu_progression_hook_deregister(int hook_id);
 
+int starpu_idle_hook_register(unsigned (*func)(void *arg), void *arg);
+void starpu_idle_hook_deregister(int hook_id);
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 0
src/Makefile.am

@@ -74,6 +74,7 @@ noinst_HEADERS = 						\
 	core/disk.h						\
 	core/disk_ops/unistd/disk_unistd_global.h		\
 	core/progress_hook.h                                    \
+	core/idle_hook.h                                        \
 	core/sched_policy.h					\
 	core/sched_ctx.h					\
 	core/sched_ctx_list.h					\
@@ -182,6 +183,7 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	core/debug.c						\
 	core/errorcheck.c					\
 	core/progress_hook.c					\
+	core/idle_hook.c                                        \
 	core/dependencies/cg.c					\
 	core/dependencies/dependencies.c			\
 	core/dependencies/implicit_data_deps.c			\

+ 118 - 0
src/core/idle_hook.c

@@ -0,0 +1,118 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2012                                     Inria
+ * Copyright (C) 2010-2014                                Université de Bordeaux
+ * Copyright (C) 2010-2013,2015,2017                      CNRS
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <core/workers.h>
+#include <common/utils.h>
+#include <core/idle_hook.h>
+
+#define NMAXHOOKS	16
+
+struct progression_hook
+{
+	unsigned (*func)(void *arg);
+	void *arg;
+	unsigned active;
+};
+
+/* protect the hook table */
+static starpu_pthread_rwlock_t idle_hook_rwlock;
+
+static struct progression_hook idle_hooks[NMAXHOOKS] = {{NULL, NULL, 0}};
+static int active_idle_hook_cnt = 0;
+
+/*
+ * Staticly initializing idle_hook_rwlock seems to lead to weird errors
+ * on Darwin, so we do it dynamically.
+ */
+void _starpu_init_idle_hooks(void)
+{
+	STARPU_PTHREAD_RWLOCK_INIT(&idle_hook_rwlock, NULL);
+	STARPU_HG_DISABLE_CHECKING(active_idle_hook_cnt);
+}
+
+int starpu_idle_hook_register(unsigned (*func)(void *arg), void *arg)
+{
+	int hook;
+	STARPU_PTHREAD_RWLOCK_WRLOCK(&idle_hook_rwlock);
+	for (hook = 0; hook < NMAXHOOKS; hook++)
+	{
+		if (!idle_hooks[hook].active)
+		{
+			/* We found an empty slot */
+			idle_hooks[hook].func = func;
+			idle_hooks[hook].arg = arg;
+			idle_hooks[hook].active = 1;
+			active_idle_hook_cnt++;
+
+			STARPU_PTHREAD_RWLOCK_UNLOCK(&idle_hook_rwlock);
+
+			return hook;
+		}
+	}
+
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&idle_hook_rwlock);
+
+	starpu_wake_all_blocked_workers();
+
+	/* We could not find an empty slot */
+	return -1;
+}
+
+void starpu_idle_hook_deregister(int hook_id)
+{
+	STARPU_PTHREAD_RWLOCK_WRLOCK(&idle_hook_rwlock);
+
+	if (idle_hooks[hook_id].active)
+		active_idle_hook_cnt--;
+
+	idle_hooks[hook_id].active = 0;
+
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&idle_hook_rwlock);
+}
+
+unsigned _starpu_execute_registered_idle_hooks(void)
+{
+	if (active_idle_hook_cnt == 0)
+		return 1;
+
+	/* By default, it is possible to block, but if some idle hooks
+	 * requires that it's not blocking, we disable blocking. */
+	unsigned may_block = 1;
+
+	unsigned hook;
+	for (hook = 0; hook < NMAXHOOKS; hook++)
+	{
+		unsigned active;
+
+		STARPU_PTHREAD_RWLOCK_RDLOCK(&idle_hook_rwlock);
+		active = idle_hooks[hook].active;
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&idle_hook_rwlock);
+
+		unsigned may_block_hook = 1;
+
+		if (active)
+			may_block_hook = idle_hooks[hook].func(idle_hooks[hook].arg);
+
+		/* As soon as one hook tells that the driver cannot be
+		 * blocking, we don't allow it. */
+		if (!may_block_hook)
+			may_block = 0;
+	}
+
+	return may_block;
+}

+ 25 - 0
src/core/idle_hook.h

@@ -0,0 +1,25 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2012                                     Inria
+ * Copyright (C) 2013,2015,2017                           CNRS
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#ifndef __IDLE_HOOK_H__
+#define __IDLE_HOOK_H__
+
+void _starpu_init_idle_hooks(void);
+
+unsigned _starpu_execute_registered_idle_hooks(void);
+
+#endif /* !__IDLE_HOOK_H__ */

+ 2 - 0
src/core/workers.c

@@ -28,6 +28,7 @@
 #include <common/utils.h>
 #include <common/graph.h>
 #include <core/progress_hook.h>
+#include <core/idle_hook.h>
 #include <core/workers.h>
 #include <core/debug.h>
 #include <core/disk.h>
@@ -1382,6 +1383,7 @@ int starpu_initialize(struct starpu_conf *user_conf, int *argc, char ***argv)
 
 	_starpu_init_all_sched_ctxs(&_starpu_config);
 	_starpu_init_progression_hooks();
+	_starpu_init_idle_hooks();
 
 	_starpu_init_tags();
 

+ 4 - 0
src/drivers/cpu/driver_cpu.c

@@ -29,6 +29,7 @@
 #include <core/debug.h>
 #include <core/workers.h>
 #include <core/drivers.h>
+#include <core/idle_hook.h>
 #include <drivers/cpu/driver_cpu.h>
 #include <core/sched_policy.h>
 #include <datawizard/memory_manager.h>
@@ -327,8 +328,11 @@ int _starpu_cpu_driver_run_once(struct _starpu_worker *cpu_worker)
 #endif
 
 	if (!task)
+	{
 		/* No task or task still pending transfers */
+		_starpu_execute_registered_idle_hooks();
 		return 0;
+	}
 
 	j = _starpu_get_job_associated_to_task(task);
 	/* NOTE: j->task is != task for parallel tasks, which share the same