On Mon, Aug 18, 2014 at 08:41:00AM +0100, Santosh Shukla wrote:
> Test application to run odp dummy dp thread
> on no_hz_full kernel mode for few seconds.
>
> - Create 2 threads, running in loop for few seconds.
> - Mask timer thread.
>
> Signed-off-by: Santosh Shukla <[email protected]>
> ---
> Note :
> - Patch set based on Maxim's v2 patch under discussion
> "implement-odp_init_global-init-mask.patch"
> - Open for review feedback however wont merge due
> above dependancy.
> - More isolation specific changes seen at
> https://git.linaro.org/people/santosh.shukla/odp.git
>
> configure.ac | 1 +
> example/Makefile.am | 2 +-
> example/isolation/Makefile.am | 5 +
> example/isolation/odp_isolation.c | 232
> +++++++++++++++++++++++++++++++++++++
> 4 files changed, 239 insertions(+), 1 deletion(-)
> create mode 100644 example/isolation/Makefile.am
> create mode 100644 example/isolation/odp_isolation.c
>
> diff --git a/configure.ac b/configure.ac
> index 74713a7..2b6758b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -142,6 +142,7 @@ AC_CONFIG_FILES([Makefile
> example/packet/Makefile
> example/packet_netmap/Makefile
> example/timer/Makefile
> + example/isolation/Makefile
> test/Makefile
> test/api_test/Makefile
> pkgconfig/libodp.pc])
> diff --git a/example/Makefile.am b/example/Makefile.am
> index 01a3305..4cb4a23 100644
> --- a/example/Makefile.am
> +++ b/example/Makefile.am
> @@ -1 +1 @@
> -SUBDIRS = generator l2fwd odp_example packet packet_netmap timer
> +SUBDIRS = generator l2fwd odp_example packet packet_netmap timer isolation
> diff --git a/example/isolation/Makefile.am b/example/isolation/Makefile.am
> new file mode 100644
> index 0000000..7e39773
> --- /dev/null
> +++ b/example/isolation/Makefile.am
> @@ -0,0 +1,5 @@
> +include $(top_srcdir)/example/Makefile.inc
> +
> +bin_PROGRAMS = odp_isolation
> +
> +dist_odp_isolation_SOURCES = odp_isolation.c
> diff --git a/example/isolation/odp_isolation.c
> b/example/isolation/odp_isolation.c
> new file mode 100644
> index 0000000..8d8fffc
> --- /dev/null
> +++ b/example/isolation/odp_isolation.c
> @@ -0,0 +1,232 @@
> +/* Copyright (c) 2013, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier: BSD-3-Clause
> + */
> +
> +/**
> + * @file
> + *
> + * @example odp_isol_test.c ODP isolation example application
> + */
> +
> +#include <string.h>
> +#include <stdlib.h>
> +
> +/* ODP main header */
> +#include <odp.h>
> +
> +/* ODP helper for Linux apps */
> +#include <helper/odp_linux.h>
> +
> +/* GNU lib C */
> +#include <getopt.h>
> +
> +#define MAX_WORKERS 32 /**< Max worker threads */
> +
> +/**
> + * Parsed command line application arguments
> + */
> +typedef struct {
> + int core_count; /**< Core count*/
> + char **core_name; /**< Array of pointers to core name */
> +} appl_args_t;
> +
> +/**
> + * @internal Print help
> + */
> +static void print_usage(void)
> +{
> + printf("\n\nUsage: ./odp_isolation [options]\n");
> + printf("Options:\n");
> + printf(" -l, --cpulist <cpu number in comma separated fashion>\n");
> + printf(" -h, --help this help\n");
> + printf("\n\n");
> +}
> +
> +/**
> + * @internal Worker thread
> + *
> + * @param arg Arguments
> + *
> + * @return NULL on failure
> + */
> +static void *run_thread(void *arg)
> +{
> + int thr;
> + unsigned long long tick = 0;
> + int counter = 0;
> +
> + thr = odp_thread_id();
> +
> + printf("Thread %i starts on core %i\n", thr, odp_thread_core());
> +
> + /* loop for some duration then exit */
> + do {
> + tick++;
> +
> + if (tick > 10000000) {
> +
> + tick = 0;
> + counter++;
> + }
> +
> + if (counter == 1000)
> + break;
> + } while (1);
> +
> + return arg;
> +}
I'm not sure it's worth adding an example application that does nothing.
Isolation is not be something the application needs explicit knowledge
of so having an example app demonstrating it is a bit odd. All of the
existing examples / tests should be capable of being run isolated.
For this test you could start with odp_example as it has no dependencies
and will exit after some time - if you need it to run for a particular
amount of time you could add an argument for that.
> +
> +/**
> + * @internal Parse arguments
> + *
> + * @param argc Argument count
> + * @param argv Argument vector
> + * @param args Test arguments
> + */
> +static void parse_args(int argc, char *argv[], appl_args_t *args)
> +{
> + int opt;
> + int long_index;
> + char *names, *str, *token, *save;
> + size_t len;
> + int i;
> +
> + static struct option longopts[] = {
> + {"cpulists", required_argument, NULL, 'l'}, /* return 'l' */
> + {"help", no_argument, NULL, 'h'}, /* return 'h' */
> + {NULL, 0, NULL, 0}
> + };
> +
> + while (1) {
> + opt = getopt_long(argc, argv, "+l:h", longopts, &long_index);
> +
> + if (opt == -1)
> + break; /* No more options */
> +
> + switch (opt) {
> + case 'l':
> + len = strlen(optarg);
> + if (len == 0) {
> + print_usage();
> + exit(EXIT_FAILURE);
> + }
> + len += 1; /* add room for '\0' */
> +
> + names = malloc(len);
> + if (names == NULL) {
> + print_usage();
> + exit(EXIT_FAILURE);
> + }
> +
> + /* count the number of tokens separated by ',' */
> + strcpy(names, optarg);
> + for (str = names, i = 0;; str = NULL, i++) {
> + token = strtok_r(str, ",", &save);
> + if (token == NULL)
> + break;
> + }
> + args->core_count = i;
> +
> + if (args->core_count == 0) {
> + print_usage();
> + exit(EXIT_FAILURE);
> + }
> + /* allocate storage for the if names */
> + args->core_name =
> + calloc(args->core_count, sizeof(char *));
> +
> + /* store the if names (reset names string) */
> + strcpy(names, optarg);
> + for (str = names, i = 0;; str = NULL, i++) {
> + token = strtok_r(str, ",", &save);
> + if (token == NULL)
> + break;
> + args->core_name[i] = token;
> + }
> + break;
> +
It would be better to change the behaviour of the existing -c
argument used in most of the examples from being a core count to
something similar to what you've done with -l here. Other related
applications (taskset [1], DPDK [2]) use -c to provide either a core
mask or a list.
[1] http://linux.die.net/man/1/taskset
[2] http://www.dpdk.info/ml/archives/dev/2014-April/002173.html
> + case 'h':
> + print_usage();
> + exit(EXIT_SUCCESS);
> + break;
> +
> + default:
> + break;
> + }
> + }
> +}
> +
> +/**
> + * Isolation test application
> + */
> +int main(int argc, char *argv[])
> +{
> + odp_linux_pthread_t thread_tbl[MAX_WORKERS];
> + appl_args_t args;
> + int thr_id;
> + int num_workers;
> + int first_core;
> + int i;
> +
> + printf("\nODP isolation test application\n");
> +
> + memset(&args, 0, sizeof(args));
> + parse_args(argc, argv, &args);
> +
> + memset(thread_tbl, 0, sizeof(thread_tbl));
> +
> + /*
> + * Don't need timer init for isolation, so mask them.
> + */
> + if (odp_init_global(ODP_INIT_F_ALL & ~ODP_INIT_F_TIMER)) {
> + printf("ODP global init failed.\n");
> + return -1;
> + }
> +
> + printf("\n");
> + printf("ODP system info\n");
> + printf("---------------\n");
> + printf("ODP API version: %s\n", odp_version_api_str());
> + printf("CPU model: %s\n", odp_sys_cpu_model_str());
> + printf("CPU freq (hz): %"PRIu64"\n", odp_sys_cpu_hz());
> + printf("Cache line size: %i\n", odp_sys_cache_line_size());
> + printf("Max core count: %i\n", odp_sys_core_count());
> +
> + printf("\n");
> +
> + /* A worker thread per core */
> + num_workers = odp_sys_core_count();
> +
> + if (args.core_count)
> + num_workers = args.core_count;
> +
> + /* force to max core count */
> + if (num_workers > MAX_WORKERS)
> + num_workers = MAX_WORKERS;
> +
> + printf("num worker threads: %i\n", num_workers);
> +
> + /*
> + * Init this thread.
> + * */
> + thr_id = odp_thread_create(0);
> + odp_init_local(thr_id);
> +
> + for (i=0; i<num_workers; i++) {
> +
> + first_core = atoi(args.core_name[i]);
> + /* Create and launch worker threads */
> + odp_linux_pthread_create(&thread_tbl[i], 1, first_core,
> + run_thread, NULL);
> + }
> +
I wonder if changing odp_linux_pthread_create to take an array of cores
rather than just the first core is a better way to go. A quick grep
through the existing examples / tests shows almost all callers provide 1
for the number of cores, so it's not currently being used as expected.
--
Stuart.
_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp