On 3 February 2017 at 07:28, Christophe Milard
<christophe.mil...@linaro.org> wrote:
> On 3 February 2017 at 12:23, Petri Savolainen
> <petri.savolai...@linaro.org> wrote:
>> There's no platform specific helpers. Helpers may depend on
>> Linux and make it easier to do common series of Linux system
>> calls. These kind of helpers are grouped into helper/linux
>> directory.
>
> This is getting really confusing to me! Haven't we defined a
> "platform" as being a couple {OS, HW}? That is any change in this
> couple makes a new platform...
> If we hold to this definition, then linux-helpers becomes platform helpers...
> Now, my humble opinion is that no-one is using these linux-only
> helpers and no one ever will unless to enforce their usage by example
> that people could copy/paste: why would a programmer want to replace a
> well known linux system call by an ODP helper call? to save a for
> loop?.
> We are hitting the same usual problem of lack of proper definition for
> things, but in this special case, my proposal is called "deletion".
> :-)
>

CC Sorin, I think OFP may be using them, but I am not sure that it
needs to, if OFP wants to be Linux specific its not hard to call
pthreads etc yourself.

Have we established that these are not better off as tested examples /
docs rather than actually in a helpers lib. Given that we do not use
them in odp-linux at all it feels that they are just clutter.

Another angle is that maybe this problem is due to having the tests
for all platforms and OS'es in the same repo as a specific linux
implimentation, perhaps with the tests all moved out it becomes much
clearer and odp-linux the implimentation is free to be entirely Linux
centric becasue the tests will use the agnostic API in a separate repo

I am glad that we are finally digging though the helpers to get them right


