diff mbox series

[1/2] helper: linux: renamed threads_extn to linux helpers

Message ID 1486121040-12393-1-git-send-email-petri.savolainen@linaro.org
State New
Headers show
Series [1/2] helper: linux: renamed threads_extn to linux helpers | expand

Commit Message

Petri Savolainen Feb. 3, 2017, 11:23 a.m. UTC
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.

Use --enable-helper-linux configuration option to enable
support for Linux helpers.

Signed-off-by: Petri Savolainen <petri.savolainen@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

-- 
2.8.1

Comments

Christophe Milard Feb. 3, 2017, 12:28 p.m. UTC | #1
On 3 February 2017 at 12:23, Petri Savolainen
<petri.savolainen@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".
:-)

Christophe

>

> Use --enable-helper-linux configuration option to enable

> support for Linux helpers.

>

> Signed-off-by: Petri Savolainen <petri.savolainen@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 Feb. 3, 2017, 12:41 p.m. UTC | #2
On 3 February 2017 at 07:28, Christophe Milard
<christophe.milard@linaro.org> wrote:
> On 3 February 2017 at 12:23, Petri Savolainen

> <petri.savolainen@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.savolainen@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"
Sorin Vultureanu Feb. 3, 2017, 12:59 p.m. UTC | #3
Hi Mike,

My understanding is that you want to remove helper lib, so I have some points why that would be a bad idea:

1. We use these helpers as abstraction layer. The fact that you remove them will add load to change things in OFP. Probably, we will be forced to reuse your deleted code as it provides some abstractization ! That code is still required to run on a platform. We use that abstractization that is right for us and we will be forced to invent other abstractization if you remove yours (if not reuse your code).

2. I strongly believe ODP should provide this process/thread abstractization as the ODP application should be portable! (be it in main ODP lib, or as is now in helper lib)

3. Backward compatibility of code and design (at major or concept level). This means that you can't really remove things and expect ODP developers to be happy with your design changes or the lack of commitment to maintain backward compatibility of any API.

So in conclusion, my point of view is that you need to make or keep some concept of process/thread that are generic and still have multiple implementations.

I have added Janne and Jere that might have a different point of view, from OFP perspective.

BR,
Sorin Vultureanu
Software Engineer
Linux R&D
Email  Sorin.Vultureanu@enea.com
Phone  +40 723.651.943

www.enea.com



This message, including attachments, is CONFIDENTIAL. It may also be privileged or otherwise protected by law. If you received this email by mistake please let us know by reply and then delete it from your system; you should not copy it or disclose its contents to anyone. All messages sent to and from Enea may be monitored to ensure compliance with internal policies and to protect our business. Emails are not secure and cannot be guaranteed to be error free as they can be intercepted, a mended, lost or destroyed, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of email transmission. Anyone who communicates with us by email accepts these risks.


> -----Original Message-----

> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> Sent: Friday, February 03, 2017 2:41 PM

> To: Christophe Milard <christophe.milard@linaro.org>

> Cc: Petri Savolainen <petri.savolainen@linaro.org>; LNG ODP Mailman List

> <lng-odp@lists.linaro.org>; Sorin Vultureanu <Sorin.Vultureanu@enea.com>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> On 3 February 2017 at 07:28, Christophe Milard

> <christophe.milard@linaro.org> wrote:

> > On 3 February 2017 at 12:23, Petri Savolainen

> > <petri.savolainen@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.savolainen@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"
Mike Holmes Feb. 3, 2017, 1:03 p.m. UTC | #4
On 3 February 2017 at 07:59, Sorin Vultureanu <Sorin.Vultureanu@enea.com> wrote:
> Hi Mike,

>

> My understanding is that you want to remove helper lib, so I have some points why that would be a bad idea:


Not remove helpers, just remove the unused linux spcific API, the
abstract one will remain.

>

> 1. We use these helpers as abstraction layer. The fact that you remove them will add load to change things in OFP. Probably, we will be forced to reuse your deleted code as it provides some abstractization ! That code is still required to run on a platform. We use that abstractization that is right for us and we will be forced to invent other abstractization if you remove yours (if not reuse your code).


But you are not useing the abstraction, you are using the original
linux only API I think.

>

> 2. I strongly believe ODP should provide this process/thread abstractization as the ODP application should be portable! (be it in main ODP lib, or as is now in helper lib)


It does, but you are not calling the abstract API I think

>

> 3. Backward compatibility of code and design (at major or concept level). This means that you can't really remove things and expect ODP developers to be happy with your design changes or the lack of commitment to maintain backward compatibility of any API.


Indeed, and at the same time we have to evolve and move towards a more
cloud friendly configuration, thus the old API was made a compile
option, I am thinking now that a lib to support th old api can remian,
but I dont think it has a place in the general
test/example/perfromance metrics applications, they all use the
abstract helper api.

>

> So in conclusion, my point of view is that you need to make or keep some concept of process/thread that are generic and still have multiple implementations.

>

> I have added Janne and Jere that might have a different point of view, from OFP perspective.

>

> BR,

> Sorin Vultureanu

> Software Engineer

> Linux R&D

> Email  Sorin.Vultureanu@enea.com

> Phone  +40 723.651.943

>

> www.enea.com

>

>

>

> This message, including attachments, is CONFIDENTIAL. It may also be privileged or otherwise protected by law. If you received this email by mistake please let us know by reply and then delete it from your system; you should not copy it or disclose its contents to anyone. All messages sent to and from Enea may be monitored to ensure compliance with internal policies and to protect our business. Emails are not secure and cannot be guaranteed to be error free as they can be intercepted, a mended, lost or destroyed, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of email transmission. Anyone who communicates with us by email accepts these risks.

>

>

>> -----Original Message-----

>> From: Mike Holmes [mailto:mike.holmes@linaro.org]

>> Sent: Friday, February 03, 2017 2:41 PM

>> To: Christophe Milard <christophe.milard@linaro.org>

>> Cc: Petri Savolainen <petri.savolainen@linaro.org>; LNG ODP Mailman List

>> <lng-odp@lists.linaro.org>; Sorin Vultureanu <Sorin.Vultureanu@enea.com>

>> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>> On 3 February 2017 at 07:28, Christophe Milard

>> <christophe.milard@linaro.org> wrote:

>> > On 3 February 2017 at 12:23, Petri Savolainen

>> > <petri.savolainen@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.savolainen@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"




-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org │ Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Savolainen, Petri (Nokia - FI/Espoo) Feb. 3, 2017, 1:11 p.m. UTC | #5
> -----Original Message-----

> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> Sent: Friday, February 03, 2017 2:29 PM

> To: Petri Savolainen <petri.savolainen@linaro.org>

> Cc: LNG ODP Mailman List <lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> On 3 February 2017 at 12:23, Petri Savolainen

> <petri.savolainen@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".

> :-)

> 

> Christophe


This is needed by OFP, for example.

The current ODP master (after v1.13) moved things backwards as linux helper (which create e.g. pthreads and call odp_local_init / _term() for those) was renamed as "linux-generic helper". That would need OFP to expose "helper/linux-generic/..." in its Makefiles, which is both ugly and wrong (in the sense that helper code is part application code, not implementation code).

-Petri
Christophe Milard Feb. 3, 2017, 1:36 p.m. UTC | #6
On 3 February 2017 at 14:11, Savolainen, Petri (Nokia - FI/Espoo)
<petri.savolainen@nokia-bell-labs.com> wrote:
>

>

>> -----Original Message-----

>> From: Christophe Milard [mailto:christophe.milard@linaro.org]

>> Sent: Friday, February 03, 2017 2:29 PM

>> To: Petri Savolainen <petri.savolainen@linaro.org>

>> Cc: LNG ODP Mailman List <lng-odp@lists.linaro.org>

>> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>> On 3 February 2017 at 12:23, Petri Savolainen

>> <petri.savolainen@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".

>> :-)

>>

>> Christophe

>

> This is needed by OFP, for example.

>

> The current ODP master (after v1.13) moved things backwards as linux helper (which create e.g. pthreads and call odp_local_init / _term() for those) was renamed as "linux-generic helper". That would need OFP to expose "helper/linux-generic/..." in its Makefiles, which is both ugly and wrong (in the sense that helper code is part application code, not implementation code).


