aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@linaro.org>2014-10-02 15:24:41 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2014-10-03 16:38:10 +0400
commitd988593a73cd2882b6ddfa5434e798f89e4b42e0 (patch)
tree0274f07398d60c8db1dee5f99e8e6f5a5796fec2 /platform
parent0e0bcce3b624c3a5afc0cca6b4d02ae940bbe47f (diff)
Added process mode to example app
- Added an option to run odp_example as Linux processes (vs. pthreads) - Removed thread dependency from odp_local_init - Added Linux helpers for forking processes - modified odp_thread.c to allocate global variables from shared memory Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/include/api/odp_init.h4
-rw-r--r--platform/linux-generic/include/api/odp_thread.h17
-rw-r--r--platform/linux-generic/include/odp_internal.h4
-rw-r--r--platform/linux-generic/odp_init.c14
-rw-r--r--platform/linux-generic/odp_linux.c113
-rw-r--r--platform/linux-generic/odp_thread.c84
6 files changed, 186 insertions, 50 deletions
diff --git a/platform/linux-generic/include/api/odp_init.h b/platform/linux-generic/include/api/odp_init.h
index 490324a30..13c8e44cb 100644
--- a/platform/linux-generic/include/api/odp_init.h
+++ b/platform/linux-generic/include/api/odp_init.h
@@ -41,10 +41,10 @@ int odp_init_global(void);
*
* All threads must call this function before calling
* any other ODP API functions.
- * @param thr_id Thread id
+ *
* @return 0 if successful
*/
-int odp_init_local(int thr_id);
+int odp_init_local(void);
diff --git a/platform/linux-generic/include/api/odp_thread.h b/platform/linux-generic/include/api/odp_thread.h
index e8e8c8ab8..5567748c4 100644
--- a/platform/linux-generic/include/api/odp_thread.h
+++ b/platform/linux-generic/include/api/odp_thread.h
@@ -8,7 +8,7 @@
/**
* @file
*
- * ODP Linux helper API
+ * ODP thread API
*/
#ifndef ODP_THREAD_H_
@@ -19,19 +19,6 @@ extern "C" {
#endif
-
-#include <odp_std_types.h>
-
-
-
-/**
- * Create thread id
- *
- * @param core Core dedicated for the thread
- * @return New thread id
- */
-int odp_thread_create(int core);
-
/**
* Get thread id
*
@@ -41,7 +28,7 @@ int odp_thread_id(void);
/**
- * Get thread id
+ * Get core id
*
* @return Core id where the thread is running currently
*/
diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index aa794933d..f8c159694 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -21,8 +21,8 @@ extern "C" {
int odp_system_info_init(void);
-void odp_thread_init_global(void);
-void odp_thread_init_local(int thr_id);
+int odp_thread_init_global(void);
+int odp_thread_init_local(void);
int odp_shm_init_global(void);
int odp_shm_init_local(void);
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 5b7e1925d..55fa53a91 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -11,8 +11,6 @@
int odp_init_global(void)
{
- odp_thread_init_global();
-
odp_system_info_init();
if (odp_shm_init_global()) {
@@ -20,6 +18,11 @@ int odp_init_global(void)
return -1;
}
+ if (odp_thread_init_global()) {
+ ODP_ERR("ODP thread init failed.\n");
+ return -1;
+ }
+
if (odp_buffer_pool_init_global()) {
ODP_ERR("ODP buffer pool init failed.\n");
return -1;
@@ -54,9 +57,12 @@ int odp_init_global(void)
}
-int odp_init_local(int thr_id)
+int odp_init_local(void)
{
- odp_thread_init_local(thr_id);
+ if (odp_thread_init_local()) {
+ ODP_ERR("ODP thread local init failed.\n");
+ return -1;
+ }
if (odp_pktio_init_local()) {
ODP_ERR("ODP packet io local init failed.\n");
diff --git a/platform/linux-generic/odp_linux.c b/platform/linux-generic/odp_linux.c
index 9251ec9d7..cba6637d2 100644
--- a/platform/linux-generic/odp_linux.c
+++ b/platform/linux-generic/odp_linux.c
@@ -8,12 +8,16 @@
#define _GNU_SOURCE
#endif
#include <sched.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
+
#include <odph_linux.h>
#include <odp_internal.h>
#include <odp_thread.h>
@@ -23,7 +27,6 @@
typedef struct {
- int thr_id;
void *(*start_routine) (void *);
void *arg;
@@ -35,9 +38,8 @@ static void *odp_run_start_routine(void *arg)
odp_start_args_t *start_args = arg;
/* ODP thread local init */
- if (odp_init_local(start_args->thr_id)) {
- ODP_ERR("Local init failed for thread: %d\n",
- start_args->thr_id);
+ if (odp_init_local()) {
+ ODP_ERR("Local init failed\n");
return NULL;
}
@@ -65,9 +67,9 @@ void odph_linux_pthread_create(odph_linux_pthread_t *thread_tbl, int num,
for (i = 0; i < num; i++) {
pthread_attr_init(&thread_tbl[i].attr);
- CPU_ZERO(&cpu_set);
-
cpu = (first_core + i) % core_count;
+ thread_tbl[i].core = cpu;
+ CPU_ZERO(&cpu_set);
CPU_SET(cpu, &cpu_set);
pthread_attr_setaffinity_np(&thread_tbl[i].attr,
@@ -81,8 +83,6 @@ void odph_linux_pthread_create(odph_linux_pthread_t *thread_tbl, int num,
start_args->start_routine = start_routine;
start_args->arg = arg;
- start_args->thr_id = odp_thread_create(cpu);
-
pthread_create(&thread_tbl[i].thread, &thread_tbl[i].attr,
odp_run_start_routine, start_args);
}
@@ -98,3 +98,100 @@ void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num)
pthread_join(thread_tbl[i].thread, NULL);
}
}
+
+
+int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
+ int num, int first_core)
+{
+ cpu_set_t cpu_set;
+ pid_t pid;
+ int core_count;
+ int cpu;
+ int i;
+
+ memset(proc_tbl, 0, num*sizeof(odph_linux_process_t));
+
+ core_count = odp_sys_core_count();
+
+ if (first_core < 0 || first_core >= core_count) {
+ ODP_ERR("Bad first_core\n");
+ return -1;
+ }
+
+ if (num < 0 || num > core_count) {
+ ODP_ERR("Bad num\n");
+ return -1;
+ }
+
+ for (i = 0; i < num; i++) {
+ cpu = (first_core + i) % core_count;
+ pid = fork();
+
+ if (pid < 0) {
+ ODP_ERR("fork() failed\n");
+ return -1;
+ }
+
+ /* Parent continues to fork */
+ if (pid > 0) {
+ proc_tbl[i].pid = pid;
+ proc_tbl[i].core = cpu;
+ continue;
+ }
+
+ /* Child process */
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu, &cpu_set);
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set)) {
+ ODP_ERR("sched_setaffinity() failed\n");
+ return -2;
+ }
+
+ if (odp_init_local()) {
+ ODP_ERR("Local init failed\n");
+ return -2;
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
+
+int odph_linux_process_fork(odph_linux_process_t *proc, int core)
+{
+ return odph_linux_process_fork_n(proc, 1, core);
+}
+
+
+int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num)
+{
+ pid_t pid;
+ int i, j;
+ int status;
+
+ for (i = 0; i < num; i++) {
+ pid = wait(&status);
+
+ if (pid < 0) {
+ ODP_ERR("wait() failed\n");
+ return -1;
+ }
+
+ for (j = 0; j < num; j++) {
+ if (proc_tbl[j].pid == pid) {
+ proc_tbl[j].status = status;
+ break;
+ }
+ }
+
+ if (j == num) {
+ ODP_ERR("Bad pid\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c
index eaa480ec8..b869b2755 100644
--- a/platform/linux-generic/odp_thread.c
+++ b/platform/linux-generic/odp_thread.c
@@ -4,65 +4,111 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+
#include <odp_thread.h>
#include <odp_internal.h>
#include <odp_atomic.h>
#include <odp_config.h>
+#include <odp_debug.h>
+#include <odp_shared_memory.h>
+#include <odp_align.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
typedef struct {
int thr_id;
- int phys_core;
+ int cpu;
+
+} thread_state_t;
+
-} odp_thread_tbl_t;
+typedef struct {
+ thread_state_t thr[ODP_CONFIG_MAX_THREADS];
+ odp_atomic_int_t num;
+
+} thread_globals_t;
/* Globals */
-static odp_thread_tbl_t odp_thread_tbl[ODP_CONFIG_MAX_THREADS];
-static odp_atomic_int_t num_threads;
+static thread_globals_t *thread_globals;
+
/* Thread local */
-static __thread odp_thread_tbl_t *odp_this_thread;
+static __thread thread_state_t *this_thread;
-void odp_thread_init_global(void)
+int odp_thread_init_global(void)
{
- memset(odp_thread_tbl, 0, sizeof(odp_thread_tbl));
- num_threads = 0;
-}
+ odp_shm_t shm;
+ shm = odp_shm_reserve("odp_thread_globals",
+ sizeof(thread_globals_t),
+ ODP_CACHE_LINE_SIZE, 0);
-void odp_thread_init_local(int thr_id)
-{
- odp_this_thread = &odp_thread_tbl[thr_id];
+ thread_globals = odp_shm_addr(shm);
+
+ if (thread_globals == NULL)
+ return -1;
+
+ memset(thread_globals, 0, sizeof(thread_globals_t));
+ return 0;
}
-int odp_thread_create(int phys_core)
+static int thread_id(void)
{
int id;
+ int cpu;
+
+ id = odp_atomic_fetch_add_int(&thread_globals->num, 1);
- id = odp_atomic_fetch_add_int(&num_threads, 1);
+ if (id >= ODP_CONFIG_MAX_THREADS) {
+ ODP_ERR("Too many threads\n");
+ return -1;
+ }
+
+ cpu = sched_getcpu();
- if (id < ODP_CONFIG_MAX_THREADS) {
- odp_thread_tbl[id].thr_id = id;
- odp_thread_tbl[id].phys_core = phys_core;
+ if (cpu < 0) {
+ ODP_ERR("getcpu failed\n");
+ return -1;
}
+ thread_globals->thr[id].thr_id = id;
+ thread_globals->thr[id].cpu = cpu;
+
return id;
}
+int odp_thread_init_local(void)
+{
+ int id;
+
+ id = thread_id();
+
+ if (id < 0)
+ return -1;
+
+ this_thread = &thread_globals->thr[id];
+ return 0;
+}
+
+
int odp_thread_id(void)
{
- return odp_this_thread->thr_id;
+ return this_thread->thr_id;
}
int odp_thread_core(void)
{
- return odp_this_thread->phys_core;
+ return this_thread->cpu;
}