From e1401d2384c122975ed2d53266f561c4c1e96eac Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Tue, 16 Dec 2025 15:59:55 -0300 Subject: [PATCH] apps/testing: Add pthread_mutex_perf created by Anchao During the discussion about the impact of adding counter to TCB Mr anchao created a pthread mutex performance example: https://github.com/apache/nuttx/pull/17468#issuecomment-3660925314 Because this example can exercise (not ideally) the pthread mutex I decided to add it to apps/testing/sched, the program name will be called "pmutexp" (because "pmp" is not a good name). Signed-off-by: Alan C. Assis --- .../sched/pthread_mutex_perf/CMakeLists.txt | 41 +++++ testing/sched/pthread_mutex_perf/Kconfig | 30 ++++ testing/sched/pthread_mutex_perf/Make.defs | 25 +++ testing/sched/pthread_mutex_perf/Makefile | 32 ++++ .../pthread_mutex_perf/pthread_mutex_perf.c | 145 ++++++++++++++++++ 5 files changed, 273 insertions(+) create mode 100644 testing/sched/pthread_mutex_perf/CMakeLists.txt create mode 100644 testing/sched/pthread_mutex_perf/Kconfig create mode 100644 testing/sched/pthread_mutex_perf/Make.defs create mode 100644 testing/sched/pthread_mutex_perf/Makefile create mode 100644 testing/sched/pthread_mutex_perf/pthread_mutex_perf.c diff --git a/testing/sched/pthread_mutex_perf/CMakeLists.txt b/testing/sched/pthread_mutex_perf/CMakeLists.txt new file mode 100644 index 00000000000..a7ac6ad92ba --- /dev/null +++ b/testing/sched/pthread_mutex_perf/CMakeLists.txt @@ -0,0 +1,41 @@ +# ############################################################################## +# apps/testing/sched/pthread_mutex_perf/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_TESTING_PTHREAD_MUTEX_PERF) + + set(SRCS pthread_mutex_perf.c) + + nuttx_add_application( + NAME + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_PROGNMAE} + PRIORITY + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_STACKSIZE} + MODULE + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF} + COMPILE_FLAGS + ${FLAGS} + SRCS + ${SRCS}) + +endif() diff --git a/testing/sched/pthread_mutex_perf/Kconfig b/testing/sched/pthread_mutex_perf/Kconfig new file mode 100644 index 00000000000..d8f188880ea --- /dev/null +++ b/testing/sched/pthread_mutex_perf/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_PTHREAD_MUTEX_PERF + bool "Pthread Mutex Performance (pmutexp) testing" + default n + ---help--- + Pthread Mutex Performance (pmp) helps to analyze the pthread + mutex performance, by calling the function many times. + +if TESTING_PTHREAD_MUTEX_PERF + +config TESTING_PTHREAD_MUTEX_PERF_PROGNAME + string "Program name" + default "pmutexp" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config TESTING_PTHREAD_MUTEX_PERF_PRIORITY + int "Priority of pmutexp process" + default 100 + +config TESTING_PTHREAD_MUTEX_PERF_STACKSIZE + int "Stack size of pmutexp process" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/testing/sched/pthread_mutex_perf/Make.defs b/testing/sched/pthread_mutex_perf/Make.defs new file mode 100644 index 00000000000..7242f204390 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/testing/sched/pthread_mutex_perf/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_PTHREAD_MUTEX_PERF),) +CONFIGURED_APPS += $(APPDIR)/testing/sched/pthread_mutex_perf +endif diff --git a/testing/sched/pthread_mutex_perf/Makefile b/testing/sched/pthread_mutex_perf/Makefile new file mode 100644 index 00000000000..8b9b114a08a --- /dev/null +++ b/testing/sched/pthread_mutex_perf/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/testing/sched/pthread_mutex_perf/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PROGNAME = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_PROGNAME) +PRIORITY = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_STACKSIZE) +MODULE = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF) + +MAINSRC = pthread_mutex_perf.c + +include $(APPDIR)/Application.mk diff --git a/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c new file mode 100644 index 00000000000..f958f0fcb30 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * apps/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +static void timespec_diff(const struct timespec *start, + const struct timespec *end, + struct timespec *diff) +{ + diff->tv_sec = end->tv_sec - start->tv_sec; + diff->tv_nsec = end->tv_nsec - start->tv_nsec; + + if (diff->tv_nsec < 0) + { + diff->tv_sec--; + diff->tv_nsec += 1000000000; + } +} + +static void timespec_add(struct timespec *total, const struct timespec *diff) +{ + total->tv_sec += diff->tv_sec; + total->tv_nsec += diff->tv_nsec; + + if (total->tv_nsec >= 1000000000) + { + total->tv_sec += total->tv_nsec / 1000000000; + total->tv_nsec = total->tv_nsec % 1000000000; + } +} + +static void timespec_avg(const struct timespec *total, int count, + struct timespec *avg) +{ + uint64_t total_ns = (uint64_t)total->tv_sec * 1000000000 + total->tv_nsec; + uint64_t avg_ns = total_ns / count; + + avg->tv_sec = avg_ns / 1000000000; + avg->tv_nsec = avg_ns % 1000000000; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * pmp_main + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + struct timespec start; + struct timespec end; + struct timespec diff; + struct timespec total = { + 0, 0 + }; + + struct timespec avg; + int i; + int j = 0; + const int loop_count = 10; + + while (j < loop_count) + { + i = 0; + j++; + + /* Get the starting time */ + + clock_gettime(CLOCK_BOOTTIME, &start); + + /* Do 1 million interactions trying to lock an already locked mutex */ + + pthread_mutex_lock(&g_mutex); + + while (i < 1000 * 1000) + { + i++; + pthread_mutex_trylock(&g_mutex); + } + + pthread_mutex_unlock(&g_mutex); + + /* Get the finished time */ + + clock_gettime(CLOCK_BOOTTIME, &end); + + /* Get the calculated elapsed time */ + + timespec_diff(&start, &end, &diff); + + /* Add it to total time for each loop pass */ + + timespec_add(&total, &diff); + + /* Get the average time */ + + timespec_avg(&total, j, &avg); + + printf("%d: diff = %lu.%09lu s | avg = %lu.%09lu s\n", j, + (unsigned long)diff.tv_sec, (unsigned long)diff.tv_nsec, + (unsigned long)avg.tv_sec, (unsigned long)avg.tv_nsec); + } + + printf("\n===== result =====\n"); + printf("count: %d\n", loop_count); + printf("total: %lu.%09lu s\n", (unsigned long)total.tv_sec, + (unsigned long)total.tv_nsec); + printf("avg: %lu.%09lu s\n", (unsigned long)avg.tv_sec, + (unsigned long)avg.tv_nsec); + + return 0; +}