I am really getting confused here...
There are two sorts of things today in the helper (regarding ODPthread
creation):
1)odph_odpthreads_create() familly of functions abstracts the ODP
thread creation, i.e. will create OPD threads. Whether that is a
pthread or linux process or anything else under the hood is hidden: It
just creates a set of ODPthreads. (for those implementation which
(should) supports different implemenation, a helper flag can be used
to select what should be done)

2)linux specific functions creating pthreads or processes. If the
application uses those, the application is definitively binding itself
to linux and is then using these functions instead of calling
pthread_create() or fork() directely.

From Mikes comment, I understand that OFP is using functions from the
second set. Do they have any reason for doing that? Possibly, if they
share data allocated after the thread creatiion, not using
odp_shm_reserve().
If an application really binds itseft to linux, I don't see anything
wrong if it is reflected in its Makefile ("helper/linux-generic/...").
If OFP does not require any specific type of ODP thread (they just
want concurrency but don't care how this is achieved) , then they
should be using function from the first set.

The Second set of function is not of much value in my eyes: They do
not provide any kind of abstraction, but just some kind of shortcut
avoiding a few things round fork() or pthread_create().
When I see the confusion that they generate, compared to the little
gain they provide (avoiding to write about 100lines of code), I still
feel those function should be part of the application. Most programmer
knows much more about pthread_create() and fork(), and the price
rewritting the little piece of code will probably been seen as lower
than learning the helper API.

The role of the helpers becomes then clearer: Abstracting thing that
can be done differentely on different platform.

Christophe

>

> -Petri

>

>

>

>

>
Savolainen, Petri (Nokia - FI/Espoo) Feb. 3, 2017, 1:53 p.m. UTC | #7
> -----Original Message-----

> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> Sent: Friday, February 03, 2017 3:37 PM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> labs.com>

> Cc: LNG ODP Mailman List <lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> On 3 February 2017 at 14:11, Savolainen, Petri (Nokia - FI/Espoo)

> <petri.savolainen@nokia-bell-labs.com> wrote:

> >

> >

> >> -----Original Message-----

> >> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> >> Sent: Friday, February 03, 2017 2:29 PM

> >> To: Petri Savolainen <petri.savolainen@linaro.org>

> >> Cc: LNG ODP Mailman List <lng-odp@lists.linaro.org>

> >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to

> >> linux helpers

> >>

> >> On 3 February 2017 at 12:23, Petri Savolainen

> >> <petri.savolainen@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".

> >> :-)

> >>

> >> Christophe

> >

> > This is needed by OFP, for example.

> >

> > The current ODP master (after v1.13) moved things backwards as linux

> helper (which create e.g. pthreads and call odp_local_init / _term() for

> those) was renamed as "linux-generic helper". That would need OFP to

> expose "helper/linux-generic/..." in its Makefiles, which is both ugly and

> wrong (in the sense that helper code is part application code, not

> implementation code).

> 

> I am really getting confused here...

> There are two sorts of things today in the helper (regarding ODPthread

> creation):

> 1)odph_odpthreads_create() familly of functions abstracts the ODP

> thread creation, i.e. will create OPD threads. Whether that is a

> pthread or linux process or anything else under the hood is hidden: It

> just creates a set of ODPthreads. (for those implementation which

> (should) supports different implemenation, a helper flag can be used

> to select what should be done)


Needed by (synthetic) validation test application that need to run on any environment to offer API verification.

> 

> 2)linux specific functions creating pthreads or processes. If the

> application uses those, the application is definitively binding itself

> to linux and is then using these functions instead of calling

> pthread_create() or fork() directely.


Most real world applications choose first an operating system and then the thread model within that OS. Linux is the largest data plane OS (ecosystem), so it's natural for ODP to offer helpers for that. Most real/production grade applications would not need OS abstraction layer (option 1) above) from ODP.


> 

> From Mikes comment, I understand that OFP is using functions from the

> second set. Do they have any reason for doing that? Possibly, if they

> share data allocated after the thread creatiion, not using

> odp_shm_reserve().

> If an application really binds itseft to linux, I don't see anything

> wrong if it is reflected in its Makefile ("helper/linux-generic/...").


... and
helper/odp-dpdk/
helper/odp-thunderx
helper/nxp
...

... gets ugly. A Linux application using ODP depends only on Linux and ODP APIs, not the ODP platform under ODP API.



> If OFP does not require any specific type of ODP thread (they just

> want concurrency but don't care how this is achieved) , then they

> should be using function from the first set.


OFP slow path is Linux, not "abstract OS" (as of today at least).

> 

> The Second set of function is not of much value in my eyes: They do

> not provide any kind of abstraction, but just some kind of shortcut

> avoiding a few things round fork() or pthread_create().


May be other common Linux data plane application patters will follow. Linux is not there only for threads. Debugging, file IO, logging, ...


> When I see the confusion that they generate, compared to the little

> gain they provide (avoiding to write about 100lines of code), I still

> feel those function should be part of the application. Most programmer

> knows much more about pthread_create() and fork(), and the price

> rewritting the little piece of code will probably been seen as lower

> than learning the helper API.

> 

> The role of the helpers becomes then clearer: Abstracting thing that

> can be done differentely on different platform.


Any helper code is optional. Application can copy the same lines into inside it's code base anytime, without breaking portability. Abstract threads help our example to run on Linux pthreads and processes without code change. Any helpers are not rewritten between ODP implementations (platforms). ODP API is for that.

-Petri
Mike Holmes Feb. 10, 2017, 3:02 p.m. UTC | #8
On 3 February 2017 at 06:23, Petri Savolainen <petri.savolainen@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.

>

> Use --enable-helper-linux configuration option to enable

> support for Linux helpers.

>

> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>

>


Reviewed-by: Mike Holmes <mike.holmes@linaro.org>


required 3 way apply


> ---

>  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 <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Savolainen, Petri (Nokia - FI/Espoo) Feb. 13, 2017, 2:41 p.m. UTC | #9
From: Mike Holmes [mailto:mike.holmes@linaro.org] 

Sent: Friday, February 10, 2017 5:02 PM
To: Petri Savolainen <petri.savolainen@linaro.org>
Cc: lng-odp <lng-odp@lists.linaro.org>
Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to linux helpers



On 3 February 2017 at 06:23, Petri Savolainen <mailto:petri.savolainen@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.

Use --enable-helper-linux configuration option to enable
support for Linux helpers.

Signed-off-by: Petri Savolainen <mailto:petri.savolainen@linaro.org>


Reviewed-by: Mike Holmes <mailto:mike.holmes@linaro.org>


required 3 way apply



This should be merged. It moves linux dependent helper code under linux folder. If there would be helper code dependent on some other OS, that would go to their own helper/OS_foo/ folder. All Linux based ODP implementations can run this helper code - there is no need to have N different linux helpers for N different Linux based implementations.


Also, the build is currently broken in master for --enable-helper-extn. E.g. OFP cannot be built against it.

platform/linux-generic/thread.c:282:12: error: \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-function]
 static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,



-Petri
Mike Holmes Feb. 13, 2017, 3:02 p.m. UTC | #10
On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo) <
petri.savolainen@nokia-bell-labs.com> wrote:

>

>

> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> Sent: Friday, February 10, 2017 5:02 PM

> To: Petri Savolainen <petri.savolainen@linaro.org>

> Cc: lng-odp <lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

>

>

>

> On 3 February 2017 at 06:23, Petri Savolainen <mailto:petri.savolainen@

> 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.

>

> Use --enable-helper-linux configuration option to enable

> support for Linux helpers.

>

> Signed-off-by: Petri Savolainen <mailto:petri.savolainen@linaro.org>

>

> Reviewed-by: Mike Holmes <mailto:mike.holmes@linaro.org>

>

> required 3 way apply

>

>

>

> This should be merged. It moves linux dependent helper code under linux

> folder. If there would be helper code dependent on some other OS, that

> would go to their own helper/OS_foo/ folder. All Linux based ODP

> implementations can run this helper code - there is no need to have N

> different linux helpers for N different Linux based implementations.