> Christophe
>
>>
>> Use --enable-helper-linux configuration option to enable
>> support for Linux helpers.
>>
>> Signed-off-by: Petri Savolainen <petri.savolai...@linaro.org>
>> ---
>>  configure.ac                                       |  17 +-
>>  example/Makefile.inc                               |   2 +-
>>  helper/Makefile.am                                 |  18 +-
>>  helper/include/odp/helper/linux/process.h          |  84 ++++++
>>  helper/include/odp/helper/linux/pthread.h          |  66 +++++
>>  .../helper/platform/linux-generic/threads_extn.h   | 112 --------
>>  helper/linux/thread.c                              | 239 ++++++++++++++++
>>  helper/m4/configure.m4                             |   8 +-
>>  helper/platform/linux-generic/thread.c             | 313 
>> ---------------------
>>  helper/test/.gitignore                             |   1 +
>>  helper/test/Makefile.am                            |   9 +-
>>  helper/test/linux-generic/Makefile.am              |   5 -
>>  helper/test/linux-generic/process.c                |  92 ------
>>  helper/test/linux-generic/thread.c                 |  87 ------
>>  helper/test/linux/Makefile.am                      |   5 +
>>  helper/test/linux/process.c                        |  93 ++++++
>>  helper/test/linux/pthread.c                        |  87 ++++++
>>  test/Makefile.inc                                  |   2 +-
>>  test/common_plat/validation/api/Makefile.inc       |   2 +-
>>  test/linux-generic/Makefile.inc                    |   2 +-
>>  20 files changed, 599 insertions(+), 645 deletions(-)
>>  create mode 100644 helper/include/odp/helper/linux/process.h
>>  create mode 100644 helper/include/odp/helper/linux/pthread.h
>>  delete mode 100644 
>> helper/include/odp/helper/platform/linux-generic/threads_extn.h
>>  create mode 100644 helper/linux/thread.c
>>  delete mode 100644 helper/platform/linux-generic/thread.c
>>  delete mode 100644 helper/test/linux-generic/Makefile.am
>>  delete mode 100644 helper/test/linux-generic/process.c
>>  delete mode 100644 helper/test/linux-generic/thread.c
>>  create mode 100644 helper/test/linux/Makefile.am
>>  create mode 100644 helper/test/linux/process.c
>>  create mode 100644 helper/test/linux/pthread.c
>>
>> diff --git a/configure.ac b/configure.ac
>> index daa9b31..b672a1a 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -138,18 +138,6 @@ 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=""
>> @@ -214,7 +202,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 ])
>> +AM_CONDITIONAL([helper_linux], [test x$helper_linux = xyes ])
>>
>>  ##########################################################################
>>  # Setup doxygen documentation
>> @@ -345,8 +333,7 @@ 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}
>> +       helper_linux:           ${helper_linux}
>>         prefix:                 ${prefix}
>>         sysconfdir:             ${sysconfdir}
>>         libdir:                 ${libdir}
>> diff --git a/example/Makefile.inc b/example/Makefile.inc
>> index ea596d5..70e3758 100644
>> --- a/example/Makefile.inc
>> +++ b/example/Makefile.inc
>> @@ -1,6 +1,6 @@
>>  include $(top_srcdir)/platform/@with_platform@/Makefile.inc
>>  LIB   = $(top_builddir)/lib
>> -LDADD = $(LIB)/libodp-linux.la $(LIB)/libodphelper-@with_helper_platform@.la
>> +LDADD = $(LIB)/libodp-linux.la $(LIB)/libodphelper.la
>>  AM_CFLAGS += \
>>         -I$(srcdir) \
>>         -I$(top_srcdir)/example \
>> diff --git a/helper/Makefile.am b/helper/Makefile.am
>> index d484679..9b6e3ce 100644
>> --- a/helper/Makefile.am
>> +++ b/helper/Makefile.am
>> @@ -30,16 +30,18 @@ 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
>> +if helper_linux
>> +helperlinuxincludedir = $(includedir)/odp/helper/linux
>> +helperlinuxinclude_HEADERS = \
>> +                 $(srcdir)/include/odp/helper/linux/pthread.h \
>> +                 $(srcdir)/include/odp/helper/linux/process.h
>>  endif
>>
>>  noinst_HEADERS = \
>>                  $(srcdir)/odph_debug.h \
>>                  $(srcdir)/odph_list_internal.h
>>
>> -__LIB__libodphelper_@with_platform@_la_SOURCES = \
>> +__LIB__libodphelper_la_SOURCES = \
>>                                         eth.c \
>>                                         ip.c \
>>                                         chksum.c \
>> @@ -49,9 +51,9 @@ __LIB__libodphelper_@with_platform@_la_SOURCES = \
>>                                         iplookuptable.c \
>>                                         threads.c
>>
>> -if helper_extn
>> -__LIB__libodphelper_@with_platform@_la_SOURCES += \
>> -                                       
>> platform/@with_helper_platform@/thread.c
>> +if helper_linux
>> +__LIB__libodphelper_la_SOURCES += \
>> +                               linux/thread.c
>>  endif
>>
>> -lib_LTLIBRARIES = $(LIB)/libodphelper-@with_platform@.la
>> +lib_LTLIBRARIES = $(LIB)/libodphelper.la
>> diff --git a/helper/include/odp/helper/linux/process.h 
>> b/helper/include/odp/helper/linux/process.h
>> new file mode 100644
>> index 0000000..9d74146
>> --- /dev/null
>> +++ b/helper/include/odp/helper/linux/process.h
>> @@ -0,0 +1,84 @@
>> +/* Copyright (c) 2017, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:     BSD-3-Clause
>> + */
>> +
>> +/**
>> + * @file
>> + *
>> + * ODP Linux helper for processes
>> + *
>> + * This file is not part of ODP APIs, but can be optionally used to ease 
>> common
>> + * setups in a Linux system. User is free to implement the same setups in
>> + * otherways (not via this file).
>> + */
>> +
>> +#ifndef ODPH_LINUX_PROCESS_H_
>> +#define ODPH_LINUX_PROCESS_H_
>> +
>> +#include <odp/helper/threads.h>
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +/** @ingroup odph_linux
>> + *  @{
>> + */
>> +
>> +/**
>> + * 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
>> diff --git a/helper/include/odp/helper/linux/pthread.h 
>> b/helper/include/odp/helper/linux/pthread.h
>> new file mode 100644
>> index 0000000..feeda5e
>> --- /dev/null
>> +++ b/helper/include/odp/helper/linux/pthread.h
>> @@ -0,0 +1,66 @@
>> +/* Copyright (c) 2017, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:     BSD-3-Clause
>> + */
>> +
>> +/**
>> + * @file
>> + *
>> + * ODP Linux helper for pthreads
>> + *
>> + * This file is not part of ODP APIs, but can be optionally used to ease 
>> common
>> + * setups in a Linux system. User is free to implement the same setups in
>> + * otherways (not via this file).
>> + */
>> +
>> +#ifndef ODPH_LINUX_PTHREAD_H_
>> +#define ODPH_LINUX_PTHREAD_H_
>> +
>> +#include <odp/helper/threads.h>
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +/** @ingroup 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);
>> +
>> +/**
>> + * @}
>> + */
>> +
>> +#ifdef __cplusplus
>> +}
>> +#endif
>> +
>> +#endif
>> diff --git a/helper/include/odp/helper/platform/linux-generic/threads_extn.h 
>> b/helper/include/odp/helper/platform/linux-generic/threads_extn.h
>> deleted file mode 100644
>> index 1d4036d..0000000
>> --- a/helper/include/odp/helper/platform/linux-generic/threads_extn.h
>> +++ /dev/null
>> @@ -1,112 +0,0 @@
>> -/* 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
>> diff --git a/helper/linux/thread.c b/helper/linux/thread.c
>> new file mode 100644
>> index 0000000..52d4efc
>> --- /dev/null
>> +++ b/helper/linux/thread.c
>> @@ -0,0 +1,239 @@
>> +/* 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/linux/pthread.h>
>> +#include <odp/helper/linux/process.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;
>> +}
>> +
>> +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;
>> +}
>> diff --git a/helper/m4/configure.m4 b/helper/m4/configure.m4
>> index 38c95d9..343f5e3 100644
>> --- a/helper/m4/configure.m4
>> +++ b/helper/m4/configure.m4
>> @@ -12,11 +12,11 @@ AC_ARG_ENABLE([test-helper],
>>  # 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)],
>> +helper_linux=no
>> +AC_ARG_ENABLE([helper-linux],
>> +       [  --enable-helper-linux        build helper platform extensions 
>> (not portable)],
>>         [if test "x$enableval" = "xyes"; then
>> -               helper_extn=yes
>> +               helper_linux=yes
>>         fi])
>>
>>  AC_CONFIG_FILES([helper/Makefile
>> diff --git a/helper/platform/linux-generic/thread.c 
>> b/helper/platform/linux-generic/thread.c
>> deleted file mode 100644
>> index 90fa42a..0000000
>> --- a/helper/platform/linux-generic/thread.c
>> +++ /dev/null
>> @@ -1,313 +0,0 @@
>> -/* 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;
>> -}
>> diff --git a/helper/test/.gitignore b/helper/test/.gitignore
>> index e5b6a0f..1a81e00 100644
>> --- a/helper/test/.gitignore
>> +++ b/helper/test/.gitignore
>> @@ -8,3 +8,4 @@ parse
>>  process
>>  table
>>  thread
>> +pthread
>> diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
>> index 1c50282..99b6df8 100644
>> --- a/helper/test/Makefile.am
>> +++ b/helper/test/Makefile.am
>> @@ -5,12 +5,11 @@ 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-@with_helper_platform@.la 
>> $(LIB)/libodp-linux.la
>> +LDADD = $(PRE_LDADD) $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>>
>>  INCFLAGS = \
>>         -I$(top_builddir)/platform/@with_platform@/include \
>>         -I$(top_srcdir)/helper/include \
>> -       -I$(top_srcdir)/helper/platform/@with_helper_platform@/include \
>>         -I$(top_srcdir)/include \
>>         -I$(top_srcdir)/platform/@with_platform@/include \
>>         -I$(top_builddir)/include \
>> @@ -31,9 +30,9 @@ EXECUTABLES = chksum$(EXEEXT) \
>>  #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)
>> +if helper_linux
>> +EXECUTABLES += linux/pthread$(EXEEXT) \
>> +              linux/process$(EXEEXT)
>>  endif
>>
>>  COMPILE_ONLY = odpthreads
>> diff --git a/helper/test/linux-generic/Makefile.am 
>> b/helper/test/linux-generic/Makefile.am
>> deleted file mode 100644
>> index 28d54a8..0000000
>> --- a/helper/test/linux-generic/Makefile.am
>> +++ /dev/null
>> @@ -1,5 +0,0 @@
>> -
>> -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
>> diff --git a/helper/test/linux-generic/process.c 
>> b/helper/test/linux-generic/process.c
>> deleted file mode 100644
>> index f9bdc3e..0000000
>> --- a/helper/test/linux-generic/process.c
>> +++ /dev/null
>> @@ -1,92 +0,0 @@
>> -/* Copyright (c) 2015, Linaro Limited
>> - * All rights reserved.
>> - *
>> - * SPDX-License-Identifier:     BSD-3-Clause
>> - */
>> -
>> -#include <odph_debug.h>
>> -#include <odp_api.h>
>> -#include <odp/helper/platform/linux-generic/threads_extn.h>
>> -
>> -#define NUMBER_WORKERS 16 /* 0 = max */
>> -
>> -static void *worker_fn(void *arg ODPH_UNUSED)
>> -{
>> -       /* depend on the odp helper to call odp_init_local */
>> -       printf("Worker thread on CPU %d\n", odp_cpu_id());
>> -
>> -       return 0;
>> -}
>> -
>> -/* Create additional dataplane processes */
>> -int main(int argc ODPH_UNUSED, char *argv[] ODPH_UNUSED)
>> -{
>> -       odp_cpumask_t cpu_mask;
>> -       int num_workers;
>> -       int cpu;
>> -       char cpumaskstr[ODP_CPUMASK_STR_SIZE];
>> -       int ret;
>> -       odph_linux_process_t proc[NUMBER_WORKERS];
>> -       odp_instance_t instance;
>> -       odph_linux_thr_params_t thr_params;
>> -
>> -       if (odp_init_global(&instance, NULL, NULL)) {
>> -               ODPH_ERR("Error: ODP global init failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
>> -               ODPH_ERR("Error: ODP local init failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       /* discover how many processes this system can support */
>> -       num_workers = odp_cpumask_default_worker(&cpu_mask, NUMBER_WORKERS);
>> -       if (num_workers < NUMBER_WORKERS) {
>> -               printf("System can only support %d processes and not the %d 
>> requested\n",
>> -                      num_workers, NUMBER_WORKERS);
>> -       }
>> -
>> -       /* generate a summary for the user */
>> -       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> -       printf("default cpu mask:           %s\n", cpumaskstr);
>> -       printf("default num worker processes: %i\n", num_workers);
>> -
>> -       cpu = odp_cpumask_first(&cpu_mask);
>> -       printf("the first CPU:              %i\n", cpu);
>> -
>> -       /* reserve cpu 0 for the control plane so remove it from
>> -        * the default mask */
>> -       odp_cpumask_clr(&cpu_mask, 0);
>> -       num_workers = odp_cpumask_count(&cpu_mask);
>> -       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> -       printf("new cpu mask:               %s\n", cpumaskstr);
>> -       printf("new num worker processes:     %i\n\n", num_workers);
>> -
>> -       memset(&thr_params, 0, sizeof(thr_params));
>> -       thr_params.thr_type = ODP_THREAD_WORKER;
>> -       thr_params.instance = instance;
>> -
>> -       /* Fork worker processes */
>> -       ret = odph_linux_process_fork_n(proc, &cpu_mask, &thr_params);
>> -
>> -       if (ret < 0) {
>> -               ODPH_ERR("Fork workers failed %i\n", ret);
>> -               return -1;
>> -       }
>> -
>> -       if (ret == 0) {
>> -               /* Child process */
>> -               worker_fn(NULL);
>> -       } else {
>> -               /* Parent process */
>> -               odph_linux_process_wait_n(proc, num_workers);
>> -
>> -               if (odp_term_global(instance)) {
>> -                       ODPH_ERR("Error: ODP global term failed.\n");
>> -                       exit(EXIT_FAILURE);
>> -               }
>> -       }
>> -
>> -       return 0;
>> -}
>> diff --git a/helper/test/linux-generic/thread.c 
>> b/helper/test/linux-generic/thread.c
>> deleted file mode 100644
>> index 919f00e..0000000
>> --- a/helper/test/linux-generic/thread.c
>> +++ /dev/null
>> @@ -1,87 +0,0 @@
>> -/* Copyright (c) 2015, Linaro Limited
>> - * All rights reserved.
>> - *
>> - * SPDX-License-Identifier:     BSD-3-Clause
>> - */
>> -
>> -#include <odph_debug.h>
>> -#include <odp_api.h>
>> -#include <odp/helper/platform/linux-generic/threads_extn.h>
>> -
>> -#define NUMBER_WORKERS 16
>> -static void *worker_fn(void *arg ODPH_UNUSED)
>> -{
>> -       /* depend on the odp helper to call odp_init_local */
>> -
>> -       printf("Worker thread on CPU %d\n", odp_cpu_id());
>> -
>> -       /* depend on the odp helper to call odp_term_local */
>> -
>> -       return NULL;
>> -}
>> -
>> -/* Create additional dataplane threads */
>> -int main(int argc ODPH_UNUSED, char *argv[] ODPH_UNUSED)
>> -{
>> -       odph_linux_pthread_t thread_tbl[NUMBER_WORKERS];
>> -       odp_cpumask_t cpu_mask;
>> -       int num_workers;
>> -       int cpu;
>> -       char cpumaskstr[ODP_CPUMASK_STR_SIZE];
>> -       odp_instance_t instance;
>> -       odph_linux_thr_params_t thr_params;
>> -
>> -       if (odp_init_global(&instance, NULL, NULL)) {
>> -               ODPH_ERR("Error: ODP global init failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
>> -               ODPH_ERR("Error: ODP local init failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       /* discover how many threads this system can support */
>> -       num_workers = odp_cpumask_default_worker(&cpu_mask, NUMBER_WORKERS);
>> -       if (num_workers < NUMBER_WORKERS) {
>> -               printf("System can only support %d threads and not the %d 
>> requested\n",
>> -                      num_workers, NUMBER_WORKERS);
>> -       }
>> -
>> -       /* generate a summary for the user */
>> -       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> -       printf("default cpu mask:           %s\n", cpumaskstr);
>> -       printf("default num worker threads: %i\n", num_workers);
>> -
>> -       cpu = odp_cpumask_first(&cpu_mask);
>> -       printf("the first CPU:              %i\n", cpu);
>> -
>> -       /* reserve cpu 0 for the control plane so remove it from
>> -        * the default mask */
>> -       odp_cpumask_clr(&cpu_mask, 0);
>> -       num_workers = odp_cpumask_count(&cpu_mask);
>> -       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> -       printf("new cpu mask:               %s\n", cpumaskstr);
>> -       printf("new num worker threads:     %i\n\n", num_workers);
>> -
>> -       memset(&thr_params, 0, sizeof(thr_params));
>> -       thr_params.start    = worker_fn;
>> -       thr_params.arg      = NULL;
>> -       thr_params.thr_type = ODP_THREAD_WORKER;
>> -       thr_params.instance = instance;
>> -
>> -       odph_linux_pthread_create(&thread_tbl[0], &cpu_mask, &thr_params);
>> -       odph_linux_pthread_join(thread_tbl, num_workers);
>> -
>> -       if (odp_term_local()) {
>> -               ODPH_ERR("Error: ODP local term failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       if (odp_term_global(instance)) {
>> -               ODPH_ERR("Error: ODP global term failed.\n");
>> -               exit(EXIT_FAILURE);
>> -       }
>> -
>> -       return 0;
>> -}
>> diff --git a/helper/test/linux/Makefile.am b/helper/test/linux/Makefile.am
>> new file mode 100644
>> index 0000000..f95e04d
>> --- /dev/null
>> +++ b/helper/test/linux/Makefile.am
>> @@ -0,0 +1,5 @@
>> +
>> +thread_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>> +dist_thread_SOURCES = pthread.c
>> +dist_process_SOURCES = process.c
>> +process_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>> diff --git a/helper/test/linux/process.c b/helper/test/linux/process.c
>> new file mode 100644
>> index 0000000..e08ef86
>> --- /dev/null
>> +++ b/helper/test/linux/process.c
>> @@ -0,0 +1,93 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:     BSD-3-Clause
>> + */
>> +
>> +#include <odph_debug.h>
>> +#include <odp_api.h>
>> +#include <odp/helper/linux/pthread.h>
>> +#include <odp/helper/linux/process.h>
>> +
>> +#define NUMBER_WORKERS 16 /* 0 = max */
>> +
>> +static void *worker_fn(void *arg ODPH_UNUSED)
>> +{
>> +       /* depend on the odp helper to call odp_init_local */
>> +       printf("Worker thread on CPU %d\n", odp_cpu_id());
>> +
>> +       return 0;
>> +}
>> +
>> +/* Create additional dataplane processes */
>> +int main(int argc ODPH_UNUSED, char *argv[] ODPH_UNUSED)
>> +{
>> +       odp_cpumask_t cpu_mask;
>> +       int num_workers;
>> +       int cpu;
>> +       char cpumaskstr[ODP_CPUMASK_STR_SIZE];
>> +       int ret;
>> +       odph_linux_process_t proc[NUMBER_WORKERS];
>> +       odp_instance_t instance;
>> +       odph_linux_thr_params_t thr_params;
>> +
>> +       if (odp_init_global(&instance, NULL, NULL)) {
>> +               ODPH_ERR("Error: ODP global init failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
>> +               ODPH_ERR("Error: ODP local init failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       /* discover how many processes this system can support */
>> +       num_workers = odp_cpumask_default_worker(&cpu_mask, NUMBER_WORKERS);
>> +       if (num_workers < NUMBER_WORKERS) {
>> +               printf("System can only support %d processes and not the %d 
>> requested\n",
>> +                      num_workers, NUMBER_WORKERS);
>> +       }
>> +
>> +       /* generate a summary for the user */
>> +       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> +       printf("default cpu mask:           %s\n", cpumaskstr);
>> +       printf("default num worker processes: %i\n", num_workers);
>> +
>> +       cpu = odp_cpumask_first(&cpu_mask);
>> +       printf("the first CPU:              %i\n", cpu);
>> +
>> +       /* reserve cpu 0 for the control plane so remove it from
>> +        * the default mask */
>> +       odp_cpumask_clr(&cpu_mask, 0);
>> +       num_workers = odp_cpumask_count(&cpu_mask);
>> +       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> +       printf("new cpu mask:               %s\n", cpumaskstr);
>> +       printf("new num worker processes:     %i\n\n", num_workers);
>> +
>> +       memset(&thr_params, 0, sizeof(thr_params));
>> +       thr_params.thr_type = ODP_THREAD_WORKER;
>> +       thr_params.instance = instance;
>> +
>> +       /* Fork worker processes */
>> +       ret = odph_linux_process_fork_n(proc, &cpu_mask, &thr_params);
>> +
>> +       if (ret < 0) {
>> +               ODPH_ERR("Fork workers failed %i\n", ret);
>> +               return -1;
>> +       }
>> +
>> +       if (ret == 0) {
>> +               /* Child process */
>> +               worker_fn(NULL);
>> +       } else {
>> +               /* Parent process */
>> +               odph_linux_process_wait_n(proc, num_workers);
>> +
>> +               if (odp_term_global(instance)) {
>> +                       ODPH_ERR("Error: ODP global term failed.\n");
>> +                       exit(EXIT_FAILURE);
>> +               }
>> +       }
>> +
>> +       return 0;
>> +}
>> diff --git a/helper/test/linux/pthread.c b/helper/test/linux/pthread.c
>> new file mode 100644
>> index 0000000..2bec0d1
>> --- /dev/null
>> +++ b/helper/test/linux/pthread.c
>> @@ -0,0 +1,87 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:     BSD-3-Clause
>> + */
>> +
>> +#include <odph_debug.h>
>> +#include <odp_api.h>
>> +#include <odp/helper/linux/pthread.h>
>> +
>> +#define NUMBER_WORKERS 16
>> +static void *worker_fn(void *arg ODPH_UNUSED)
>> +{
>> +       /* depend on the odp helper to call odp_init_local */
>> +
>> +       printf("Worker thread on CPU %d\n", odp_cpu_id());
>> +
>> +       /* depend on the odp helper to call odp_term_local */
>> +
>> +       return NULL;
>> +}
>> +
>> +/* Create additional dataplane threads */
>> +int main(int argc ODPH_UNUSED, char *argv[] ODPH_UNUSED)
>> +{
>> +       odph_linux_pthread_t thread_tbl[NUMBER_WORKERS];
>> +       odp_cpumask_t cpu_mask;
>> +       int num_workers;
>> +       int cpu;
>> +       char cpumaskstr[ODP_CPUMASK_STR_SIZE];
>> +       odp_instance_t instance;
>> +       odph_linux_thr_params_t thr_params;
>> +
>> +       if (odp_init_global(&instance, NULL, NULL)) {
>> +               ODPH_ERR("Error: ODP global init failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
>> +               ODPH_ERR("Error: ODP local init failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       /* discover how many threads this system can support */
>> +       num_workers = odp_cpumask_default_worker(&cpu_mask, NUMBER_WORKERS);
>> +       if (num_workers < NUMBER_WORKERS) {
>> +               printf("System can only support %d threads and not the %d 
>> requested\n",
>> +                      num_workers, NUMBER_WORKERS);
>> +       }
>> +
>> +       /* generate a summary for the user */
>> +       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> +       printf("default cpu mask:           %s\n", cpumaskstr);
>> +       printf("default num worker threads: %i\n", num_workers);
>> +
>> +       cpu = odp_cpumask_first(&cpu_mask);
>> +       printf("the first CPU:              %i\n", cpu);
>> +
>> +       /* reserve cpu 0 for the control plane so remove it from
>> +        * the default mask */
>> +       odp_cpumask_clr(&cpu_mask, 0);
>> +       num_workers = odp_cpumask_count(&cpu_mask);
>> +       (void)odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));
>> +       printf("new cpu mask:               %s\n", cpumaskstr);
>> +       printf("new num worker threads:     %i\n\n", num_workers);
>> +
>> +       memset(&thr_params, 0, sizeof(thr_params));
>> +       thr_params.start    = worker_fn;
>> +       thr_params.arg      = NULL;
>> +       thr_params.thr_type = ODP_THREAD_WORKER;
>> +       thr_params.instance = instance;
>> +
>> +       odph_linux_pthread_create(&thread_tbl[0], &cpu_mask, &thr_params);
>> +       odph_linux_pthread_join(thread_tbl, num_workers);
>> +
>> +       if (odp_term_local()) {
>> +               ODPH_ERR("Error: ODP local term failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       if (odp_term_global(instance)) {
>> +               ODPH_ERR("Error: ODP global term failed.\n");
>> +               exit(EXIT_FAILURE);
>> +       }
>> +
>> +       return 0;
>> +}
>> diff --git a/test/Makefile.inc b/test/Makefile.inc
>> index 243a616..1ad5d3a 100644
>> --- a/test/Makefile.inc
>> +++ b/test/Makefile.inc
>> @@ -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-@with_helper_platform@.la 
>> $(LIB)/libodp-linux.la
>> +LDADD = $(PRE_LDADD) $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>>
>>  INCFLAGS = \
>>         -I$(top_builddir)/platform/@with_platform@/include \
>> diff --git a/test/common_plat/validation/api/Makefile.inc 
>> b/test/common_plat/validation/api/Makefile.inc
>> index a0afd26..dda18ad 100644
>> --- a/test/common_plat/validation/api/Makefile.inc
>> +++ b/test/common_plat/validation/api/Makefile.inc
>> @@ -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-@with_helper_platform@.la 
>> $(LIB)/libodp-linux.la
>> +LIBODP = $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>> diff --git a/test/linux-generic/Makefile.inc 
>> b/test/linux-generic/Makefile.inc
>> index 2a49076..4b88b43 100644
>> --- a/test/linux-generic/Makefile.inc
>> +++ b/test/linux-generic/Makefile.inc
>> @@ -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-@with_helper_platform@.la 
>> $(LIB)/libodp-linux.la
>> +LIBODP = $(LIB)/libodphelper.la $(LIB)/libodp-linux.la
>>
>>  INCCUNIT_COMMON = -I$(top_srcdir)/test/common_plat/common
>>  INCODP =  \
>> --
>> 2.8.1
>>



-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org │ Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"

Reply via email to