diff options
author | Petri Savolainen <petri.savolainen@linaro.org> | 2014-10-02 15:24:41 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2014-10-03 16:38:10 +0400 |
commit | d988593a73cd2882b6ddfa5434e798f89e4b42e0 (patch) | |
tree | 0274f07398d60c8db1dee5f99e8e6f5a5796fec2 /platform | |
parent | 0e0bcce3b624c3a5afc0cca6b4d02ae940bbe47f (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.h | 4 | ||||
-rw-r--r-- | platform/linux-generic/include/api/odp_thread.h | 17 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_internal.h | 4 | ||||
-rw-r--r-- | platform/linux-generic/odp_init.c | 14 | ||||
-rw-r--r-- | platform/linux-generic/odp_linux.c | 113 | ||||
-rw-r--r-- | platform/linux-generic/odp_thread.c | 84 |
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; } |