>

>

> Also, the build is currently broken in master for --enable-helper-extn.

> E.g. OFP cannot be built against it.

>


This is not broken IMHO, it is by design, OFP depends on the helpers, we
need helpers to either be support for apps that we maintain and don't use
(current case) or we enforce  OFP and others to use the abstract API that
all our own executable use. Maintaining code we don't use is dangerous, you
should have to choose to do it, but I like the rename, that is fine and is
progress, hence the review.

I think splitting out all of all the executables  will make this much
cleaner.
All ODP upstream executables will use the abstract API and be portable to
any platform and OS. Meanwhile the odp-Linux repo can have a Linux specific
apis such as the legacy one OFP is using and that is just that
implementations choice, as we have said there is no requirement to use
helpers, or linux, and OFP might want to attach itself to that,  but the
tests and examples must remain agnostic until we state we are dropping that
goal.


>

> platform/linux-generic/thread.c:282:12: error: \u2018odph_linux_thread_create\u2019

> defined but not used [-Werror=unused-function]

>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

>

>

>

> -Petri

>

>

>

>



-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Savolainen, Petri (Nokia - FI/Espoo) Feb. 13, 2017, 3:09 p.m. UTC | #11
From: Mike Holmes [mailto:mike.holmes@linaro.org] 

Sent: Monday, February 13, 2017 5:02 PM
To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-labs.com>
Cc: lng-odp <lng-odp@lists.linaro.org>
Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to linux helpers



On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo) <mailto:petri.savolainen@nokia-bell-labs.com> wrote:


From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

Sent: Friday, February 10, 2017 5:02 PM
To: Petri Savolainen <mailto:petri.savolainen@linaro.org>
Cc: lng-odp <mailto:lng-odp@lists.linaro.org>
Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to linux helpers



On 3 February 2017 at 06:23, Petri Savolainen <mailto:mailto:petri.savolainen@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.

Use --enable-helper-linux configuration option to enable
support for Linux helpers.

Signed-off-by: Petri Savolainen <mailto:mailto:petri.savolainen@linaro.org>


Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>


required 3 way apply



This should be merged. It moves linux dependent helper code under linux folder. If there would be helper code dependent on some other OS, that would go to their own helper/OS_foo/ folder. All Linux based ODP implementations can run this helper code - there is no need to have N different linux helpers for N different Linux based implementations.


Also, the build is currently broken in master for --enable-helper-extn. E.g. OFP cannot be built against it.

This is not broken IMHO, it is by design, OFP depends on the helpers, we need helpers to either be support for apps that we maintain and don't use (current case) or we enforce  OFP and others to use the abstract API that all our own executable use. Maintaining code we don't use is dangerous, you should have to choose to do it, but I like the rename, that is fine and is progress, hence the review.

I think splitting out all of all the executables  will make this much cleaner. 
All ODP upstream executables will use the abstract API and be portable to any platform and OS. Meanwhile the odp-Linux repo can have a Linux specific apis such as the legacy one OFP is using and that is just that implementations choice, as we have said there is no requirement to use helpers, or linux, and OFP might want to attach itself to that,  but the tests and examples must remain agnostic until we state we are dropping that goal.


Please try:
./configure --enable-helper-extn
make

It does not compile, due to:

platform/linux-generic/thread.c:282:12: error: \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-function]
 static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,


My patch fixes this also.


-Petri
Christophe Milard Feb. 13, 2017, 3:41 p.m. UTC | #12
This is getting very confusing now: why helper/<OS>?  do we have
odp/<OS>?: shouldn't  these be symetric?

My view is getting clearer and clearer:
On the test side, was have made tests for {OS, HW}= {linux/PC} and
given the possibility to diverge from these (for any  reason, e.g.
difference of HW or OS) with the use of "platform":
If a test defined on the common validation test is inappropriate for a
ODP developer (whatever the reason), that developer can overwrite this
test (or part of it, such as its setup) with an appropriate one on the
platform side.
Kallray, AFAIK, if using the platform trick for both OS and HW divergence.

Why not the same approach on the helper side? We give helpers for
{linux/PC} and provide a way to redefine these function for those who
need to,  on the platform side (e.g. using a weak symbol on the common
helpers and letting those who need define the same function as
"strong" on the helper platform side?... or any other better trick).

Then, any implementer knows where to place their hacks: on the
"platform side". Maybe not best, but at least consistent and clear.

That would just give helpers, with different platform (for any reason)
implementations.

The linux-specific helper would of course not fit on the common helper
part as they are linux specific and cannot be implementation on
different OS (platform). Once again, I don't understand why we needed
to do wrappers around well known Linux system calls: IMHO, helpers
should contains functions that we expect to be delivered on any
implementation (OS/HW) helpers, so these linux wrappers don't fit
there.
If we really want to keep that (I'd vote against), let's create
another directory name for what it is: "linux-wrappers"... and
separate them from function we'd expect to see everywhere (the rest of
the helpers, even if different platform dependent implementations for
those might exist)

Christophe

On 13 February 2017 at 16:09, Savolainen, Petri (Nokia - FI/Espoo)
<petri.savolainen@nokia-bell-labs.com> wrote:
>

>

> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> Sent: Monday, February 13, 2017 5:02 PM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-labs.com>

> Cc: lng-odp <lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to linux helpers

>

>

>

> On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo) <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

>

>

> From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> Sent: Friday, February 10, 2017 5:02 PM

> To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to linux helpers

>

>

>

> On 3 February 2017 at 06:23, Petri Savolainen <mailto:mailto:petri.savolainen@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.

>

> Use --enable-helper-linux configuration option to enable

> support for Linux helpers.

>

> Signed-off-by: Petri Savolainen <mailto:mailto:petri.savolainen@linaro.org>

>

> Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

>

> required 3 way apply

>

>

>

> This should be merged. It moves linux dependent helper code under linux folder. If there would be helper code dependent on some other OS, that would go to their own helper/OS_foo/ folder. All Linux based ODP implementations can run this helper code - there is no need to have N different linux helpers for N different Linux based implementations.

>

>

> Also, the build is currently broken in master for --enable-helper-extn. E.g. OFP cannot be built against it.

>

> This is not broken IMHO, it is by design, OFP depends on the helpers, we need helpers to either be support for apps that we maintain and don't use (current case) or we enforce  OFP and others to use the abstract API that all our own executable use. Maintaining code we don't use is dangerous, you should have to choose to do it, but I like the rename, that is fine and is progress, hence the review.

>

> I think splitting out all of all the executables  will make this much cleaner.

> All ODP upstream executables will use the abstract API and be portable to any platform and OS. Meanwhile the odp-Linux repo can have a Linux specific apis such as the legacy one OFP is using and that is just that implementations choice, as we have said there is no requirement to use helpers, or linux, and OFP might want to attach itself to that,  but the tests and examples must remain agnostic until we state we are dropping that goal.

>

>

> Please try:

> ./configure --enable-helper-extn

> make

>

> It does not compile, due to:

>

> platform/linux-generic/thread.c:282:12: error: \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-function]

>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

>

>

> My patch fixes this also.

>

>

> -Petri

>

>
Savolainen, Petri (Nokia - FI/Espoo) Feb. 15, 2017, 8:34 a.m. UTC | #13
> -----Original Message-----

> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> Sent: Monday, February 13, 2017 5:41 PM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> labs.com>

> Cc: Mike Holmes <mike.holmes@linaro.org>; lng-odp <lng-

> odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> This is getting very confusing now: why helper/<OS>?  do we have

> odp/<OS>?: shouldn't  these be symetric?



Application (like OFP today) which wants to use e.g. Linux pthread helpers include:

#include <odp_api.h>
#include <odp/helper/linux/pthread.h>

odph_linux_pthread_create()
...
odph_linux_pthread_join()


It explicitly uses Linux pthreads through a helper function. There's no need to provide these helpers and functions on a non-Linux implementation (because there is no Linux).

Linux helpers are totally different thing than ODP implementation internal directory structure.


> 

> My view is getting clearer and clearer:

> On the test side, was have made tests for {OS, HW}= {linux/PC} and

> given the possibility to diverge from these (for any  reason, e.g.

> difference of HW or OS) with the use of "platform":

