On 2016-12-23 14:15, Mike Holmes wrote:
> Only the portable api is built by default, use --enable-helper-extn
> to enable non portable APIs for a helper platform
> 
> Signed-off-by: Mike Holmes <[email protected]>
> ---

I am probably missing something, but, seen from the original file,
I would have expected everything preceeding the following comment...
/*
 * wrapper for odpthreads, either implemented as linux threads or processes.
 * (in process mode, if start_routine returns NULL, the process return FAILURE).
 */
...to be in the linux part.
(I already did the separation as I expected the linux only stuff to be
 deleted, but that was nacked as you know)

Why isn't it as simple as I thought?

Mike: You can HO me when you have time

Christophe


>  configure.ac                                       |  17 +-
>  example/Makefile.inc                               |   2 +-
>  helper/Makefile.am                                 |  15 +-
>  .../helper/platform/linux-generic/threads_extn.h   | 112 ++++++++
>  helper/include/odp/helper/threads.h                |  76 -----
>  helper/m4/configure.m4                             |  11 +
>  helper/odph_thread_internal.h                      |  27 ++
>  helper/platform/linux-generic/thread.c             | 256 +++++++++++++++++
>  helper/test/Makefile.am                            |  17 +-
>  helper/test/linux-generic/Makefile.am              |   5 +
>  helper/test/{ => linux-generic}/process.c          |   2 +-
>  helper/test/{ => linux-generic}/thread.c           |   2 +-
>  helper/threads.c                                   | 314 
> ++++-----------------
>  ...inux.pc.in => libodphelper-linux-generic.pc.in} |   4 +-
>  test/Makefile.inc                                  |   2 +-
>  test/common_plat/validation/api/Makefile.inc       |   2 +-
>  test/linux-generic/Makefile.inc                    |   2 +-
>  17 files changed, 515 insertions(+), 351 deletions(-)
>  create mode 100644 
> helper/include/odp/helper/platform/linux-generic/threads_extn.h
>  create mode 100644 helper/odph_thread_internal.h
>  create mode 100644 helper/platform/linux-generic/thread.c
>  create mode 100644 helper/test/linux-generic/Makefile.am
>  rename helper/test/{ => linux-generic}/process.c (97%)
>  rename helper/test/{ => linux-generic}/thread.c (97%)
>  rename pkgconfig/{libodphelper-linux.pc.in => 
> libodphelper-linux-generic.pc.in} (72%)
> 
> diff --git a/configure.ac b/configure.ac
> index 4fec9d5..001cab9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -138,6 +138,18 @@ AC_SUBST([with_platform])
>  AC_SUBST([platform_with_platform], ["platform/${with_platform}"])
>  
>  ##########################################################################
> +# Determine which helper platform to build for
> +##########################################################################
> +AC_ARG_WITH([helper_platform],
> +    [AS_HELP_STRING([--with-helper_platform=platform],
> +     [select helper platform to be used, default linux-generic])],
> +    [],
> +    [with_helper_platform=${with_platform}
> +    ])
> +
> +AC_SUBST([with_helper_platform])
> +
> +##########################################################################
>  # Run platform specific checks and settings
>  ##########################################################################
>  IMPLEMENTATION_NAME=""
> @@ -202,6 +214,7 @@ AM_CONDITIONAL([test_example], [test x$test_example = 
> xyes ])
>  AM_CONDITIONAL([HAVE_DOXYGEN], [test "x${DOXYGEN}" = "xdoxygen"])
>  AM_CONDITIONAL([user_guide], [test "x${user_guides}" = "xyes" ])
>  AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"])
> +AM_CONDITIONAL([helper_ext], [test x$helper_ext = xyes ])
>  
>  ##########################################################################
>  # Setup doxygen documentation
> @@ -293,7 +306,7 @@ AM_CXXFLAGS="-std=c++11"
>  
>  AC_CONFIG_FILES([Makefile
>                pkgconfig/libodp-linux.pc
> -              pkgconfig/libodphelper-linux.pc
> +              pkgconfig/libodphelper-linux-generic.pc
>                ])
>  
>  AC_SEARCH_LIBS([timer_create],[rt posix4])
> @@ -320,6 +333,8 @@ AC_MSG_RESULT([
>       implementation_name:    ${IMPLEMENTATION_NAME}
>       ARCH_DIR                ${ARCH_DIR}
>       with_platform:          ${with_platform}
> +     with_helper_platform:   ${with_helper_platform}
> +     helper_ext:             ${helper_ext}
>       prefix:                 ${prefix}
>       sysconfdir:             ${sysconfdir}
>       libdir:                 ${libdir}
> diff --git a/example/Makefile.inc b/example/Makefile.inc
> index 19d3994..ea596d5 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-linux.la
> +LDADD = $(LIB)/libodp-linux.la $(LIB)/libodphelper-@[email protected]
>  AM_CFLAGS += \
>       -I$(srcdir) \
>       -I$(top_srcdir)/example \
> diff --git a/helper/Makefile.am b/helper/Makefile.am
> index 71c6975..66d60dd 100644
> --- a/helper/Makefile.am
> +++ b/helper/Makefile.am
> @@ -1,7 +1,7 @@
>  include $(top_srcdir)/platform/@with_platform@/Makefile.inc
>  
>  pkgconfigdir = $(libdir)/pkgconfig
> -pkgconfig_DATA = $(top_builddir)/pkgconfig/libodphelper-linux.pc
> +pkgconfig_DATA = 
> $(top_builddir)/pkgconfig/libodphelper-@[email protected]
>  
>  LIB   = $(top_builddir)/lib
>  AM_CFLAGS  = -I$(srcdir)/include
> @@ -25,18 +25,25 @@ helperinclude_HEADERS = \
>                 $(srcdir)/include/odp/helper/table.h\
>                 $(srcdir)/include/odp/helper/udp.h
>  
> +if helper_ext
> +helperinclude_HEADERS += \
> +     
> $(srcdir)/include/odp/helper/platform/@with_helper_platform@/threads_extn.h
> +endif
> +
>  noinst_HEADERS = \
>                $(srcdir)/odph_debug.h \
>                $(srcdir)/odph_hashtable.h \
>                $(srcdir)/odph_lineartable.h \
> -              $(srcdir)/odph_list_internal.h
> +              $(srcdir)/odph_list_internal.h \
> +              $(srcdir)/odph_thread_internal.h
>  
> -__LIB__libodphelper_linux_la_SOURCES = \
> +__LIB__libodphelper_@with_helper_platform@_la_SOURCES = \
>                                       eth.c \
>                                       ip.c \
>                                       chksum.c \
>                                       threads.c \
> +                                     
> platform/@with_helper_platform@/thread.c \
>                                       hashtable.c \
>                                       lineartable.c
>  
> -lib_LTLIBRARIES = $(LIB)/libodphelper-linux.la
> +lib_LTLIBRARIES = $(LIB)/libodphelper-@[email protected]
> diff --git a/helper/include/odp/helper/platform/linux-generic/threads_extn.h 
> b/helper/include/odp/helper/platform/linux-generic/threads_extn.h
> new file mode 100644
> index 0000000..1d4036d
> --- /dev/null
> +++ b/helper/include/odp/helper/platform/linux-generic/threads_extn.h
> @@ -0,0 +1,112 @@
> +/* Copyright (c) 2016, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:     BSD-3-Clause
> + */
> +
> +/**
> + * @file
> + *
> + * ODP Linux helper extension API
> + *
> + * This file is an optional helper to odp.h APIs. These functions are 
> provided
> + * to ease common setups in a Linux system. User is free to implement the 
> same
> + * setups in otherways (not via this API).
> + */
> +
> +#ifndef ODPH_LINUX_EXT_H_
> +#define ODPH_LINUX_EXT_H_
> +
> +#include <odp/helper/threads.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/** @addtogroup odph_linux ODPH LINUX
> + *  @{
> + */
> +
> +/**
> + * Creates and launches pthreads
> + *
> + * Creates, pins and launches threads to separate CPU's based on the cpumask.
> + *
> + * @param[out] pthread_tbl Table of pthread state information records. Table
> + *                         must have at least as many entries as there are
> + *                         CPUs in the CPU mask.
> + * @param      mask        CPU mask
> + * @param      thr_params  Linux helper thread parameters
> + *
> + * @return Number of threads created
> + */
> +int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
> +                           const odp_cpumask_t *mask,
> +                           const odph_linux_thr_params_t *thr_params);
> +
> +/**
> + * Waits pthreads to exit
> + *
> + * Returns when all threads have been exit.
> + *
> + * @param thread_tbl    Thread table
> + * @param num           Number of threads to create
> + *
> + */
> +void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num);
> +
> +/**
> + * Fork a process
> + *
> + * Forks and sets CPU affinity for the child process. Ignores 'start' and 
> 'arg'
> + * thread parameters.
> + *
> + * @param[out] proc        Pointer to process state info (for output)
> + * @param      cpu         Destination CPU for the child process
> + * @param      thr_params  Linux helper thread parameters
> + *
> + * @return On success: 1 for the parent, 0 for the child
> + *         On failure: -1 for the parent, -2 for the child
> + */
> +int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
> +                         const odph_linux_thr_params_t *thr_params);
> +
> +/**
> + * Fork a number of processes
> + *
> + * Forks and sets CPU affinity for child processes. Ignores 'start' and 'arg'
> + * thread parameters.
> + *
> + * @param[out] proc_tbl    Process state info table (for output)
> + * @param      mask        CPU mask of processes to create
> + * @param      thr_params  Linux helper thread parameters
> + *
> + * @return On success: 1 for the parent, 0 for the child
> + *         On failure: -1 for the parent, -2 for the child
> + */
> +int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
> +                           const odp_cpumask_t *mask,
> +                           const odph_linux_thr_params_t *thr_params);
> +
> +/**
> + * Wait for a number of processes
> + *
> + * Waits for a number of child processes to terminate. Records process state
> + * change status into the process state info structure.
> + *
> + * @param proc_tbl      Process state info table (previously filled by fork)
> + * @param num           Number of processes to wait
> + *
> + * @return 0 on success, -1 on failure
> + */
> +int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num);
> +
> +/**
> + * @}
> + */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/helper/include/odp/helper/threads.h 
> b/helper/include/odp/helper/threads.h
> index b8d975a..5682bab 100644
> --- a/helper/include/odp/helper/threads.h
> +++ b/helper/include/odp/helper/threads.h
> @@ -93,82 +93,6 @@ typedef struct {
>  } odph_odpthread_t;
>  
>  /**
> - * Creates and launches pthreads
> - *
> - * Creates, pins and launches threads to separate CPU's based on the cpumask.
> - *
> - * @param[out] pthread_tbl Table of pthread state information records. Table
> - *                         must have at least as many entries as there are
> - *                         CPUs in the CPU mask.
> - * @param      mask        CPU mask
> - * @param      thr_params  Linux helper thread parameters
> - *
> - * @return Number of threads created
> - */
> -int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
> -                           const odp_cpumask_t *mask,
> -                           const odph_linux_thr_params_t *thr_params);
> -
> -/**
> - * Waits pthreads to exit
> - *
> - * Returns when all threads have been exit.
> - *
> - * @param thread_tbl    Thread table
> - * @param num           Number of threads to create
> - *
> - */
> -void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num);
> -
> -/**
> - * Fork a process
> - *
> - * Forks and sets CPU affinity for the child process. Ignores 'start' and 
> 'arg'
> - * thread parameters.
> - *
> - * @param[out] proc        Pointer to process state info (for output)
> - * @param      cpu         Destination CPU for the child process
> - * @param      thr_params  Linux helper thread parameters
> - *
> - * @return On success: 1 for the parent, 0 for the child
> - *         On failure: -1 for the parent, -2 for the child
> - */
> -int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
> -                         const odph_linux_thr_params_t *thr_params);
> -
> -
> -/**
> - * Fork a number of processes
> - *
> - * Forks and sets CPU affinity for child processes. Ignores 'start' and 'arg'
> - * thread parameters.
> - *
> - * @param[out] proc_tbl    Process state info table (for output)
> - * @param      mask        CPU mask of processes to create
> - * @param      thr_params  Linux helper thread parameters
> - *
> - * @return On success: 1 for the parent, 0 for the child
> - *         On failure: -1 for the parent, -2 for the child
> - */
> -int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
> -                           const odp_cpumask_t *mask,
> -                           const odph_linux_thr_params_t *thr_params);
> -
> -
> -/**
> - * Wait for a number of processes
> - *
> - * Waits for a number of child processes to terminate. Records process state
> - * change status into the process state info structure.
> - *
> - * @param proc_tbl      Process state info table (previously filled by fork)
> - * @param num           Number of processes to wait
> - *
> - * @return 0 on success, -1 on failure
> - */
> -int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num);
> -
> -/**
>   * Creates and launches odpthreads (as linux threads or processes)
>   *
>   * Creates, pins and launches threads to separate CPU's based on the cpumask.
> diff --git a/helper/m4/configure.m4 b/helper/m4/configure.m4
> index b8a21f7..8f1c929 100644
> --- a/helper/m4/configure.m4
> +++ b/helper/m4/configure.m4
> @@ -8,5 +8,16 @@ AC_ARG_ENABLE([test-helper],
>          test_helper=yes
>      fi])
>  
> +##########################################################################
> +# Enable/disable helper-ext
> +# platform specific non portable extensions
> +##########################################################################
> +helper_ext=no
> +AC_ARG_ENABLE([helper-ext],
> +     [  --enable-helper-ext  build helper platform extensions (not 
> portable)],
> +     [if test "x$enableval" = "xyes"; then
> +             helper_ext=yes
> +     fi])
> +
>  AC_CONFIG_FILES([helper/Makefile
>                               helper/test/Makefile])
> diff --git a/helper/odph_thread_internal.h b/helper/odph_thread_internal.h
> new file mode 100644
> index 0000000..24d5e09
> --- /dev/null
> +++ b/helper/odph_thread_internal.h
> @@ -0,0 +1,27 @@
> +/* Copyright (c) 2016, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:     BSD-3-Clause
> + */
> +
> +/**
> + * @file
> + *
> + * ODP Helper internal thread APIs
> + */
> +
> +#ifndef ODPH_THREAD_INTERNAL_H_
> +#define ODPH_THREAD_INTERNAL_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +void *_odph_run_start_routine(void *arg);
> +void *_odph_thread_run_start_routine(void *arg);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/helper/platform/linux-generic/thread.c 
> b/helper/platform/linux-generic/thread.c
> new file mode 100644
> index 0000000..b6424a7
> --- /dev/null
> +++ b/helper/platform/linux-generic/thread.c
> @@ -0,0 +1,256 @@
> +/* 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_thread_internal.h>
> +#include "odph_debug.h"
> +
> +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/Makefile.am b/helper/test/Makefile.am
> index 545db73..47dcb86 100644
> --- a/helper/test/Makefile.am
> +++ b/helper/test/Makefile.am
> @@ -6,11 +6,18 @@ AM_LDFLAGS += -static
>  TESTS_ENVIRONMENT += TEST_DIR=${builddir}
>  
>  EXECUTABLES = chksum$(EXEEXT) \
> -              thread$(EXEEXT) \
>                parse$(EXEEXT)\
> -              process$(EXEEXT)\
>                table$(EXEEXT)
>  
> +#These are platform specific extensions that are not portable
> +#They are a convenience to app writers who have chosen to
> +#restrict their application to Linux.
> +
> +if helper_ext
> +EXECUTABLES += @with_helper_platform@/thread$(EXEEXT) \
> +               @with_helper_platform@/process$(EXEEXT)
> +endif
> +
>  COMPILE_ONLY = odpthreads
>  
>  TESTSCRIPTS = odpthreads_as_processes \
> @@ -28,10 +35,6 @@ EXTRA_DIST = odpthreads_as_processes odpthreads_as_pthreads
>  
>  dist_chksum_SOURCES = chksum.c
>  dist_odpthreads_SOURCES = odpthreads.c
> -odpthreads_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
> -dist_thread_SOURCES = thread.c
> -thread_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
> -dist_process_SOURCES = process.c
> +odpthreads_LDADD = $(LIB)/libodphelper-@[email protected] 
> $(LIB)/libodp-linux.la
>  dist_parse_SOURCES = parse.c
> -process_LDADD = $(LIB)/libodphelper-linux.la $(LIB)/libodp-linux.la
>  dist_table_SOURCES = table.c
> diff --git a/helper/test/linux-generic/Makefile.am 
> b/helper/test/linux-generic/Makefile.am
> new file mode 100644
> index 0000000..28d54a8
> --- /dev/null
> +++ b/helper/test/linux-generic/Makefile.am
> @@ -0,0 +1,5 @@
> +
> +thread_LDADD = $(LIB)/libodphelper-@[email protected] 
> $(LIB)/libodp-linux.la
> +dist_thread_SOURCES = thread.c
> +dist_process_SOURCES = process.c
> +process_LDADD = $(LIB)/libodphelper-@[email protected] 
> $(LIB)/libodp-linux.la
> diff --git a/helper/test/process.c b/helper/test/linux-generic/process.c
> similarity index 97%
> rename from helper/test/process.c
> rename to helper/test/linux-generic/process.c
> index f3c6d50..f641128 100644
> --- a/helper/test/process.c
> +++ b/helper/test/linux-generic/process.c
> @@ -6,7 +6,7 @@
>  
>  #include <test_debug.h>
>  #include <odp_api.h>
> -#include <odp/helper/threads.h>
> +#include <odp/helper/platform/linux-generic/threads_extn.h>
>  
>  #define NUMBER_WORKERS 16 /* 0 = max */
>  
> diff --git a/helper/test/thread.c b/helper/test/linux-generic/thread.c
> similarity index 97%
> rename from helper/test/thread.c
> rename to helper/test/linux-generic/thread.c
> index da94b49..f1ca1b7 100644
> --- a/helper/test/thread.c
> +++ b/helper/test/linux-generic/thread.c
> @@ -6,7 +6,7 @@
>  
>  #include <test_debug.h>
>  #include <odp_api.h>
> -#include <odp/helper/threads.h>
> +#include <odp/helper/platform/linux-generic/threads_extn.h>
>  
>  #define NUMBER_WORKERS 16
>  static void *worker_fn(void *arg TEST_UNUSED)
> diff --git a/helper/threads.c b/helper/threads.c
> index d5215c2..edfbe0e 100644
> --- a/helper/threads.c
> +++ b/helper/threads.c
> @@ -9,25 +9,24 @@
>  #endif
>  #include <sched.h>
>  #include <unistd.h>
> -#include <sys/types.h>
>  #include <sys/wait.h>
>  #include <sys/prctl.h>
>  #include <sys/syscall.h>
>  
> -#include <stdlib.h>
> -#include <string.h>
> -#include <stdio.h>
> -#include <stdbool.h>
> -
>  #include <odp_api.h>
>  #include <odp/helper/threads.h>
>  #include "odph_debug.h"
>  
> +static int _odph_linux_process_create(odph_odpthread_t *thread_tbl,
> +                                   int cpu,
> +                                   const odph_odpthread_params_t *thr_params
> +                                   );
> +
>  static struct {
>       int proc; /* true when process mode is required, false otherwise */
>  } helper_options;
>  
> -static void *odp_run_start_routine(void *arg)
> +void *_odph_run_start_routine(void *arg)
>  {
>       odph_linux_thr_params_t *thr_params = arg;
>  
> @@ -48,206 +47,11 @@ static void *odp_run_start_routine(void *arg)
>       return ret_ptr;
>  }
>  
> -int odph_linux_pthread_create(odph_linux_pthread_t *pthread_tbl,
> -                           const odp_cpumask_t *mask,
> -                           const odph_linux_thr_params_t *thr_params)
> -{
> -     int i;
> -     int num;
> -     int cpu_count;
> -     int cpu;
> -     int ret;
> -
> -     num = odp_cpumask_count(mask);
> -
> -     memset(pthread_tbl, 0, num * sizeof(odph_linux_pthread_t));
> -
> -     cpu_count = odp_cpu_count();
> -
> -     if (num < 1 || num > cpu_count) {
> -             ODPH_ERR("Invalid number of threads:%d (%d cores available)\n",
> -                      num, cpu_count);
> -             return 0;
> -     }
> -
> -     cpu = odp_cpumask_first(mask);
> -     for (i = 0; i < num; i++) {
> -             cpu_set_t cpu_set;
> -
> -             CPU_ZERO(&cpu_set);
> -             CPU_SET(cpu, &cpu_set);
> -
> -             pthread_attr_init(&pthread_tbl[i].attr);
> -
> -             pthread_tbl[i].cpu = cpu;
> -
> -             pthread_attr_setaffinity_np(&pthread_tbl[i].attr,
> -                                         sizeof(cpu_set_t), &cpu_set);
> -
> -             pthread_tbl[i].thr_params.start    = thr_params->start;
> -             pthread_tbl[i].thr_params.arg      = thr_params->arg;
> -             pthread_tbl[i].thr_params.thr_type = thr_params->thr_type;
> -             pthread_tbl[i].thr_params.instance = thr_params->instance;
> -
> -             ret = pthread_create(&pthread_tbl[i].thread,
> -                                  &pthread_tbl[i].attr,
> -                                  odp_run_start_routine,
> -                                  &pthread_tbl[i].thr_params);
> -             if (ret != 0) {
> -                     ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
> -                     break;
> -             }
> -
> -             cpu = odp_cpumask_next(mask, cpu);
> -     }
> -
> -     return i;
> -}
> -
> -void odph_linux_pthread_join(odph_linux_pthread_t *thread_tbl, int num)
> -{
> -     int i;
> -     int ret;
> -
> -     for (i = 0; i < num; i++) {
> -             /* Wait thread to exit */
> -             ret = pthread_join(thread_tbl[i].thread, NULL);
> -             if (ret != 0) {
> -                     ODPH_ERR("Failed to join thread from cpu #%d\n",
> -                              thread_tbl[i].cpu);
> -             }
> -             pthread_attr_destroy(&thread_tbl[i].attr);
> -     }
> -}
> -
> -int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
> -                           const odp_cpumask_t *mask,
> -                           const odph_linux_thr_params_t *thr_params)
> -{
> -     pid_t pid;
> -     int num;
> -     int cpu_count;
> -     int cpu;
> -     int i;
> -
> -     num = odp_cpumask_count(mask);
> -
> -     memset(proc_tbl, 0, num * sizeof(odph_linux_process_t));
> -
> -     cpu_count = odp_cpu_count();
> -
> -     if (num < 1 || num > cpu_count) {
> -             ODPH_ERR("Bad num\n");
> -             return -1;
> -     }
> -
> -     cpu = odp_cpumask_first(mask);
> -     for (i = 0; i < num; i++) {
> -             cpu_set_t cpu_set;
> -
> -             CPU_ZERO(&cpu_set);
> -             CPU_SET(cpu, &cpu_set);
> -
> -             pid = fork();
> -
> -             if (pid < 0) {
> -                     ODPH_ERR("fork() failed\n");
> -                     return -1;
> -             }
> -
> -             /* Parent continues to fork */
> -             if (pid > 0) {
> -                     proc_tbl[i].pid  = pid;
> -                     proc_tbl[i].cpu = cpu;
> -
> -                     cpu = odp_cpumask_next(mask, cpu);
> -                     continue;
> -             }
> -
> -             /* Child process */
> -
> -             /* Request SIGTERM if parent dies */
> -             prctl(PR_SET_PDEATHSIG, SIGTERM);
> -             /* Parent died already? */
> -             if (getppid() == 1)
> -                     kill(getpid(), SIGTERM);
> -
> -             if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set)) {
> -                     ODPH_ERR("sched_setaffinity() failed\n");
> -                     return -2;
> -             }
> -
> -             if (odp_init_local(thr_params->instance,
> -                                thr_params->thr_type)) {
> -                     ODPH_ERR("Local init failed\n");
> -                     return -2;
> -             }
> -
> -             return 0;
> -     }
> -
> -     return 1;
> -}
> -
> -int odph_linux_process_fork(odph_linux_process_t *proc, int cpu,
> -                         const odph_linux_thr_params_t *thr_params)
> -{
> -     odp_cpumask_t mask;
> -
> -     odp_cpumask_zero(&mask);
> -     odp_cpumask_set(&mask, cpu);
> -     return odph_linux_process_fork_n(proc, &mask, thr_params);
> -}
> -
> -int odph_linux_process_wait_n(odph_linux_process_t *proc_tbl, int num)
> -{
> -     pid_t pid;
> -     int i, j;
> -     int status = 0;
> -
> -     for (i = 0; i < num; i++) {
> -             pid = wait(&status);
> -
> -             if (pid < 0) {
> -                     ODPH_ERR("wait() failed\n");
> -                     return -1;
> -             }
> -
> -             for (j = 0; j < num; j++) {
> -                     if (proc_tbl[j].pid == pid) {
> -                             proc_tbl[j].status = status;
> -                             break;
> -                     }
> -             }
> -
> -             if (j == num) {
> -                     ODPH_ERR("Bad pid:%d\n", (int)pid);
> -                     return -1;
> -             }
> -
> -             /* Examine the child process' termination status */
> -             if (WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS) {
> -                     ODPH_ERR("Child exit status:%d (pid:%d)\n",
> -                              WEXITSTATUS(status), (int)pid);
> -                     return -1;
> -             }
> -             if (WIFSIGNALED(status)) {
> -                     int signo = WTERMSIG(status);
> -
> -                     ODPH_ERR("Child term signo:%d - %s (pid:%d)\n",
> -                              signo, strsignal(signo), (int)pid);
> -                     return -1;
> -             }
> -     }
> -
> -     return 0;
> -}
> -
>  /*
>   * wrapper for odpthreads, either implemented as linux threads or processes.
>   * (in process mode, if start_routine returns NULL, the process return 
> FAILURE).
>   */
> -static void *odpthread_run_start_routine(void *arg)
> +void *_odph_thread_run_start_routine(void *arg)
>  {
>       int status;
>       int ret;
> @@ -289,54 +93,6 @@ static void *odpthread_run_start_routine(void *arg)
>  }
>  
>  /*
> - * Create a single ODPthread as a linux process
> - */
> -static int odph_linux_process_create(odph_odpthread_t *thread_tbl,
> -                                  int cpu,
> -                                  const odph_odpthread_params_t *thr_params)
> -{
> -     cpu_set_t cpu_set;
> -     pid_t pid;
> -
> -     CPU_ZERO(&cpu_set);
> -     CPU_SET(cpu, &cpu_set);
> -
> -     thread_tbl->start_args.thr_params    = *thr_params; /* copy */
> -     thread_tbl->start_args.linuxtype     = ODPTHREAD_PROCESS;
> -     thread_tbl->cpu = cpu;
> -
> -     pid = fork();
> -     if (pid < 0) {
> -             ODPH_ERR("fork() failed\n");
> -             thread_tbl->start_args.linuxtype = ODPTHREAD_NOT_STARTED;
> -             return -1;
> -     }
> -
> -     /* Parent continues to fork */
> -     if (pid > 0) {
> -             thread_tbl->proc.pid  = pid;
> -             return 0;
> -     }
> -
> -     /* 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;
> -     }
> -
> -     odpthread_run_start_routine(&thread_tbl->start_args);
> -
> -     return 0; /* never reached */
> -}
> -
> -/*
>   * Create a single ODPthread as a linux thread
>   */
>  static int odph_linux_thread_create(odph_odpthread_t *thread_tbl,
> @@ -361,7 +117,7 @@ static int odph_linux_thread_create(odph_odpthread_t 
> *thread_tbl,
>  
>       ret = pthread_create(&thread_tbl->thread.thread_id,
>                            &thread_tbl->thread.attr,
> -                          odpthread_run_start_routine,
> +                          _odph_thread_run_start_routine,
>                            &thread_tbl->start_args);
>       if (ret != 0) {
>               ODPH_ERR("Failed to start thread on cpu #%d\n", cpu);
> @@ -405,9 +161,9 @@ int odph_odpthreads_create(odph_odpthread_t *thread_tbl,
>                                                    thr_params))
>                               break;
>                } else {
> -                     if (odph_linux_process_create(&thread_tbl[i],
> -                                                   cpu,
> -                                                   thr_params))
> +                     if (_odph_linux_process_create(&thread_tbl[i],
> +                                                    cpu,
> +                                                    thr_params))
>                               break;
>               }
>  
> @@ -677,3 +433,51 @@ int odph_parse_options(int argc, char *argv[],
>  
>       return res;
>  }
> +
> +/*
> + * Create a single ODPthread as a linux process
> + */
> +static int _odph_linux_process_create(odph_odpthread_t *thread_tbl,
> +                                   int cpu,
> +                                   const odph_odpthread_params_t *thr_params)
> +{
> +     cpu_set_t cpu_set;
> +     pid_t pid;
> +
> +     CPU_ZERO(&cpu_set);
> +     CPU_SET(cpu, &cpu_set);
> +
> +     thread_tbl->start_args.thr_params    = *thr_params; /* copy */
> +     thread_tbl->start_args.linuxtype     = ODPTHREAD_PROCESS;
> +     thread_tbl->cpu = cpu;
> +
> +     pid = fork();
> +     if (pid < 0) {
> +             ODPH_ERR("fork() failed\n");
> +             thread_tbl->start_args.linuxtype = ODPTHREAD_NOT_STARTED;
> +             return -1;
> +     }
> +
> +     /* Parent continues to fork */
> +     if (pid > 0) {
> +             thread_tbl->proc.pid  = pid;
> +             return 0;
> +     }
> +
> +     /* 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;
> +     }
> +
> +     _odph_thread_run_start_routine(&thread_tbl->start_args);
> +
> +     return 0; /* never reached */
> +}
> diff --git a/pkgconfig/libodphelper-linux.pc.in 
> b/pkgconfig/libodphelper-linux-generic.pc.in
> similarity index 72%
> rename from pkgconfig/libodphelper-linux.pc.in
> rename to pkgconfig/libodphelper-linux-generic.pc.in
> index 3987f4c..cab7be2 100644
> --- a/pkgconfig/libodphelper-linux.pc.in
> +++ b/pkgconfig/libodphelper-linux-generic.pc.in
> @@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@
>  libdir=@libdir@
>  includedir=@includedir@
>  
> -Name: libodphelper-linux
> +Name: libodphelper-linux-generic
>  Description: Helper for the ODP packet processing engine
>  Version: @PKGCONFIG_VERSION@
> -Libs: -L${libdir} -lodphelper-linux
> +Libs: -L${libdir} -lodphelper-linux-generic
>  Libs.private:
>  Cflags: -I${includedir}
> diff --git a/test/Makefile.inc b/test/Makefile.inc
> index 1ebc047..243a616 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-linux.la $(LIB)/libodp-linux.la
> +LDADD = $(PRE_LDADD) $(LIB)/libodphelper-@[email protected] 
> $(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 ffba620..a0afd26 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-linux.la $(LIB)/libodp-linux.la
> +LIBODP = $(LIB)/libodphelper-@[email protected] $(LIB)/libodp-linux.la
> diff --git a/test/linux-generic/Makefile.inc b/test/linux-generic/Makefile.inc
> index 36745fe..2a49076 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-linux.la $(LIB)/libodp-linux.la
> +LIBODP = $(LIB)/libodphelper-@[email protected] $(LIB)/libodp-linux.la
>  
>  INCCUNIT_COMMON = -I$(top_srcdir)/test/common_plat/common
>  INCODP =  \
> -- 
> 2.9.3
> 

Reply via email to