From eac7ebe476d07e6a2eccf5e050c536e393157569 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Wed, 4 Dec 2019 11:50:46 +0000 Subject: [PATCH] Merged in masayuki2009/nuttx.apps/getprime (pull request #207) apps/testing/getprime: Add getprime program to check multi-thread performance Signed-off-by: Masayuki Ishikawa Approved-by: Gregory Nutt --- testing/getprime/.gitignore | 11 ++ testing/getprime/Kconfig | 30 +++++ testing/getprime/Make.defs | 39 ++++++ testing/getprime/Makefile | 49 ++++++++ testing/getprime/getprime_main.c | 203 +++++++++++++++++++++++++++++++ 5 files changed, 332 insertions(+) create mode 100644 testing/getprime/.gitignore create mode 100644 testing/getprime/Kconfig create mode 100644 testing/getprime/Make.defs create mode 100644 testing/getprime/Makefile create mode 100644 testing/getprime/getprime_main.c diff --git a/testing/getprime/.gitignore b/testing/getprime/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/testing/getprime/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/testing/getprime/Kconfig b/testing/getprime/Kconfig new file mode 100644 index 000000000..d59fd80a7 --- /dev/null +++ b/testing/getprime/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_GETPRIME + tristate "getprime example" + default n + ---help--- + Enable the getprime example. This program is used to check multi + thread performance mainly for SMP (but not limited to) + +if TESTING_GETPRIME + +config TESTING_GETPRIME_PROGNAME + string "Program name" + default "getprime" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config TESTING_GETPRIME_PRIORITY + int "getprime task priority" + default 50 + +config TESTING_GETPRIME_STACKSIZE + int "getprime stack size" + default 1024 + +endif diff --git a/testing/getprime/Make.defs b/testing/getprime/Make.defs new file mode 100644 index 000000000..4baf7c2e5 --- /dev/null +++ b/testing/getprime/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/testing/getprime/Make.defs +# Adds selected applications to apps/ build +# +# Copyright 2019 Sony Home Entertainment & Sound Products Inc. +# Author: Masayuki Ishikawa +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_GETPRIME),) +CONFIGURED_APPS += $(APPDIR)/testing/getprime +endif diff --git a/testing/getprime/Makefile b/testing/getprime/Makefile new file mode 100644 index 000000000..5af27009e --- /dev/null +++ b/testing/getprime/Makefile @@ -0,0 +1,49 @@ +############################################################################ +# apps/testing/getprime/Makefile +# +# Copyright 2019 Sony Home Entertainment & Sound Products Inc. +# Author: Masayuki Ishikawa +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +# getprime built-in application info + +PROGNAME = $(CONFIG_TESTING_GETPRIME_PROGNAME) +PRIORITY = $(CONFIG_TESTING_GETPRIME_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_GETPRIME_STACKSIZE) +MODULE = $(CONFIG_TESTING_GETPRIME) + +# getprime main source + +MAINSRC = getprime_main.c + +include $(APPDIR)/Application.mk diff --git a/testing/getprime/getprime_main.c b/testing/getprime/getprime_main.c new file mode 100644 index 000000000..909e25ab4 --- /dev/null +++ b/testing/getprime/getprime_main.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * apps/testing/getprime_main.c + * + * Copyright 2019 Sony Home Entertainment & Sound Products Inc. + * Author: Masayuki Ishikawa + * + * Based on apps/testing/ostest/roundrobin.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PRIME_RANGE 10000 +#define PRIME_RUNS 10 +#define MAX_THREADS 8 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: get_primes + ****************************************************************************/ + +static void get_primes(int *count, int *last) +{ + int num; + int found = 0; + + *last = 0; + + for (num = 1; num < PRIME_RANGE; num++) + { + int div; + bool is_prime = true; + + for (div = 2; div <= num / 2; div++) + { + if (num % div == 0) + { + is_prime = false; + break; + } + } + + if (is_prime) + { + found++; + *last = num; + } + } + + *count = found; +} + +/**************************************************************************** + * Name: thread_func + ****************************************************************************/ + +static FAR void *thread_func(FAR void *param) +{ + int no = *(int *)param; + int count; + int last; + int i; + + printf("thread #%d started, looking for primes < %d, doing %d run(s)\n", + no, PRIME_RANGE, PRIME_RUNS); + + for (i = 0; i < PRIME_RUNS; i++) + { + get_primes(&count, &last); + } + + printf("thread #%d finished, found %d primes, last one was %d\n", + no, count, last); + + pthread_exit(NULL); + return NULL; /* To keep some compilers happy */ +} + +/**************************************************************************** + * Name: get_prime_in_parallel + ****************************************************************************/ + +static void get_prime_in_parallel(int n) +{ + pthread_t thread[MAX_THREADS]; + struct sched_param sparam; + pthread_attr_t attr; + pthread_addr_t result; + int status; + int i; + + status = pthread_attr_init(&attr); + ASSERT(status == OK); + + sparam.sched_priority = sched_get_priority_min(SCHED_FIFO); + status = pthread_attr_setschedparam(&attr, &sparam); + ASSERT(status == OK); + + printf("Set thread priority to %d\n", sparam.sched_priority); + + status = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + ASSERT(status == OK); + + printf("Set thread policy to SCHED_FIFO \n"); + + for (i = 0; i < n; i++) + { + printf("Start thread #%d \n", i); + status = pthread_create(&thread[i], &attr, + thread_func, (FAR void *)&i); + ASSERT(status == OK); + } + + /* Wait for finishing the last thread */ + + pthread_join(thread[n - 1], &result); + + printf("Done\n"); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * smp_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct timespec ts0; + struct timespec ts1; + uint64_t elapsed; + char *endp; + int n = 1; + + if (argc == 2) + { + n = (int)strtol(argv[1], &endp, 10); + ASSERT(argv[1] != endp); + + ASSERT(0 < n && n <= MAX_THREADS); + } + + (void)clock_gettime(CLOCK_REALTIME, &ts0); + get_prime_in_parallel(n); + (void)clock_gettime(CLOCK_REALTIME, &ts1); + + elapsed = (((uint64_t)ts1.tv_sec * NSEC_PER_SEC) + ts1.tv_nsec); + elapsed -= (((uint64_t)ts0.tv_sec * NSEC_PER_SEC) + ts0.tv_nsec); + elapsed /= NSEC_PER_MSEC; /* msec */ + + printf("%s took %ld msec \n", argv[0], elapsed); + return 0; +}