> If a test defined on the common validation test is inappropriate for a

> ODP developer (whatever the reason), that developer can overwrite this

> test (or part of it, such as its setup) with an appropriate one on the

> platform side.

> Kallray, AFAIK, if using the platform trick for both OS and HW divergence.


If the system under test is not a Linux system. You cannot run linux helper code there and thus you just skip the linux helper tests.


> 

> Why not the same approach on the helper side? We give helpers for

> {linux/PC} and provide a way to redefine these function for those who

> need to,  on the platform side (e.g. using a weak symbol on the common

> helpers and letting those who need define the same function as

> "strong" on the helper platform side?... or any other better trick).


Why a vendor which do not support Linux would rewrite e.g. odph_linux_pthread_create() to emulate Linux pthreads? If the system is not Linux, there is no point to run Linux system calls there and application would not call odph_linux_pthread_create() there.

Remember, helper code is application code. Application would not call Linux system calls in an non-Linux system. So, no need for a non-Linux based ODP implementation to emulate any Linux system calls.


> 

> Then, any implementer knows where to place their hacks: on the

> "platform side". Maybe not best, but at least consistent and clear.

> 

> That would just give helpers, with different platform (for any reason)

> implementations.

> 

> The linux-specific helper would of course not fit on the common helper

> part as they are linux specific and cannot be implementation on

> different OS (platform). Once again, I don't understand why we needed

> to do wrappers around well known Linux system calls: IMHO, helpers

> should contains functions that we expect to be delivered on any

> implementation (OS/HW) helpers, so these linux wrappers don't fit

> there.


Linux helpers can be used in Linux based systems - may be 90 - 95% of all data plane systems today support or can support Linux.

Non-Linux systems do not need to run Linux applications (helpers).


> If we really want to keep that (I'd vote against), let's create

> another directory name for what it is: "linux-wrappers"... and

> separate them from function we'd expect to see everywhere (the rest of

> the helpers, even if different platform dependent implementations for

> those might exist)


This patch uses odp/helper/linux/xx.h which is pretty explicit about the dependency to Linux. Anything under odp/helper/linux is Linux dependent and would not build/run on non-Linux systems. Clear?


-Petri





> 

> Christophe

> 

> On 13 February 2017 at 16:09, Savolainen, Petri (Nokia - FI/Espoo)

> <petri.savolainen@nokia-bell-labs.com> wrote:

> >

> >

> > From: Mike Holmes [mailto:mike.holmes@linaro.org]

> > Sent: Monday, February 13, 2017 5:02 PM

> > To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> labs.com>

> > Cc: lng-odp <lng-odp@lists.linaro.org>

> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to linux helpers

> >

> >

> >

> > On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

> >

> >

> > From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> > Sent: Friday, February 10, 2017 5:02 PM

> > To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> > Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to linux helpers

> >

> >

> >

> > On 3 February 2017 at 06:23, Petri Savolainen

> <mailto:mailto:petri.savolainen@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.

> >

> > Use --enable-helper-linux configuration option to enable

> > support for Linux helpers.

> >

> > Signed-off-by: Petri Savolainen

> <mailto:mailto:petri.savolainen@linaro.org>

> >

> > Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

> >

> > required 3 way apply

> >

> >

> >

> > This should be merged. It moves linux dependent helper code under linux

> folder. If there would be helper code dependent on some other OS, that

> would go to their own helper/OS_foo/ folder. All Linux based ODP

> implementations can run this helper code - there is no need to have N

> different linux helpers for N different Linux based implementations.

> >

> >

> > Also, the build is currently broken in master for --enable-helper-extn.

> E.g. OFP cannot be built against it.

> >

> > This is not broken IMHO, it is by design, OFP depends on the helpers, we

> need helpers to either be support for apps that we maintain and don't use

> (current case) or we enforce  OFP and others to use the abstract API that

> all our own executable use. Maintaining code we don't use is dangerous,

> you should have to choose to do it, but I like the rename, that is fine

> and is progress, hence the review.

> >

> > I think splitting out all of all the executables  will make this much

> cleaner.

> > All ODP upstream executables will use the abstract API and be portable

> to any platform and OS. Meanwhile the odp-Linux repo can have a Linux

> specific apis such as the legacy one OFP is using and that is just that

> implementations choice, as we have said there is no requirement to use

> helpers, or linux, and OFP might want to attach itself to that,  but the

> tests and examples must remain agnostic until we state we are dropping

> that goal.

> >

> >

> > Please try:

> > ./configure --enable-helper-extn

> > make

> >

> > It does not compile, due to:

> >

> > platform/linux-generic/thread.c:282:12: error:

> \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-

> function]

> >  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

> >

> >

> > My patch fixes this also.

> >

> >

> > -Petri

> >

> >
Christophe Milard Feb. 15, 2017, 9:40 a.m. UTC | #14
On 15 February 2017 at 09:34, Savolainen, Petri (Nokia - FI/Espoo)
<petri.savolainen@nokia-bell-labs.com> wrote:
>

>

>> -----Original Message-----

>> From: Christophe Milard [mailto:christophe.milard@linaro.org]

>> Sent: Monday, February 13, 2017 5:41 PM

>> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

>> labs.com>

>> Cc: Mike Holmes <mike.holmes@linaro.org>; lng-odp <lng-

>> odp@lists.linaro.org>

>> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>> This is getting very confusing now: why helper/<OS>?  do we have

>> odp/<OS>?: shouldn't  these be symetric?

>

>

> Application (like OFP today) which wants to use e.g. Linux pthread helpers include:

>

> #include <odp_api.h>

> #include <odp/helper/linux/pthread.h>

>

> odph_linux_pthread_create()

> ...

> odph_linux_pthread_join()

>

>

> It explicitly uses Linux pthreads through a helper function. There's no need to provide these helpers and functions on a non-Linux implementation (because there is no Linux).

>

> Linux helpers are totally different thing than ODP implementation internal directory structure.


Different: Yes. But related:
We are back, sadly, to my first question: "what is a platform".
To that, you, Petri, answered: "platform == implementation". And I agree.

Now, can we agree that the above platform definition implies:
different OS => different platform? Or are you saying that a OSE ODP
and linux ODP are the same implementation???.

If we can agree that, for ODP implementation, different OSes means
different platforms, do you feel comfortable calling these variation
differently for the helpers?

What if some helper function requires to be different for a given OS?
Say for instance, some company wants to implement ODP threads using
libdill or libmill? (on linux). Or some helper function would depend
on memory available on a given HW?

Yes, ODP implementation and helpers are 2 differents things, but they
are facing the same issue: They try to implement a given interface
(the ODP API  for ODP and the helper API for the helpers) on different
HW, OS, ... I'd say on different platform. I cannot see why helpers
variants would only be limited to OSes.

If we can agree on the above, we should agree that a common solution
to tackle the same problem would be nice.
On the ODP implementation side, we agreed that a platform was just a
way to diverge for the main delivery.
I still think it makes sense to have the same approach for the helpers:
If we deliver ODP implementation "linux-gen" and "ODP-dpdk" we should
deliver 2 variant of helper for these as well (even if they happen to
be the same).

A constructor willing to have his own ODP (whatever the reason) would
have the framework to diverge: a divergence is a new platform. Both
for helpers and ODP
The interesting question is how do we write the code so that these
divergence would be easy to do and so that maximum code can be reuse.
That is where the next challenge is.  But first we need to agree on
what a platform is and how we handle helpers.

Christophe.

>

>

>>

>> My view is getting clearer and clearer:

>> On the test side, was have made tests for {OS, HW}= {linux/PC} and

>> given the possibility to diverge from these (for any  reason, e.g.

>> difference of HW or OS) with the use of "platform":

>> If a test defined on the common validation test is inappropriate for a

>> ODP developer (whatever the reason), that developer can overwrite this

>> test (or part of it, such as its setup) with an appropriate one on the

>> platform side.

>> Kallray, AFAIK, if using the platform trick for both OS and HW divergence.

>

> If the system under test is not a Linux system. You cannot run linux helper code there and thus you just skip the linux helper tests.

>

>

>>

>> Why not the same approach on the helper side? We give helpers for

