diff mbox

[2/2] linux-generic: init: assign affinity for main thread

Message ID 1453501492-9721-3-git-send-email-ivan.khoronzhuk@linaro.org
State New
Headers show

Commit Message

Ivan Khoronzhuk Jan. 22, 2016, 10:24 p.m. UTC
By default it's supposed CPU0 to be used for control thread.
So assign CPU0 as control thread CPU. The CPU0 is still can
be used for worker threads, but after this change control thread
cannot use CPUs used by "worker" threads. As example, in some cases,
can happen, at application initialization, the OS scheduler switches
control thread on CPUn (n != 0), and if in this time odp timer is
scheduled, it executes notify routine on CPUn, which will consume
CPU time off some "worker thread" even after initialization.
Also this is good example, how control thread should be used, it
always runs on same CPU, allowing to use local time API,
which can be legal only on single CPU threads.

Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
 platform/linux-generic/odp_init.c | 50 +++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 13 deletions(-)
diff mbox

Patch

diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 3a990d2..7637a85 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -4,6 +4,10 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
+#include <odp_posix_extensions.h>
+#include <sched.h>
+#include <pthread.h>
+
 #include <odp/init.h>
 #include <odp_internal.h>
 #include <odp/debug.h>
@@ -11,6 +15,21 @@ 
 
 struct odp_global_data_s odp_global_data;
 
+static int init_global_set_affinity(void)
+{
+	int ret;
+	cpu_set_t cpuset;
+
+	CPU_ZERO(&cpuset);
+	CPU_SET(0, &cpuset);
+	ret = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
+
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
 int odp_init_global(const odp_init_t *params,
 		    const odp_platform_init_t *platform_params ODP_UNUSED)
 {
@@ -25,12 +44,6 @@  int odp_init_global(const odp_init_t *params,
 			odp_global_data.abort_fn = params->abort_fn;
 	}
 
-	if (odp_time_init_global()) {
-		ODP_ERR("ODP time init failed.\n");
-		goto init_failed;
-	}
-	stage = TIME_INIT;
-
 	if (odp_system_info_init()) {
 		ODP_ERR("ODP system_info init failed.\n");
 		goto init_failed;
@@ -91,6 +104,17 @@  int odp_init_global(const odp_init_t *params,
 	}
 	stage = CLASSIFICATION_INIT;
 
+	if (init_global_set_affinity()) {
+		ODP_ERR("ODP affinity init failed.\n");
+		return -1;
+	}
+
+	if (odp_time_init_global()) {
+		ODP_ERR("ODP time init failed.\n");
+		goto init_failed;
+	}
+	stage = TIME_INIT;
+
 	return 0;
 
 init_failed:
@@ -110,6 +134,13 @@  int _odp_term_global(enum init_stage stage)
 	switch (stage) {
 	case ALL_INIT:
 
+	case TIME_INIT:
+		if (odp_time_term_global()) {
+			ODP_ERR("ODP time term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
 	case CLASSIFICATION_INIT:
 		if (odp_classification_term_global()) {
 			ODP_ERR("ODP classificatio term failed.\n");
@@ -180,13 +211,6 @@  int _odp_term_global(enum init_stage stage)
 		}
 		/* Fall through */
 
-	case TIME_INIT:
-		if (odp_time_term_global()) {
-			ODP_ERR("ODP time term failed.\n");
-			rc = -1;
-		}
-		/* Fall through */
-
 	case NO_INIT:
 		;
 	}