@@ -138,6 +138,18 @@ AC_SUBST([with_platform])
AC_SUBST([platform_with_platform], ["platform/${with_platform}"])
##########################################################################
+# Determine which helper platform to build for
+##########################################################################
+AC_ARG_WITH([helper_platform],
+ [AS_HELP_STRING([--with-helper_platform=platform],
+ [select helper platform to be used, default linux-generic])],
+ [],
+ [with_helper_platform=${with_platform}
+ ])
+
+AC_SUBST([with_helper_platform])
+
+##########################################################################
# Run platform specific checks and settings
##########################################################################
IMPLEMENTATION_NAME=""
@@ -202,6 +214,7 @@ AM_CONDITIONAL([test_example], [test x$test_example = xyes ])
AM_CONDITIONAL([HAVE_DOXYGEN], [test "x${DOXYGEN}" = "xdoxygen"])
AM_CONDITIONAL([user_guide], [test "x${user_guides}" = "xyes" ])
AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"])
+AM_CONDITIONAL([helper_extn], [test x$helper_extn = xyes ])
##########################################################################
# Setup doxygen documentation
@@ -293,7 +306,7 @@ AM_CXXFLAGS="-std=c++11"
AC_CONFIG_FILES([Makefile
pkgconfig/libodp-linux.pc
- pkgconfig/libodphelper-linux.pc
+ pkgconfig/libodphelper-linux-generic.pc
])
AC_SEARCH_LIBS([timer_create],[rt posix4])
@@ -320,6 +333,8 @@ AC_MSG_RESULT([
implementation_name: ${IMPLEMENTATION_NAME}
ARCH_DIR ${ARCH_DIR}
with_platform: ${with_platform}
+ with_helper_platform: ${with_helper_platform}
+ helper_extn: ${helper_extn}
prefix: ${prefix}
sysconfdir: ${sysconfdir}
libdir: ${libdir}
@@ -1,6 +1,6 @@
include $(top_srcdir)/platform/@with_platform@/Makefile.inc
LIB = $(top_builddir)/lib
-LDADD = $(LIB)/libodp-linux.la $(LIB)/libodphelper-linux.la
+LDADD = $(LIB)/libodp-linux.la $(LIB)/libodphelper-@with_helper_platform@.la
AM_CFLAGS += \
-I$(srcdir) \
-I$(top_srcdir)/example \
@@ -1,7 +1,7 @@
include $(top_srcdir)/platform/@with_platform@/Makefile.inc
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = $(top_builddir)/pkgconfig/libodphelper-linux.pc
+pkgconfig_DATA = $(top_builddir)/pkgconfig/libodphelper-linux-generic.pc
LIB = $(top_builddir)/lib
AM_CFLAGS = -I$(srcdir)/include
@@ -25,18 +25,24 @@ helperinclude_HEADERS = \
$(srcdir)/include/odp/helper/threads.h \
$(srcdir)/include/odp/helper/udp.h
+if helper_extn
+helperinclude_HEADERS += \
+ $(srcdir)/include/odp/helper/platform/@with_helper_platform@/threads_extn.h
+endif
+
noinst_HEADERS = \
$(srcdir)/odph_debug.h \
$(srcdir)/odph_hashtable.h \
$(srcdir)/odph_lineartable.h \
$(srcdir)/odph_list_internal.h
-__LIB__libodphelper_linux_la_SOURCES = \
+__LIB__libodphelper_@with_platform@_la_SOURCES = \
eth.c \
ip.c \
chksum.c \
hashtable.c \
lineartable.c \
- threads.c
+ threads.c \
+ platform/@with_helper_platform@/thread.c
-lib_LTLIBRARIES = $(LIB)/libodphelper-linux.la
+lib_LTLIBRARIES = $(LIB)/libodphelper-@with_platform@.la
new file mode 100644
@@ -0,0 +1,112 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP Linux helper extension API
+ *
+ * This file is an optional helper to odp.h APIs. These functions are provided
+ * to ease common setups in a Linux system. User is free to implement the same
+ * setups in otherways (not via this API).
+ */
+
+#ifndef ODPH_LINUX_EXT_H_
+#define ODPH_LINUX_EXT_H_
+
+#include <odp/helper/threads.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odph_linux ODPH LINUX
+ * @{
+ */
+
+/**
+ * Creates and launches pthreads
+ *
+ * Creates, pins and launches threads to separate CPU's based on the cpumask.
+ *
+ * @param[out] pthread_tbl Table of pthread state information records. Table
+ * must have at least as many entries as there are
+ * CPUs in the CPU mask.
+ * @param mask CPU mask
+ * @param thr_params Linux helper thread parameters
+ *
+ * @return Number of threads created
+ */
+int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
+ const odp_cpumask_t *mask,
+ const odph_linux_thr_params_t *thr_params);
+
+/**
+ * Waits pthreads to exit
+ *
+ * Returns when all threads have been exit.
+ *
+ * @param thread_tbl Thread table
+ * @param num Number of threads to create
+ *
+ */
+void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num);
+
+/**
+ * Fork a process
+ *
+ * Forks and sets CPU affinity for the child process. Ignores 'start' and 'arg'
+ * thread parameters.
+ *
+ * @param[out] proc Pointer to process state info (for output)
+ * @param cpu Destination CPU for the child process
+ * @param thr_params Linux helper thread parameters
+ *
+ * @return On success: 1 for the parent, 0 for the child
+ * On failure: -1 for the parent, -2 for the child
+ */
+int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
+ const odph_linux_thr_params_t *thr_params);
+
+/**
+ * Fork a number of processes
+ *
+ * Forks and sets CPU affinity for child processes. Ignores 'start' and 'arg'
+ * thread parameters.
+ *
+ * @param[out] proc_tbl Process state info table (for output)
+ * @param mask CPU mask of processes to create
+ * @param thr_params Linux helper thread parameters
+ *
+ * @return On success: 1 for the parent, 0 for the child
+ * On failure: -1 for the parent, -2 for the child
+ */
+int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
+ const odp_cpumask_t *mask,
+ const odph_linux_thr_params_t *thr_params);
+
+/**
+ * Wait for a number of processes
+ *
+ * Waits for a number of child processes to terminate. Records process state
+ * change status into the process state info structure.
+ *
+ * @param proc_tbl Process state info table (previously filled by fork)
+ * @param num Number of processes to wait
+ *
+ * @return 0 on success, -1 on failure
+ */
+int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
@@ -93,82 +93,6 @@ typedef struct {
} odph_odpthread_t;
/**
- * Creates and launches pthreads
- *
- * Creates, pins and launches threads to separate CPU's based on the cpumask.
- *
- * @param[out] pthread_tbl Table of pthread state information records. Table
- * must have at least as many entries as there are
- * CPUs in the CPU mask.
- * @param mask CPU mask
- * @param thr_params Linux helper thread parameters
- *
- * @return Number of threads created
- */
-int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
- const odp_cpumask_t *mask,
- const odph_linux_thr_params_t *thr_params);
-
-/**
- * Waits pthreads to exit
- *
- * Returns when all threads have been exit.
- *
- * @param thread_tbl Thread table
- * @param num Number of threads to create
- *
- */
-void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num);
-
-/**
- * Fork a process
- *
- * Forks and sets CPU affinity for the child process. Ignores 'start' and 'arg'
- * thread parameters.
- *
- * @param[out] proc Pointer to process state info (for output)
- * @param cpu Destination CPU for the child process
- * @param thr_params Linux helper thread parameters
- *
- * @return On success: 1 for the parent, 0 for the child
- * On failure: -1 for the parent, -2 for the child
- */
-int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
- const odph_linux_thr_params_t *thr_params);
-
-
-/**
- * Fork a number of processes
- *
- * Forks and sets CPU affinity for child processes. Ignores 'start' and 'arg'
- * thread parameters.
- *
- * @param[out] proc_tbl Process state info table (for output)
- * @param mask CPU mask of processes to create
- * @param thr_params Linux helper thread parameters
- *
- * @return On success: 1 for the parent, 0 for the child
- * On failure: -1 for the parent, -2 for the child
- */
-int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
- const odp_cpumask_t *mask,
- const odph_linux_thr_params_t *thr_params);
-
-
-/**
- * Wait for a number of processes
- *
- * Waits for a number of child processes to terminate. Records process state
- * change status into the process state info structure.
- *
- * @param proc_tbl Process state info table (previously filled by fork)
- * @param num Number of processes to wait
- *
- * @return 0 on success, -1 on failure
- */
-int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num);
-
-/**
* Creates and launches odpthreads (as linux threads or processes)
*
* Creates, pins and launches threads to separate CPU's based on the cpumask.
@@ -8,5 +8,16 @@ AC_ARG_ENABLE([test-helper],
test_helper=yes
fi])
+##########################################################################
+# Enable/disable helper-ext
+# platform specific non portable extensions
+##########################################################################
+helper_extn=no
+AC_ARG_ENABLE([helper-extn],
+ [ --enable-helper-extn build helper platform extensions (not portable)],
+ [if test "x$enableval" = "xyes"; then
+ helper_extn=yes
+ fi])
+
AC_CONFIG_FILES([helper/Makefile
helper/test/Makefile])
new file mode 100644
@@ -0,0 +1,313 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include <odp_api.h>
+#include <odp/helper/platform/linux-generic/threads_extn.h>
+#include "odph_debug.h"
+
+static void *_odph_run_start_routine(void *arg)
+{
+ odph_linux_thr_params_t *thr_params = arg;
+
+ /* ODP thread local init */
+ if (odp_init_local(thr_params->instance, thr_params->thr_type)) {
+ ODPH_ERR("Local init failed\n");
+ return NULL;
+ }
+
+ void *ret_ptr = thr_params->start(thr_params->arg);
+ int ret = odp_term_local();
+
+ if (ret < 0)
+ ODPH_ERR("Local term failed\n");
+
+ return ret_ptr;
+}
+
+static void *_odph_thread_run_start_routine(void *arg)
+{
+ int status;
+ int ret;
+ odph_odpthread_params_t *thr_params;
+
+ odph_odpthread_start_args_t *start_args = arg;
+
+ thr_params = &start_args->thr_params;
+
+ /* ODP thread local init */
+ if (odp_init_local(thr_params->instance, thr_params->thr_type)) {
+ ODPH_ERR("Local init failed\n");
+ if (start_args->linuxtype == ODPTHREAD_PROCESS)
+ _exit(EXIT_FAILURE);
+ return (void *)-1;
+ }
+
+ ODPH_DBG("helper: ODP %s thread started as linux %s. (pid=%d)\n",
+ thr_params->thr_type == ODP_THREAD_WORKER ?
+ "worker" : "control",
+ (start_args->linuxtype == ODPTHREAD_PTHREAD) ?
+ "pthread" : "process",
+ (int)getpid());
+
+ status = thr_params->start(thr_params->arg);
+ ret = odp_term_local();
+
+ if (ret < 0)
+ ODPH_ERR("Local term failed\n");
+
+ /* for process implementation of odp threads, just return status... */
+ if (start_args->linuxtype == ODPTHREAD_PROCESS)
+ _exit(status);
+
+ /* threads implementation return void* pointers: cast status to that. */
+ return (void *)(intptr_t)status;
+}
+
+int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
+ const odp_cpumask_t *mask,
+ const odph_linux_thr_params_t *thr_params)
+{
+ int i;
+ int num;
+ int cpu_count;
+ int cpu;
+ int ret;
+
+ num = odp_cpumask_count(mask);
+
+ memset(pthread_tbl, 0, num * sizeof(odph_linux_pthread_t));
+
+ cpu_count = odp_cpu_count();
+
+ if (num < 1 || num > cpu_count) {
+ ODPH_ERR("Invalid number of threads:%d (%d cores available)\n",
+ num, cpu_count);
+ return 0;
+ }
+
+ cpu = odp_cpumask_first(mask);
+ for (i = 0; i < num; i++) {
+ cpu_set_t cpu_set;
+
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu, &cpu_set);
+
+ pthread_attr_init(&pthread_tbl[i].attr);
+
+ pthread_tbl[i].cpu = cpu;
+
+ pthread_attr_setaffinity_np(&pthread_tbl[i].attr,
+ sizeof(cpu_set_t), &cpu_set);
+
+ pthread_tbl[i].thr_params.start = thr_params->start;
+ pthread_tbl[i].thr_params.arg = thr_params->arg;
+ pthread_tbl[i].thr_params.thr_type = thr_params->thr_type;
+ pthread_tbl[i].thr_params.instance = thr_params->instance;
+
+ ret = pthread_create(&pthread_tbl[i].thread,
+ &pthread_tbl[i].attr,
+ _odph_run_start_routine,
+ &pthread_tbl[i].thr_params);
+ if (ret != 0) {
+ ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
+ break;
+ }
+
+ cpu = odp_cpumask_next(mask, cpu);
+ }
+
+ return i;
+}
+
+void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < num; i++) {
+ /* Wait thread to exit */
+ ret = pthread_join(thread_tbl[i].thread, NULL);
+ if (ret != 0) {
+ ODPH_ERR("Failed to join thread from cpu #%d\n",
+ thread_tbl[i].cpu);
+ }
+ pthread_attr_destroy(&thread_tbl[i].attr);
+ }
+}
+
+int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
+ const odp_cpumask_t *mask,
+ const odph_linux_thr_params_t *thr_params)
+{
+ pid_t pid;
+ int num;
+ int cpu_count;
+ int cpu;
+ int i;
+
+ num = odp_cpumask_count(mask);
+
+ memset(proc_tbl, 0, num * sizeof(odph_linux_process_t));
+
+ cpu_count = odp_cpu_count();
+
+ if (num < 1 || num > cpu_count) {
+ ODPH_ERR("Bad num\n");
+ return -1;
+ }
+
+ cpu = odp_cpumask_first(mask);
+ for (i = 0; i < num; i++) {
+ cpu_set_t cpu_set;
+
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu, &cpu_set);
+
+ pid = fork();
+
+ if (pid < 0) {
+ ODPH_ERR("fork() failed\n");
+ return -1;
+ }
+
+ /* Parent continues to fork */
+ if (pid > 0) {
+ proc_tbl[i].pid = pid;
+ proc_tbl[i].cpu = cpu;
+
+ cpu = odp_cpumask_next(mask, cpu);
+ continue;
+ }
+
+ /* Child process */
+
+ /* Request SIGTERM if parent dies */
+ prctl(PR_SET_PDEATHSIG, SIGTERM);
+ /* Parent died already? */
+ if (getppid() == 1)
+ kill(getpid(), SIGTERM);
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set)) {
+ ODPH_ERR("sched_setaffinity() failed\n");
+ return -2;
+ }
+
+ if (odp_init_local(thr_params->instance,
+ thr_params->thr_type)) {
+ ODPH_ERR("Local init failed\n");
+ return -2;
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
+ const odph_linux_thr_params_t *thr_params)
+{
+ odp_cpumask_t mask;
+
+ odp_cpumask_zero(&mask);
+ odp_cpumask_set(&mask, cpu);
+ return odph_linux_process_fork_n(proc, &mask, thr_params);
+}
+
+int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num)
+{
+ pid_t pid;
+ int i, j;
+ int status = 0;
+
+ for (i = 0; i < num; i++) {
+ pid = wait(&status);
+
+ if (pid < 0) {
+ ODPH_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) {
+ ODPH_ERR("Bad pid:%d\n", (int)pid);
+ return -1;
+ }
+
+ /* Examine the child process' termination status */
+ if (WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS) {
+ ODPH_ERR("Child exit status:%d (pid:%d)\n",
+ WEXITSTATUS(status), (int)pid);
+ return -1;
+ }
+ if (WIFSIGNALED(status)) {
+ int signo = WTERMSIG(status);
+
+ ODPH_ERR("Child term signo:%d - %s (pid:%d)\n",
+ signo, strsignal(signo), (int)pid);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Create a single ODPthread as a linux thread
+ */
+static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,
+ int cpu,
+ const odph_odpthread_params_t *thr_params)
+{
+ int ret;
+ cpu_set_t cpu_set;
+
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu, &cpu_set);
+
+ pthread_attr_init(&thread_tbl->thread.attr);
+
+ thread_tbl->cpu = cpu;
+
+ pthread_attr_setaffinity_np(&thread_tbl->thread.attr,
+ sizeof(cpu_set_t), &cpu_set);
+
+ thread_tbl->start_args.thr_params = *thr_params; /* copy */
+ thread_tbl->start_args.linuxtype = ODPTHREAD_PTHREAD;
+
+ ret = pthread_create(&thread_tbl->thread.thread_id,
+ &thread_tbl->thread.attr,
+ _odph_thread_run_start_routine,
+ &thread_tbl->start_args);
+ if (ret != 0) {
+ ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
+ thread_tbl->start_args.linuxtype = ODPTHREAD_NOT_STARTED;
+ return ret;
+ }
+
+ return 0;
+}
@@ -6,11 +6,18 @@ AM_LDFLAGS += -static
TESTS_ENVIRONMENT += TEST_DIR=${builddir}
EXECUTABLES = chksum$(EXEEXT) \
- thread$(EXEEXT) \
parse$(EXEEXT)\
- process$(EXEEXT)\
table$(EXEEXT)
+#These are platform specific extensions that are not portable
+#They are a convenience to app writers who have chosen to
+#restrict their application to Linux.
+
+if helper_extn
+EXECUTABLES += @with_helper_platform@/thread$(EXEEXT) \
+ @with_helper_platform@/process$(EXEEXT)
+endif
+
COMPILE_ONLY = odpthreads
TESTSCRIPTS = odpthreads_as_processes \
@@ -28,10 +35,6 @@ EXTRA_DIST = odpthreads_as_processes odpthreads_as_pthreads
dist_chksum_SOURCES = chksum.c
dist_odpthreads_SOURCES = odpthreads.c
-odpthreads_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
-dist_thread_SOURCES = thread.c
-thread_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
-dist_process_SOURCES = process.c
+odpthreads_LDADD = $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
dist_parse_SOURCES = parse.c
-process_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
dist_table_SOURCES = table.c
new file mode 100644
@@ -0,0 +1,5 @@
+
+thread_LDADD = $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
+dist_thread_SOURCES = thread.c
+dist_process_SOURCES = process.c
+process_LDADD = $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
similarity index 97%
rename from helper/test/process.c
rename to helper/test/linux-generic/process.c
@@ -6,7 +6,7 @@
#include <test_debug.h>
#include <odp_api.h>
-#include <odp/helper/threads.h>
+#include <odp/helper/platform/linux-generic/threads_extn.h>
#define NUMBER_WORKERS 16 /* 0 = max */
similarity index 97%
rename from helper/test/thread.c
rename to helper/test/linux-generic/thread.c
@@ -6,7 +6,7 @@
#include <test_debug.h>
#include <odp_api.h>
-#include <odp/helper/threads.h>
+#include <odp/helper/platform/linux-generic/threads_extn.h>
#define NUMBER_WORKERS 16
static void *worker_fn(void *arg TEST_UNUSED)
@@ -9,16 +9,10 @@
#endif
#include <sched.h>
#include <unistd.h>
-#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdbool.h>
-
#include <odp_api.h>
#include <odp/helper/threads.h>
#include "odph_debug.h"
@@ -27,225 +21,11 @@ static struct {
int proc; /* true when process mode is required, false otherwise */
} helper_options;
-static void *odp_run_start_routine(void *arg)
-{
- odph_linux_thr_params_t *thr_params = arg;
-
- /* ODP thread local init */
- if (odp_init_local(thr_params->instance, thr_params->thr_type)) {
- ODPH_ERR("Local init failed\n");
- return NULL;
- }
-
- void *ret_ptr = thr_params->start(thr_params->arg);
- int ret = odp_term_local();
-
- if (ret < 0)
- ODPH_ERR("Local term failed\n");
-
- return ret_ptr;
-}
-
-int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
- const odp_cpumask_t *mask,
- const odph_linux_thr_params_t *thr_params)
-{
- int i;
- int num;
- int cpu_count;
- int cpu;
- int ret;
-
- num = odp_cpumask_count(mask);
-
- memset(pthread_tbl, 0, num * sizeof(odph_linux_pthread_t));
-
- cpu_count = odp_cpu_count();
-
- if (num < 1 || num > cpu_count) {
- ODPH_ERR("Invalid number of threads:%d (%d cores available)\n",
- num, cpu_count);
- return 0;
- }
-
- cpu = odp_cpumask_first(mask);
- for (i = 0; i < num; i++) {
- cpu_set_t cpu_set;
-
- CPU_ZERO(&cpu_set);
- CPU_SET(cpu, &cpu_set);
-
- pthread_attr_init(&pthread_tbl[i].attr);
-
- pthread_tbl[i].cpu = cpu;
-
- pthread_attr_setaffinity_np(&pthread_tbl[i].attr,
- sizeof(cpu_set_t), &cpu_set);
-
- pthread_tbl[i].thr_params.start = thr_params->start;
- pthread_tbl[i].thr_params.arg = thr_params->arg;
- pthread_tbl[i].thr_params.thr_type = thr_params->thr_type;
- pthread_tbl[i].thr_params.instance = thr_params->instance;
-
- ret = pthread_create(&pthread_tbl[i].thread,
- &pthread_tbl[i].attr,
- odp_run_start_routine,
- &pthread_tbl[i].thr_params);
- if (ret != 0) {
- ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
- break;
- }
-
- cpu = odp_cpumask_next(mask, cpu);
- }
-
- return i;
-}
-
-void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num)
-{
- int i;
- int ret;
-
- for (i = 0; i < num; i++) {
- /* Wait thread to exit */
- ret = pthread_join(thread_tbl[i].thread, NULL);
- if (ret != 0) {
- ODPH_ERR("Failed to join thread from cpu #%d\n",
- thread_tbl[i].cpu);
- }
- pthread_attr_destroy(&thread_tbl[i].attr);
- }
-}
-
-int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
- const odp_cpumask_t *mask,
- const odph_linux_thr_params_t *thr_params)
-{
- pid_t pid;
- int num;
- int cpu_count;
- int cpu;
- int i;
-
- num = odp_cpumask_count(mask);
-
- memset(proc_tbl, 0, num * sizeof(odph_linux_process_t));
-
- cpu_count = odp_cpu_count();
-
- if (num < 1 || num > cpu_count) {
- ODPH_ERR("Bad num\n");
- return -1;
- }
-
- cpu = odp_cpumask_first(mask);
- for (i = 0; i < num; i++) {
- cpu_set_t cpu_set;
-
- CPU_ZERO(&cpu_set);
- CPU_SET(cpu, &cpu_set);
-
- pid = fork();
-
- if (pid < 0) {
- ODPH_ERR("fork() failed\n");
- return -1;
- }
-
- /* Parent continues to fork */
- if (pid > 0) {
- proc_tbl[i].pid = pid;
- proc_tbl[i].cpu = cpu;
-
- cpu = odp_cpumask_next(mask, cpu);
- continue;
- }
-
- /* Child process */
-
- /* Request SIGTERM if parent dies */
- prctl(PR_SET_PDEATHSIG, SIGTERM);
- /* Parent died already? */
- if (getppid() == 1)
- kill(getpid(), SIGTERM);
-
- if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set)) {
- ODPH_ERR("sched_setaffinity() failed\n");
- return -2;
- }
-
- if (odp_init_local(thr_params->instance,
- thr_params->thr_type)) {
- ODPH_ERR("Local init failed\n");
- return -2;
- }
-
- return 0;
- }
-
- return 1;
-}
-
-int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
- const odph_linux_thr_params_t *thr_params)
-{
- odp_cpumask_t mask;
-
- odp_cpumask_zero(&mask);
- odp_cpumask_set(&mask, cpu);
- return odph_linux_process_fork_n(proc, &mask, thr_params);
-}
-
-int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num)
-{
- pid_t pid;
- int i, j;
- int status = 0;
-
- for (i = 0; i < num; i++) {
- pid = wait(&status);
-
- if (pid < 0) {
- ODPH_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) {
- ODPH_ERR("Bad pid:%d\n", (int)pid);
- return -1;
- }
-
- /* Examine the child process' termination status */
- if (WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS) {
- ODPH_ERR("Child exit status:%d (pid:%d)\n",
- WEXITSTATUS(status), (int)pid);
- return -1;
- }
- if (WIFSIGNALED(status)) {
- int signo = WTERMSIG(status);
-
- ODPH_ERR("Child term signo:%d - %s (pid:%d)\n",
- signo, strsignal(signo), (int)pid);
- return -1;
- }
- }
-
- return 0;
-}
-
/*
* wrapper for odpthreads, either implemented as linux threads or processes.
* (in process mode, if start_routine returns NULL, the process return FAILURE).
*/
-static void *odpthread_run_start_routine(void *arg)
+static void *_odph_thread_run_start_routine(void *arg)
{
int status;
int ret;
@@ -287,9 +67,9 @@ static void *odpthread_run_start_routine(void *arg)
/*
* Create a single ODPthread as a linux process
*/
-static int odph_linux_process_create(odph_odpthread_t *thread_tbl,
- int cpu,
- const odph_odpthread_params_t *thr_params)
+static int _odph_linux_process_create(odph_odpthread_t *thread_tbl,
+ int cpu,
+ const odph_odpthread_params_t *thr_params)
{
cpu_set_t cpu_set;
pid_t pid;
@@ -327,7 +107,7 @@ static int odph_linux_process_create(odph_odpthread_t *thread_tbl,
return -2;
}
- odpthread_run_start_routine(&thread_tbl->start_args);
+ _odph_thread_run_start_routine(&thread_tbl->start_args);
return 0; /* never reached */
}
@@ -357,7 +137,7 @@ static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,
ret = pthread_create(&thread_tbl->thread.thread_id,
&thread_tbl->thread.attr,
- odpthread_run_start_routine,
+ _odph_thread_run_start_routine,
&thread_tbl->start_args);
if (ret != 0) {
ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
@@ -401,9 +181,9 @@ int odph_odpthreads_create(odph_odpthread_t *thread_tbl,
thr_params))
break;
} else {
- if (odph_linux_process_create(&thread_tbl[i],
- cpu,
- thr_params))
+ if (_odph_linux_process_create(&thread_tbl[i],
+ cpu,
+ thr_params))
break;
}
similarity index 72%
rename from pkgconfig/libodphelper-linux.pc.in
rename to pkgconfig/libodphelper-linux-generic.pc.in
@@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: libodphelper-linux
+Name: libodphelper-linux-generic
Description: Helper for the ODP packet processing engine
Version: @PKGCONFIG_VERSION@
-Libs: -L${libdir} -lodphelper-linux
+Libs: -L${libdir} -lodphelper-linux-generic
Libs.private:
Cflags: -I${includedir}
@@ -4,7 +4,7 @@ LIB = $(top_builddir)/lib
#in the following line, the libs using the symbols should come before
#the libs containing them! The includer is given a chance to add things
#before libodp by setting PRE_LDADD before the inclusion.
-LDADD = $(PRE_LDADD) $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
+LDADD = $(PRE_LDADD) $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
INCFLAGS = \
-I$(top_builddir)/platform/@with_platform@/include \
@@ -13,4 +13,4 @@ AM_LDFLAGS += -static
LIBCUNIT_COMMON = $(COMMON_DIR)/libcunit_common.la
LIBCPUMASK_COMMON = $(COMMON_DIR)/libcpumask_common.la
LIBTHRMASK_COMMON = $(COMMON_DIR)/libthrmask_common.la
-LIBODP = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
+LIBODP = $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
@@ -6,7 +6,7 @@ AM_LDFLAGS += -static
LIBCUNIT_COMMON = $(top_builddir)/test/common_plat/common/libcunit_common.la
LIB = $(top_builddir)/lib
-LIBODP = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
+LIBODP = $(LIB)/libodphelper-@with_helper_platform@.la $(LIB)/libodp-linux.la
INCCUNIT_COMMON = -I$(top_srcdir)/test/common_plat/common
INCODP = \
Only the portable api is built by default, use --enable-helper-extn to enable non portable APIs for a helper platform Signed-off-by: Mike Holmes <mike.holmes@linaro.org> --- configure.ac | 17 +- example/Makefile.inc | 2 +- helper/Makefile.am | 14 +- .../helper/platform/linux-generic/threads_extn.h | 112 ++++++++ helper/include/odp/helper/threads.h | 76 ----- helper/m4/configure.m4 | 11 + helper/platform/linux-generic/thread.c | 313 +++++++++++++++++++++ helper/test/Makefile.am | 17 +- helper/test/linux-generic/Makefile.am | 5 + helper/test/{ => linux-generic}/process.c | 2 +- helper/test/{ => linux-generic}/thread.c | 2 +- helper/threads.c | 238 +--------------- ...inux.pc.in => libodphelper-linux-generic.pc.in} | 4 +- test/Makefile.inc | 2 +- test/common_plat/validation/api/Makefile.inc | 2 +- test/linux-generic/Makefile.inc | 2 +- 16 files changed, 494 insertions(+), 325 deletions(-) create mode 100644 helper/include/odp/helper/platform/linux-generic/threads_extn.h create mode 100644 helper/platform/linux-generic/thread.c create mode 100644 helper/test/linux-generic/Makefile.am rename helper/test/{ => linux-generic}/process.c (97%) rename helper/test/{ => linux-generic}/thread.c (97%) rename pkgconfig/{libodphelper-linux.pc.in => libodphelper-linux-generic.pc.in} (72%) -- 2.9.3