>> {linux/PC} and provide a way to redefine these function for those who

>> need to,  on the platform side (e.g. using a weak symbol on the common

>> helpers and letting those who need define the same function as

>> "strong" on the helper platform side?... or any other better trick).

>

> Why a vendor which do not support Linux would rewrite e.g. odph_linux_pthread_create() to emulate Linux pthreads? If the system is not Linux, there is no point to run Linux system calls there and application would not call odph_linux_pthread_create() there.

>

> Remember, helper code is application code. Application would not call Linux system calls in an non-Linux system. So, no need for a non-Linux based ODP implementation to emulate any Linux system calls.

>

>

>>

>> Then, any implementer knows where to place their hacks: on the

>> "platform side". Maybe not best, but at least consistent and clear.

>>

>> That would just give helpers, with different platform (for any reason)

>> implementations.

>>

>> The linux-specific helper would of course not fit on the common helper

>> part as they are linux specific and cannot be implementation on

>> different OS (platform). Once again, I don't understand why we needed

>> to do wrappers around well known Linux system calls: IMHO, helpers

>> should contains functions that we expect to be delivered on any

>> implementation (OS/HW) helpers, so these linux wrappers don't fit

>> there.

>

> Linux helpers can be used in Linux based systems - may be 90 - 95% of all data plane systems today support or can support Linux.

>

> Non-Linux systems do not need to run Linux applications (helpers).

>

>

>> If we really want to keep that (I'd vote against), let's create

>> another directory name for what it is: "linux-wrappers"... and

>> separate them from function we'd expect to see everywhere (the rest of

>> the helpers, even if different platform dependent implementations for

>> those might exist)

>

> This patch uses odp/helper/linux/xx.h which is pretty explicit about the dependency to Linux. Anything under odp/helper/linux is Linux dependent and would not build/run on non-Linux systems. Clear?

>

>

> -Petri

>

>

>

>

>

>>

>> Christophe

>>

>> On 13 February 2017 at 16:09, Savolainen, Petri (Nokia - FI/Espoo)

>> <petri.savolainen@nokia-bell-labs.com> wrote:

>> >

>> >

>> > From: Mike Holmes [mailto:mike.holmes@linaro.org]

>> > Sent: Monday, February 13, 2017 5:02 PM

>> > To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

>> labs.com>

>> > Cc: lng-odp <lng-odp@lists.linaro.org>

>> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

>> to linux helpers

>> >

>> >

>> >

>> > On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

>> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

>> >

>> >

>> > From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

>> > Sent: Friday, February 10, 2017 5:02 PM

>> > To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

>> > Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

>> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

>> to linux helpers

>> >

>> >

>> >

>> > On 3 February 2017 at 06:23, Petri Savolainen

>> <mailto:mailto:petri.savolainen@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.

>> >

>> > Use --enable-helper-linux configuration option to enable

>> > support for Linux helpers.

>> >

>> > Signed-off-by: Petri Savolainen

>> <mailto:mailto:petri.savolainen@linaro.org>

>> >

>> > Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

>> >

>> > required 3 way apply

>> >

>> >

>> >

>> > This should be merged. It moves linux dependent helper code under linux

>> folder. If there would be helper code dependent on some other OS, that

>> would go to their own helper/OS_foo/ folder. All Linux based ODP

>> implementations can run this helper code - there is no need to have N

>> different linux helpers for N different Linux based implementations.

>> >

>> >

>> > Also, the build is currently broken in master for --enable-helper-extn.

>> E.g. OFP cannot be built against it.

>> >

>> > This is not broken IMHO, it is by design, OFP depends on the helpers, we

>> need helpers to either be support for apps that we maintain and don't use

>> (current case) or we enforce  OFP and others to use the abstract API that

>> all our own executable use. Maintaining code we don't use is dangerous,

>> you should have to choose to do it, but I like the rename, that is fine

>> and is progress, hence the review.

>> >

>> > I think splitting out all of all the executables  will make this much

>> cleaner.

>> > All ODP upstream executables will use the abstract API and be portable

>> to any platform and OS. Meanwhile the odp-Linux repo can have a Linux

>> specific apis such as the legacy one OFP is using and that is just that

>> implementations choice, as we have said there is no requirement to use

>> helpers, or linux, and OFP might want to attach itself to that,  but the

>> tests and examples must remain agnostic until we state we are dropping

>> that goal.

>> >

>> >

>> > Please try:

>> > ./configure --enable-helper-extn

>> > make

>> >

>> > It does not compile, due to:

>> >

>> > platform/linux-generic/thread.c:282:12: error:

>> \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-

>> function]

>> >  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

>> >

>> >

>> > My patch fixes this also.

>> >

>> >

>> > -Petri

>> >

>> >
Savolainen, Petri (Nokia - FI/Espoo) Feb. 15, 2017, 10:57 a.m. UTC | #15
> -----Original Message-----

> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> Sent: Wednesday, February 15, 2017 11:40 AM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> labs.com>

> Cc: Mike Holmes <mike.holmes@linaro.org>; lng-odp <lng-

> odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> On 15 February 2017 at 09:34, Savolainen, Petri (Nokia - FI/Espoo)

> <petri.savolainen@nokia-bell-labs.com> wrote:

> >

> >

> >> -----Original Message-----

> >> From: Christophe Milard [mailto:christophe.milard@linaro.org]

> >> Sent: Monday, February 13, 2017 5:41 PM

> >> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> >> labs.com>

> >> Cc: Mike Holmes <mike.holmes@linaro.org>; lng-odp <lng-

> >> odp@lists.linaro.org>

> >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to

> >> linux helpers

> >>

> >> This is getting very confusing now: why helper/<OS>?  do we have

> >> odp/<OS>?: shouldn't  these be symetric?

> >

> >

> > Application (like OFP today) which wants to use e.g. Linux pthread

> helpers include:

> >

> > #include <odp_api.h>

> > #include <odp/helper/linux/pthread.h>

> >

> > odph_linux_pthread_create()

> > ...

> > odph_linux_pthread_join()

> >

> >

> > It explicitly uses Linux pthreads through a helper function. There's no

> need to provide these helpers and functions on a non-Linux implementation

> (because there is no Linux).

> >

> > Linux helpers are totally different thing than ODP implementation

> internal directory structure.

> 

> Different: Yes. But related:

> We are back, sadly, to my first question: "what is a platform".

> To that, you, Petri, answered: "platform == implementation". And I agree.


Linux helpers use Linux API and ODP API calls. Those are not aware how an implementation is split into files and folders. So, what is platform discussion does not belong into this thread. This patch fixes the build issue under and renames --enable-helper-thread-extn to --enable-helper-linux, which is more logical and explicit about linux helpers.


> 

> Now, can we agree that the above platform definition implies:

> different OS => different platform? Or are you saying that a OSE ODP

> and linux ODP are the same implementation???.


Each vendor decide their folder structure. If they re-use ours you can either find e.g.

odp/platform/nxp-ls, which includes code for all supported OSes, or

odp/platform/odp-nxp-ls-linux
odp/platform/odp-nxp-ls-ose
odp/platform/odp-nxp-ls-vxworks

I really don't care as long as everything builds and tests run for each OS. I'd prefer platform per vendor + SoC family, so that in the *unlikely case* that everything is installed into the same directory you would see

odp/platform/linux-generic
odp/platform/odp-dpdk
odp/platform/odp-nxp-ls
odp/platform/odp-cavium-thunder
...

But, as said every vendor organize their repo as they like.



> 

> If we can agree that, for ODP implementation, different OSes means

> different platforms, do you feel comfortable calling these variation

> differently for the helpers?


Repo/directory structure is own by vendor/implementation/platform. Helpers depend on APIs. There's no direct link. Helpers are sorted based on the API(s) they depend on.


> 

> What if some helper function requires to be different for a given OS?

> Say for instance, some company wants to implement ODP threads using

> libdill or libmill? (on linux). Or some helper function would depend

> on memory available on a given HW?


odp/helper/linux/pthread.h
odp/helper/linux/dill.h
odp/helper/linux/mill.h
odp/helper/ose/interrupt.h
odp/helper/ose/xyz.h


Helper code uses ODP API exactly the same way as application does: it uses capability APIs if it's concerned about some capability. Helper code is part of application code.



> 

> Yes, ODP implementation and helpers are 2 differents things, but they

> are facing the same issue: They try to implement a given interface

> (the ODP API  for ODP and the helper API for the helpers) on different

> HW, OS, ... I'd say on different platform. I cannot see why helpers

> variants would only be limited to OSes.


No helpers do not have different implementation for different ODP implementation.

Even the "abstract threads" implement (today) abstraction over linux pthread and process, but not e.g. OSE threads. You'd need to add some #ifdef __OSE there to enable OSE support. Maybe first add odp/helper/ose/thread.c and then #ifdef abtract thread to call those functions if application (and helpers) are built against OSE (instead of Linux).



> 

> If we can agree on the above, we should agree that a common solution

> to tackle the same problem would be nice.

> On the ODP implementation side, we agreed that a platform was just a

> way to diverge for the main delivery.

> I still think it makes sense to have the same approach for the helpers:

> If we deliver ODP implementation "linux-gen" and "ODP-dpdk" we should

> deliver 2 variant of helper for these as well (even if they happen to

> be the same).


No, since helper code should be always the same.

Pthread system calls in Linux work the same way, regardless if it's called with odp-linux or odp-dpdk lib installed.

-Petri


> 

> A constructor willing to have his own ODP (whatever the reason) would

> have the framework to diverge: a divergence is a new platform. Both

> for helpers and ODP

> The interesting question is how do we write the code so that these

> divergence would be easy to do and so that maximum code can be reuse.

> That is where the next challenge is.  But first we need to agree on

> what a platform is and how we handle helpers.

> 

> Christophe.

> 

> >

> >

> >>

> >> My view is getting clearer and clearer:

> >> On the test side, was have made tests for {OS, HW}= {linux/PC} and

> >> given the possibility to diverge from these (for any  reason, e.g.

> >> difference of HW or OS) with the use of "platform":

> >> If a test defined on the common validation test is inappropriate for a

> >> ODP developer (whatever the reason), that developer can overwrite this

> >> test (or part of it, such as its setup) with an appropriate one on the

> >> platform side.

> >> Kallray, AFAIK, if using the platform trick for both OS and HW

> divergence.

> >

> > If the system under test is not a Linux system. You cannot run linux

> helper code there and thus you just skip the linux helper tests.

> >

> >

> >>

> >> Why not the same approach on the helper side? We give helpers for

> >> {linux/PC} and provide a way to redefine these function for those who

> >> need to,  on the platform side (e.g. using a weak symbol on the common

> >> helpers and letting those who need define the same function as

> >> "strong" on the helper platform side?... or any other better trick).

> >

> > Why a vendor which do not support Linux would rewrite e.g.

> odph_linux_pthread_create() to emulate Linux pthreads? If the system is

> not Linux, there is no point to run Linux system calls there and

> application would not call odph_linux_pthread_create() there.

> >

> > Remember, helper code is application code. Application would not call

> Linux system calls in an non-Linux system. So, no need for a non-Linux

> based ODP implementation to emulate any Linux system calls.

> >

> >

> >>

> >> Then, any implementer knows where to place their hacks: on the

> >> "platform side". Maybe not best, but at least consistent and clear.

> >>

> >> That would just give helpers, with different platform (for any reason)

> >> implementations.

> >>

> >> The linux-specific helper would of course not fit on the common helper

> >> part as they are linux specific and cannot be implementation on

> >> different OS (platform). Once again, I don't understand why we needed

> >> to do wrappers around well known Linux system calls: IMHO, helpers

> >> should contains functions that we expect to be delivered on any

> >> implementation (OS/HW) helpers, so these linux wrappers don't fit

> >> there.

> >

> > Linux helpers can be used in Linux based systems - may be 90 - 95% of

> all data plane systems today support or can support Linux.

> >

> > Non-Linux systems do not need to run Linux applications (helpers).

> >

> >

> >> If we really want to keep that (I'd vote against), let's create

> >> another directory name for what it is: "linux-wrappers"... and

> >> separate them from function we'd expect to see everywhere (the rest of

> >> the helpers, even if different platform dependent implementations for

> >> those might exist)

> >

> > This patch uses odp/helper/linux/xx.h which is pretty explicit about the

> dependency to Linux. Anything under odp/helper/linux is Linux dependent

> and would not build/run on non-Linux systems. Clear?

> >

> >

> > -Petri

> >

> >

> >

> >

> >

> >>

> >> Christophe

> >>

> >> On 13 February 2017 at 16:09, Savolainen, Petri (Nokia - FI/Espoo)

> >> <petri.savolainen@nokia-bell-labs.com> wrote:

> >> >

> >> >

> >> > From: Mike Holmes [mailto:mike.holmes@linaro.org]

> >> > Sent: Monday, February 13, 2017 5:02 PM

> >> > To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-

> bell-

> >> labs.com>

> >> > Cc: lng-odp <lng-odp@lists.linaro.org>

> >> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed

> threads_extn

> >> to linux helpers

> >> >

> >> >

> >> >

> >> > On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

> >> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

> >> >

> >> >

> >> > From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> >> > Sent: Friday, February 10, 2017 5:02 PM

> >> > To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> >> > Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> >> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed

> threads_extn

> >> to linux helpers

> >> >

> >> >

> >> >

> >> > On 3 February 2017 at 06:23, Petri Savolainen

> >> <mailto:mailto:petri.savolainen@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.

> >> >

> >> > Use --enable-helper-linux configuration option to enable

> >> > support for Linux helpers.

> >> >

> >> > Signed-off-by: Petri Savolainen

> >> <mailto:mailto:petri.savolainen@linaro.org>

> >> >

> >> > Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

> >> >

> >> > required 3 way apply

> >> >

> >> >

> >> >

> >> > This should be merged. It moves linux dependent helper code under

> linux

> >> folder. If there would be helper code dependent on some other OS, that

> >> would go to their own helper/OS_foo/ folder. All Linux based ODP

> >> implementations can run this helper code - there is no need to have N

> >> different linux helpers for N different Linux based implementations.

> >> >

> >> >

> >> > Also, the build is currently broken in master for --enable-helper-

> extn.

> >> E.g. OFP cannot be built against it.

> >> >

> >> > This is not broken IMHO, it is by design, OFP depends on the helpers,

> we

> >> need helpers to either be support for apps that we maintain and don't

> use

> >> (current case) or we enforce  OFP and others to use the abstract API

> that

> >> all our own executable use. Maintaining code we don't use is dangerous,

> >> you should have to choose to do it, but I like the rename, that is fine

> >> and is progress, hence the review.

> >> >

> >> > I think splitting out all of all the executables  will make this much

> >> cleaner.

> >> > All ODP upstream executables will use the abstract API and be

> portable

> >> to any platform and OS. Meanwhile the odp-Linux repo can have a Linux

> >> specific apis such as the legacy one OFP is using and that is just that

> >> implementations choice, as we have said there is no requirement to use

> >> helpers, or linux, and OFP might want to attach itself to that,  but

> the

> >> tests and examples must remain agnostic until we state we are dropping

> >> that goal.

> >> >

> >> >

> >> > Please try:

> >> > ./configure --enable-helper-extn

> >> > make

> >> >

> >> > It does not compile, due to:

> >> >

> >> > platform/linux-generic/thread.c:282:12: error:

> >> \u2018odph_linux_thread_create\u2019 defined but not used [-

> Werror=unused-

> >> function]

> >> >  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

> >> >

> >> >

> >> > My patch fixes this also.

> >> >

> >> >

> >> > -Petri

> >> >

> >> >
Savolainen, Petri (Nokia - FI/Espoo) Feb. 16, 2017, 8:51 a.m. UTC | #16
> -----Original Message-----

> From: Savolainen, Petri (Nokia - FI/Espoo)

> Sent: Monday, February 13, 2017 5:10 PM

> To: 'Mike Holmes' <mike.holmes@linaro.org>

> Cc: lng-odp <lng-odp@lists.linaro.org>

> Subject: RE: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> 

> 

> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> Sent: Monday, February 13, 2017 5:02 PM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> labs.com>

> Cc: lng-odp <lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> 

> 

> On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

> 

> 

> From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> Sent: Friday, February 10, 2017 5:02 PM

> To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> 

> 

> On 3 February 2017 at 06:23, Petri Savolainen

> <mailto:mailto:petri.savolainen@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.

> 

> Use --enable-helper-linux configuration option to enable

> support for Linux helpers.

> 

> Signed-off-by: Petri Savolainen

> <mailto:mailto:petri.savolainen@linaro.org>

> 

> Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

> 

> required 3 way apply

> 

> 

> 

> This should be merged. It moves linux dependent helper code under linux

> folder. If there would be helper code dependent on some other OS, that

> would go to their own helper/OS_foo/ folder. All Linux based ODP

> implementations can run this helper code - there is no need to have N

> different linux helpers for N different Linux based implementations.

> 

> 

> Also, the build is currently broken in master for --enable-helper-extn.

> E.g. OFP cannot be built against it.

> 

> This is not broken IMHO, it is by design, OFP depends on the helpers, we

> need helpers to either be support for apps that we maintain and don't use

> (current case) or we enforce  OFP and others to use the abstract API that

> all our own executable use. Maintaining code we don't use is dangerous,

> you should have to choose to do it, but I like the rename, that is fine

> and is progress, hence the review.

> 

> I think splitting out all of all the executables  will make this much

> cleaner.

> All ODP upstream executables will use the abstract API and be portable to

> any platform and OS. Meanwhile the odp-Linux repo can have a Linux

> specific apis such as the legacy one OFP is using and that is just that

> implementations choice, as we have said there is no requirement to use

> helpers, or linux, and OFP might want to attach itself to that,  but the

> tests and examples must remain agnostic until we state we are dropping

> that goal.

> 

> 

> Please try:

> ./configure --enable-helper-extn

> make

> 

> It does not compile, due to:

> 

> platform/linux-generic/thread.c:282:12: error:

> \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-

> function]

>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

> 

> 

> My patch fixes this also.

> 

> 

> -Petri

>


Could we merge this clean up patch. It does not belong to discussions about:
* what is platform
* cloud profile
* abstract threads

All those can be discussed and done on other mail threads and patches. This patch just explicitly defines that pthread/process functions depend on Linux. Application is free to use those or not. Similarly to e.g. cuckoo hash helper, an application is free to use cuckoo or not. 

Currently the code in the repo (breaks the build and) hints that pthread/process functions do not depend on Linux, but on an ODP implementation which is wrong. Abstract thread helper may depend on implementation, but these pthread/process functions here are not abstract - they use Linux.

-Petri
Maxim Uvarov Feb. 16, 2017, 8:55 p.m. UTC | #17
On 02/16/17 11:51, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> 

> 

>> -----Original Message-----

>> From: Savolainen, Petri (Nokia - FI/Espoo)

>> Sent: Monday, February 13, 2017 5:10 PM

>> To: 'Mike Holmes' <mike.holmes@linaro.org>

>> Cc: lng-odp <lng-odp@lists.linaro.org>

>> Subject: RE: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>>

>>

>> From: Mike Holmes [mailto:mike.holmes@linaro.org]

>> Sent: Monday, February 13, 2017 5:02 PM

>> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

>> labs.com>

>> Cc: lng-odp <lng-odp@lists.linaro.org>

>> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>>

>>

>> On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

>> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

>>

>>

>> From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

>> Sent: Friday, February 10, 2017 5:02 PM

>> To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

>> Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

>> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

>> linux helpers

>>

>>

>>

>> On 3 February 2017 at 06:23, Petri Savolainen

>> <mailto:mailto:petri.savolainen@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.

>>

>> Use --enable-helper-linux configuration option to enable

>> support for Linux helpers.

>>

>> Signed-off-by: Petri Savolainen

>> <mailto:mailto:petri.savolainen@linaro.org>

>>

>> Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

>>

>> required 3 way apply

>>

>>

>>

>> This should be merged. It moves linux dependent helper code under linux

>> folder. If there would be helper code dependent on some other OS, that

>> would go to their own helper/OS_foo/ folder. All Linux based ODP

>> implementations can run this helper code - there is no need to have N

>> different linux helpers for N different Linux based implementations.

>>

>>

>> Also, the build is currently broken in master for --enable-helper-extn.

>> E.g. OFP cannot be built against it.

>>

>> This is not broken IMHO, it is by design, OFP depends on the helpers, we

>> need helpers to either be support for apps that we maintain and don't use

>> (current case) or we enforce  OFP and others to use the abstract API that

>> all our own executable use. Maintaining code we don't use is dangerous,

>> you should have to choose to do it, but I like the rename, that is fine

>> and is progress, hence the review.

>>

>> I think splitting out all of all the executables  will make this much

>> cleaner.

>> All ODP upstream executables will use the abstract API and be portable to

>> any platform and OS. Meanwhile the odp-Linux repo can have a Linux

>> specific apis such as the legacy one OFP is using and that is just that

>> implementations choice, as we have said there is no requirement to use

>> helpers, or linux, and OFP might want to attach itself to that,  but the

>> tests and examples must remain agnostic until we state we are dropping

>> that goal.

>>

>>

>> Please try:

>> ./configure --enable-helper-extn

>> make

>>

>> It does not compile, due to:

>>

>> platform/linux-generic/thread.c:282:12: error:

>> \u2018odph_linux_thread_create\u2019 defined but not used [-Werror=unused-

>> function]

>>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

>>

>>

>> My patch fixes this also.

>>

>>

>> -Petri

>>

> 

> Could we merge this clean up patch. It does not belong to discussions about:

> * what is platform

> * cloud profile

> * abstract threads

> 

> All those can be discussed and done on other mail threads and patches. This patch just explicitly defines that pthread/process functions depend on Linux. Application is free to use those or not. Similarly to e.g. cuckoo hash helper, an application is free to use cuckoo or not. 

> 

> Currently the code in the repo (breaks the build and) hints that pthread/process functions do not depend on Linux, but on an ODP implementation which is wrong. Abstract thread helper may depend on implementation, but these pthread/process functions here are not abstract - they use Linux.

> 

> -Petri

> 


Ok, I applied 1/2. 2/2 has rejects. Can you please rebase it?

Maxim.
Savolainen, Petri (Nokia - FI/Espoo) Feb. 17, 2017, 9:39 a.m. UTC | #18
> -----Original Message-----

> From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of Maxim

> Uvarov

> Sent: Thursday, February 16, 2017 10:55 PM

> To: lng-odp@lists.linaro.org

> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> linux helpers

> 

> On 02/16/17 11:51, Savolainen, Petri (Nokia - FI/Espoo) wrote:

> >

> >

> >> -----Original Message-----

> >> From: Savolainen, Petri (Nokia - FI/Espoo)

> >> Sent: Monday, February 13, 2017 5:10 PM

> >> To: 'Mike Holmes' <mike.holmes@linaro.org>

> >> Cc: lng-odp <lng-odp@lists.linaro.org>

> >> Subject: RE: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to

> >> linux helpers

> >>

> >>

> >>

> >> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> >> Sent: Monday, February 13, 2017 5:02 PM

> >> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> >> labs.com>

> >> Cc: lng-odp <lng-odp@lists.linaro.org>

> >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to

> >> linux helpers

> >>

> >>

> >>

> >> On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

> >> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

> >>

> >>

> >> From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> >> Sent: Friday, February 10, 2017 5:02 PM

> >> To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> >> Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> to

> >> linux helpers

> >>

> >>

> >>

> >> On 3 February 2017 at 06:23, Petri Savolainen

> >> <mailto:mailto:petri.savolainen@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.

> >>

> >> Use --enable-helper-linux configuration option to enable

> >> support for Linux helpers.

> >>

> >> Signed-off-by: Petri Savolainen

> >> <mailto:mailto:petri.savolainen@linaro.org>

> >>

> >> Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

> >>

> >> required 3 way apply

> >>

> >>

> >>

> >> This should be merged. It moves linux dependent helper code under linux

> >> folder. If there would be helper code dependent on some other OS, that

> >> would go to their own helper/OS_foo/ folder. All Linux based ODP

> >> implementations can run this helper code - there is no need to have N

> >> different linux helpers for N different Linux based implementations.

> >>

> >>

> >> Also, the build is currently broken in master for --enable-helper-extn.

> >> E.g. OFP cannot be built against it.

> >>

> >> This is not broken IMHO, it is by design, OFP depends on the helpers,

> we

> >> need helpers to either be support for apps that we maintain and don't

> use

> >> (current case) or we enforce  OFP and others to use the abstract API

> that

> >> all our own executable use. Maintaining code we don't use is dangerous,

> >> you should have to choose to do it, but I like the rename, that is fine

> >> and is progress, hence the review.

> >>

> >> I think splitting out all of all the executables  will make this much

> >> cleaner.

> >> All ODP upstream executables will use the abstract API and be portable

> to

> >> any platform and OS. Meanwhile the odp-Linux repo can have a Linux

> >> specific apis such as the legacy one OFP is using and that is just that

> >> implementations choice, as we have said there is no requirement to use

> >> helpers, or linux, and OFP might want to attach itself to that,  but

> the

> >> tests and examples must remain agnostic until we state we are dropping

> >> that goal.

> >>

> >>

> >> Please try:

> >> ./configure --enable-helper-extn

> >> make

> >>

> >> It does not compile, due to:

> >>

> >> platform/linux-generic/thread.c:282:12: error:

> >> \u2018odph_linux_thread_create\u2019 defined but not used [-

> Werror=unused-

> >> function]

> >>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

> >>

> >>

> >> My patch fixes this also.

> >>

> >>

> >> -Petri

> >>

> >

> > Could we merge this clean up patch. It does not belong to discussions

> about:

> > * what is platform

> > * cloud profile

> > * abstract threads

> >

> > All those can be discussed and done on other mail threads and patches.

> This patch just explicitly defines that pthread/process functions depend

> on Linux. Application is free to use those or not. Similarly to e.g.

> cuckoo hash helper, an application is free to use cuckoo or not.

> >

> > Currently the code in the repo (breaks the build and) hints that

> pthread/process functions do not depend on Linux, but on an ODP

> implementation which is wrong. Abstract thread helper may depend on

> implementation, but these pthread/process functions here are not abstract

> - they use Linux.

> >

> > -Petri

> >

> 

> Ok, I applied 1/2. 2/2 has rejects. Can you please rebase it?

> 

> Maxim.


2/2 is not needed anymore. It fixed missing doxygen documentation, but those were fixed since by other patch.

-Petri
Maxim Uvarov Feb. 17, 2017, 9:40 a.m. UTC | #19
ok, thanks.

On 17 February 2017 at 12:39, Savolainen, Petri (Nokia - FI/Espoo) <
petri.savolainen@nokia-bell-labs.com> wrote:

>

>

> > -----Original Message-----

> > From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of

> Maxim

> > Uvarov

> > Sent: Thursday, February 16, 2017 10:55 PM

> > To: lng-odp@lists.linaro.org

> > Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn to

> > linux helpers

> >

> > On 02/16/17 11:51, Savolainen, Petri (Nokia - FI/Espoo) wrote:

> > >

> > >

> > >> -----Original Message-----

> > >> From: Savolainen, Petri (Nokia - FI/Espoo)

> > >> Sent: Monday, February 13, 2017 5:10 PM

> > >> To: 'Mike Holmes' <mike.holmes@linaro.org>

> > >> Cc: lng-odp <lng-odp@lists.linaro.org>

> > >> Subject: RE: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> > to

> > >> linux helpers

> > >>

> > >>

> > >>

> > >> From: Mike Holmes [mailto:mike.holmes@linaro.org]

> > >> Sent: Monday, February 13, 2017 5:02 PM

> > >> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell-

> > >> labs.com>

> > >> Cc: lng-odp <lng-odp@lists.linaro.org>

> > >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> > to

> > >> linux helpers

> > >>

> > >>

> > >>

> > >> On 13 February 2017 at 09:41, Savolainen, Petri (Nokia - FI/Espoo)

> > >> <mailto:petri.savolainen@nokia-bell-labs.com> wrote:

> > >>

> > >>

> > >> From: Mike Holmes [mailto:mailto:mike.holmes@linaro.org]

> > >> Sent: Friday, February 10, 2017 5:02 PM

> > >> To: Petri Savolainen <mailto:petri.savolainen@linaro.org>

> > >> Cc: lng-odp <mailto:lng-odp@lists.linaro.org>

> > >> Subject: Re: [lng-odp] [PATCH 1/2] helper: linux: renamed threads_extn

> > to

> > >> linux helpers

> > >>

> > >>

> > >>

> > >> On 3 February 2017 at 06:23, Petri Savolainen

> > >> <mailto:mailto:petri.savolainen@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.

> > >>

> > >> Use --enable-helper-linux configuration option to enable

> > >> support for Linux helpers.

> > >>

> > >> Signed-off-by: Petri Savolainen

> > >> <mailto:mailto:petri.savolainen@linaro.org>

> > >>

> > >> Reviewed-by: Mike Holmes <mailto:mailto:mike.holmes@linaro.org>

> > >>

> > >> required 3 way apply

> > >>

> > >>

> > >>

> > >> This should be merged. It moves linux dependent helper code under

> linux

> > >> folder. If there would be helper code dependent on some other OS, that

> > >> would go to their own helper/OS_foo/ folder. All Linux based ODP

> > >> implementations can run this helper code - there is no need to have N

> > >> different linux helpers for N different Linux based implementations.

> > >>

> > >>

> > >> Also, the build is currently broken in master for

> --enable-helper-extn.

> > >> E.g. OFP cannot be built against it.

> > >>

> > >> This is not broken IMHO, it is by design, OFP depends on the helpers,

> > we

> > >> need helpers to either be support for apps that we maintain and don't

> > use

> > >> (current case) or we enforce  OFP and others to use the abstract API

> > that

> > >> all our own executable use. Maintaining code we don't use is

> dangerous,

> > >> you should have to choose to do it, but I like the rename, that is

> fine

> > >> and is progress, hence the review.

> > >>

> > >> I think splitting out all of all the executables  will make this much

> > >> cleaner.

> > >> All ODP upstream executables will use the abstract API and be portable

> > to

> > >> any platform and OS. Meanwhile the odp-Linux repo can have a Linux

> > >> specific apis such as the legacy one OFP is using and that is just

> that

> > >> implementations choice, as we have said there is no requirement to use

> > >> helpers, or linux, and OFP might want to attach itself to that,  but

> > the

> > >> tests and examples must remain agnostic until we state we are dropping

> > >> that goal.

> > >>

> > >>

> > >> Please try:

> > >> ./configure --enable-helper-extn

> > >> make

> > >>

> > >> It does not compile, due to:

> > >>

> > >> platform/linux-generic/thread.c:282:12: error:

> > >> \u2018odph_linux_thread_create\u2019 defined but not used [-

> > Werror=unused-

> > >> function]

> > >>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,

> > >>

> > >>

> > >> My patch fixes this also.

> > >>

> > >>

> > >> -Petri

> > >>

> > >

> > > Could we merge this clean up patch. It does not belong to discussions

> > about:

> > > * what is platform

> > > * cloud profile

> > > * abstract threads

> > >

> > > All those can be discussed and done on other mail threads and patches.

> > This patch just explicitly defines that pthread/process functions depend

> > on Linux. Application is free to use those or not. Similarly to e.g.

> > cuckoo hash helper, an application is free to use cuckoo or not.

> > >

> > > Currently the code in the repo (breaks the build and) hints that

> > pthread/process functions do not depend on Linux, but on an ODP

> > implementation which is wrong. Abstract thread helper may depend on

> > implementation, but these pthread/process functions here are not abstract

> > - they use Linux.

> > >

> > > -Petri

> > >

> >

> > Ok, I applied 1/2. 2/2 has rejects. Can you please rebase it?

> >

> > Maxim.

>

> 2/2 is not needed anymore. It fixed missing doxygen documentation, but

> those were fixed since by other patch.

>

> -Petri

>

>
diff mbox series

Patch

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 =  \