diff --git a/samples/subsys/zbus/benchmark/CMakeLists.txt b/samples/subsys/zbus/benchmark/CMakeLists.txt index e66cd1e4ace6b9c..c057dd1b70b94e4 100644 --- a/samples/subsys/zbus/benchmark/CMakeLists.txt +++ b/samples/subsys/zbus/benchmark/CMakeLists.txt @@ -4,5 +4,19 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(benchmark) -FILE(GLOB app_sources src/*.c) +set(app_sources src/benchmark.c) + +if(CONFIG_BM_LISTENERS) + list(APPEND app_sources src/lis.c) + +elseif(CONFIG_BM_SUBSCRIBERS) + list(APPEND app_sources src/sub.c) + +elseif(CONFIG_BM_MSG_SUBSCRIBERS) + list(APPEND app_sources src/msg_sub.c) + +endif() + +message(" > Benchmark files: ${app_sources}") + target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/zbus/benchmark/Kconfig b/samples/subsys/zbus/benchmark/Kconfig index 2fdeb3ff76b0b8a..52ad7d444f37be5 100644 --- a/samples/subsys/zbus/benchmark/Kconfig +++ b/samples/subsys/zbus/benchmark/Kconfig @@ -9,8 +9,25 @@ config BM_ONE_TO int "Number of consumers" default 8 -config BM_ASYNC - bool "Consuming in asynchronous mode" - default false +choice BM_OBSERVER_TYPE + bool "Observer type to be used in the benchmark" + +config BM_LISTENERS + bool "Consuming mode async" + +config BM_SUBSCRIBERS + bool "Consuming in asynchronous mode with message subscribers" + +config BM_MSG_SUBSCRIBERS + bool "Consuming in asynchronous mode with message subscribers" + select ZBUS_MSG_SUBSCRIBER + +endchoice + +config BM_FAIRPLAY + bool "Force a comparison with same actions" + help + Forces a message copy on the listeners and subscribers to behave equivalent to + message subscribers. source "Kconfig.zephyr" diff --git a/samples/subsys/zbus/benchmark/README.rst b/samples/subsys/zbus/benchmark/README.rst index 4dd146076230421..62998f7f7e02145 100644 --- a/samples/subsys/zbus/benchmark/README.rst +++ b/samples/subsys/zbus/benchmark/README.rst @@ -2,9 +2,10 @@ :name: Benchmarking :relevant-api: zbus_apis - Measure the time for sending 256KB from a producer to X consumers. + Measure the time for sending 256KB from a producer to N consumers. -This sample implements an application to measure the time for sending 256KB from the producer to the consumers. +This sample implements an application to measure the time for sending 256KB from the producer to the +consumers. Building and Running ******************** @@ -13,14 +14,16 @@ Building and Running :zephyr-app: samples/subsys/zbus/dyn_channel :host-os: unix :board: qemu_cortex_m3 - :gen-args: -DCONFIG_BM_MESSAGE_SIZE=1 -DCONFIG_BM_ONE_TO=1 -DCONFIG_BM_ASYNC=y + :gen-args: -DCONFIG_BM_MESSAGE_SIZE=512 -DCONFIG_BM_ONE_TO=1 -DCONFIG_BM_LISTENERS=y :goals: build run Notice we have the following parameters: -* **CONFIG_BM_MESSAGE_SIZE** the size of the message to be transferred (1, 2, 4, 8, 16, 32, 64, 128, or 256); -* **CONFIG_BM_ONE_TO** number of consumers to send (1, 2, 4, or 8); -* **CONFIG_BM_ASYNC** if the execution must be asynchronous or synchronous. Use y to async and n to sync; +* **CONFIG_BM_MESSAGE_SIZE** the size of the message to be transferred (2 to 4096 bytes); +* **CONFIG_BM_ONE_TO** number of consumers to send (1 up to 8 consumers); +* **CONFIG_BM_LISTENERS** Use y to perform the benchmark listeners; +* **CONFIG_BM_SUBSCRIBERS** Use y to perform the benchmark subscribers; +* **CONFIG_BM_MSG_SUBSCRIBERS** Use y to perform the benchmark message subscribers. Sample Output ============= @@ -28,13 +31,13 @@ The result would be something like: .. code-block:: console - *** Booting Zephyr OS build zephyr-v3.3.0 *** - I: Benchmark 1 to 1: Dynamic memory, SYNC transmission and message size 1 - I: Bytes sent = 262144, received = 262144 - I: Average data rate: 0.6MB/s - I: Duration: 4.72020167s + *** Booting Zephyr OS build zephyr-vX.Y.Z *** + I: Benchmark 1 to 1 using LISTENER(S) to transmit with message size: 512 bytes + I: Bytes sent = 262144, received = 262144 + I: Average data rate: 12.62MB/s + I: Duration: 0.019805908s - @4072020167 + @19805 Running the benchmark automatically diff --git a/samples/subsys/zbus/benchmark/benchmark_256KB.robot b/samples/subsys/zbus/benchmark/benchmark_256KB.robot index ef637f358f139f9..db2ab59d6a4a547 100644 --- a/samples/subsys/zbus/benchmark/benchmark_256KB.robot +++ b/samples/subsys/zbus/benchmark/benchmark_256KB.robot @@ -8,19 +8,23 @@ Suite Teardown Terminate All Processes kill=True *** Variables *** -${csv_file} zbus_dyn_benchmark_256kb.csv -${board} hifive1_revb -${serial_port} /dev/ttyACM0 +${csv_file} zbus_dyn_benchmark_256kb.csv +${board} hifive1_revb +${serial_port} /dev/ttyACM0 + *** Tasks *** Clear Old CSV File Empty Csv File ${csv_file} Zbus Benchmark - FOR ${async} IN "n" "y" - FOR ${consumers} IN 1 2 4 8 - FOR ${msg_size} IN 1 2 4 8 16 32 64 128 256 - Benchmark Report For message_size=${msg_size} one_to=${consumers} asynchronous=${async} + FOR ${obs_type} IN 0 1 2 + FOR ${consumers} IN 1 4 8 + FOR ${msg_size} IN 2 8 32 128 512 + Benchmark Report For + ... message_size=${msg_size} + ... one_to=${consumers} + ... observer_type=${obs_type} END END END @@ -54,30 +58,41 @@ Measure Results [Teardown] Delete All Ports Benchmark - [Arguments] ${message_size}=256 ${one_to}=1 ${asynchronous}=n + [Arguments] ${message_size}=256 ${one_to}=1 ${observer_type}=LISTENERS ${result} Run Process - ... west build -b ${board} -p always -- -DCONFIG_BM_MESSAGE_SIZE\=${message_size} -DCONFIG_BM_ONE_TO\=${one_to} -DCONFIG_BM_ASYNC\=${asynchronous} + ... west build -b ${board} -p always -- -DCONFIG_BM_MESSAGE_SIZE\=${message_size} -DCONFIG_BM_ONE_TO\=${one_to} -DCONFIG_BM_${observer_type}\=y ... shell=True Should Be Equal As Integers ${result.rc} 0 ${duration} Measure Results RETURN ${duration} Benchmark Report For - [Arguments] ${message_size}=256 ${one_to}=1 ${asynchronous}=n - ${duration} Benchmark message_size=${message_size} one_to=${one_to} asynchronous=${asynchronous} + [Arguments] ${message_size}=256 ${one_to}=1 ${observer_type}=0 + + ${obs_type_str} Set Variable LISTENERS + IF ${observer_type} == 1 + ${obs_type_str} Set Variable SUBSCRIBERS + ELSE IF ${observer_type} == 2 + ${obs_type_str} Set Variable MSG_SUBSCRIBERS + END + + ${duration} Benchmark + ... message_size=${message_size} + ... one_to=${one_to} + ... observer_type=${obs_type_str} + ${ram_amount} Run Memory Report ram + ${rom_amount} Run Memory Report rom - IF ${asynchronous} == "y" - ${async_str} Set Variable ASYNC - ELSE - ${async_str} Set Variable SYNC - END + @{results} Create List - ... ${async_str} + ... ${obs_type_str} ... ${one_to} ... ${message_size} ... ${duration} ... ${ram_amount} ... ${rom_amount} + Log To Console \n${results} + Append To Csv File ${csv_file} ${results} diff --git a/samples/subsys/zbus/benchmark/prj.conf b/samples/subsys/zbus/benchmark/prj.conf index 2c2865f39185938..d79ae4dffe83704 100644 --- a/samples/subsys/zbus/benchmark/prj.conf +++ b/samples/subsys/zbus/benchmark/prj.conf @@ -1,5 +1,7 @@ CONFIG_LOG=y +CONFIG_BOOT_BANNER=n CONFIG_LOG_MODE_MINIMAL=y CONFIG_ASSERT=n CONFIG_ZBUS=y CONFIG_ZBUS_LOG_LEVEL_INF=y +CONFIG_HEAP_MEM_POOL_SIZE=1024 diff --git a/samples/subsys/zbus/benchmark/sample.yaml b/samples/subsys/zbus/benchmark/sample.yaml index b090cc9d4670e11..089d62209e23100 100644 --- a/samples/subsys/zbus/benchmark/sample.yaml +++ b/samples/subsys/zbus/benchmark/sample.yaml @@ -10,7 +10,7 @@ tests: type: multi_line ordered: true regex: - - "I: Benchmark 1 to 8: Dynamic memory, ASYNC transmission and message size 256" + - "I: Benchmark 1 to 8 using LISTENERS to transmit with message size: 256 bytes" - "I: Bytes sent = 262144, received = 262144" - "I: Average data rate: (\\d+).(\\d+)MB/s" - "I: Duration: (\\d+).(\\d+)s" @@ -18,7 +18,29 @@ tests: extra_configs: - CONFIG_BM_ONE_TO=8 - CONFIG_BM_MESSAGE_SIZE=256 - - CONFIG_BM_ASYNC=y + - CONFIG_BM_LISTENERS=y + - arch:nios2:CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 + - CONFIG_IDLE_STACK_SIZE=1024 + integration_platforms: + - qemu_x86 + sample.zbus.benchmark_async_msg_sub: + tags: zbus + min_ram: 16 + filter: CONFIG_SYS_CLOCK_EXISTS and not (CONFIG_ARCH_POSIX and not CONFIG_BOARD_NATIVE_POSIX) + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "I: Benchmark 1 to 8 using MSG_SUBSCRIBERS to transmit with message size: 256 bytes" + - "I: Bytes sent = 262144, received = 262144" + - "I: Average data rate: (\\d+).(\\d+)MB/s" + - "I: Duration: (\\d+).(\\d+)s" + - "@(.*)" + extra_configs: + - CONFIG_BM_ONE_TO=8 + - CONFIG_BM_MESSAGE_SIZE=256 + - CONFIG_BM_MSG_SUBSCRIBERS=y - arch:nios2:CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 - CONFIG_IDLE_STACK_SIZE=1024 integration_platforms: @@ -32,7 +54,7 @@ tests: type: multi_line ordered: true regex: - - "I: Benchmark 1 to 8: Dynamic memory, SYNC transmission and message size 256" + - "I: Benchmark 1 to 8 using SUBSCRIBERS to transmit with message size: 256 bytes" - "I: Bytes sent = 262144, received = 262144" - "I: Average data rate: (\\d+).(\\d+)MB/s" - "I: Duration: (\\d+).(\\d+)s" @@ -40,7 +62,7 @@ tests: extra_configs: - CONFIG_BM_ONE_TO=8 - CONFIG_BM_MESSAGE_SIZE=256 - - CONFIG_BM_ASYNC=n + - CONFIG_BM_SUBSCRIBERS=y - arch:nios2:CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 - CONFIG_IDLE_STACK_SIZE=1024 integration_platforms: diff --git a/samples/subsys/zbus/benchmark/src/benchmark.c b/samples/subsys/zbus/benchmark/src/benchmark.c index ac781a6306f96e3..267c593b4b18f16 100644 --- a/samples/subsys/zbus/benchmark/src/benchmark.c +++ b/samples/subsys/zbus/benchmark/src/benchmark.c @@ -4,8 +4,6 @@ */ #include "messages.h" -#include - #include #include #include @@ -27,183 +25,57 @@ LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL); #define CONSUMER_STACK_SIZE (CONFIG_IDLE_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE) #define PRODUCER_STACK_SIZE (CONFIG_MAIN_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE) -ZBUS_CHAN_DEFINE(bm_channel, /* Name */ +ZBUS_CHAN_DEFINE(bm_channel, /* Name */ struct bm_msg, /* Message type */ - NULL, /* Validator */ - NULL, /* User data */ - ZBUS_OBSERVERS(s1 - -#if (CONFIG_BM_ONE_TO >= 2LLU) - , - s2 -#if (CONFIG_BM_ONE_TO > 2LLU) - , - s3, s4 -#if (CONFIG_BM_ONE_TO > 4LLU) - , - s5, s6, s7, s8 -#if (CONFIG_BM_ONE_TO > 8LLU) - , - s9, s10, s11, s12, s13, s14, s15, s16 -#endif -#endif -#endif -#endif - ), /* observers */ - ZBUS_MSG_INIT(0) /* Initial value {0} */ + NULL, /* Validator */ + NULL, /* User data */ + ZBUS_OBSERVERS_EMPTY, /* observers */ + ZBUS_MSG_INIT(0) /* Initial value {0} */ ); #define BYTES_TO_BE_SENT (256LLU * 1024LLU) -static atomic_t count; - -#if (CONFIG_BM_ASYNC == 1) -ZBUS_SUBSCRIBER_DEFINE(s1, 4); -#if (CONFIG_BM_ONE_TO >= 2LLU) -ZBUS_SUBSCRIBER_DEFINE(s2, 4); -#if (CONFIG_BM_ONE_TO > 2LLU) -ZBUS_SUBSCRIBER_DEFINE(s3, 4); -ZBUS_SUBSCRIBER_DEFINE(s4, 4); -#if (CONFIG_BM_ONE_TO > 4LLU) -ZBUS_SUBSCRIBER_DEFINE(s5, 4); -ZBUS_SUBSCRIBER_DEFINE(s6, 4); -ZBUS_SUBSCRIBER_DEFINE(s7, 4); -ZBUS_SUBSCRIBER_DEFINE(s8, 4); -#if (CONFIG_BM_ONE_TO > 8LLU) -ZBUS_SUBSCRIBER_DEFINE(s9, 4); -ZBUS_SUBSCRIBER_DEFINE(s10, 4); -ZBUS_SUBSCRIBER_DEFINE(s11, 4); -ZBUS_SUBSCRIBER_DEFINE(s12, 4); -ZBUS_SUBSCRIBER_DEFINE(s13, 4); -ZBUS_SUBSCRIBER_DEFINE(s14, 4); -ZBUS_SUBSCRIBER_DEFINE(s15, 4); -ZBUS_SUBSCRIBER_DEFINE(s16, 4); -#endif -#endif -#endif -#endif - -#define S_TASK(name) \ - void name##_task(void) \ - { \ - const struct zbus_channel *chan; \ - struct bm_msg *msg_received; \ - \ - while (!zbus_sub_wait(&name, &chan, K_FOREVER)) { \ - zbus_chan_claim(chan, K_NO_WAIT); \ - \ - msg_received = zbus_chan_msg(chan); \ - \ - zbus_chan_finish(chan); \ - \ - atomic_add(&count, CONFIG_BM_MESSAGE_SIZE); \ - } \ - } \ - \ - K_THREAD_DEFINE(name##_id, CONSUMER_STACK_SIZE, name##_task, NULL, NULL, NULL, 3, 0, 0); - -S_TASK(s1) -#if (CONFIG_BM_ONE_TO >= 2LLU) -S_TASK(s2) -#if (CONFIG_BM_ONE_TO > 2LLU) -S_TASK(s3) -S_TASK(s4) -#if (CONFIG_BM_ONE_TO > 4LLU) -S_TASK(s5) -S_TASK(s6) -S_TASK(s7) -S_TASK(s8) -#if (CONFIG_BM_ONE_TO > 8LLU) -S_TASK(s9) -S_TASK(s10) -S_TASK(s11) -S_TASK(s12) -S_TASK(s13) -S_TASK(s14) -S_TASK(s15) -S_TASK(s16) -#endif -#endif -#endif -#endif - -#else /* SYNC */ - -static void s_cb(const struct zbus_channel *chan); - -ZBUS_LISTENER_DEFINE(s1, s_cb); - -#if (CONFIG_BM_ONE_TO >= 2LLU) -ZBUS_LISTENER_DEFINE(s2, s_cb); -#if (CONFIG_BM_ONE_TO > 2LLU) -ZBUS_LISTENER_DEFINE(s3, s_cb); -ZBUS_LISTENER_DEFINE(s4, s_cb); -#if (CONFIG_BM_ONE_TO > 4LLU) -ZBUS_LISTENER_DEFINE(s5, s_cb); -ZBUS_LISTENER_DEFINE(s6, s_cb); -ZBUS_LISTENER_DEFINE(s7, s_cb); -ZBUS_LISTENER_DEFINE(s8, s_cb); -#if (CONFIG_BM_ONE_TO > 8LLU) -ZBUS_LISTENER_DEFINE(s9, s_cb); -ZBUS_LISTENER_DEFINE(s10, s_cb); -ZBUS_LISTENER_DEFINE(s11, s_cb); -ZBUS_LISTENER_DEFINE(s12, s_cb); -ZBUS_LISTENER_DEFINE(s13, s_cb); -ZBUS_LISTENER_DEFINE(s14, s_cb); -ZBUS_LISTENER_DEFINE(s15, s_cb); -ZBUS_LISTENER_DEFINE(s16, s_cb); -#endif -#endif -#endif -#endif - -static void s_cb(const struct zbus_channel *chan) -{ - const struct bm_msg *actual_message_data = zbus_chan_const_msg(chan); - - /* It only illustrates the message is ready to be consumed */ - ARG_UNUSED(actual_message_data); - - count += CONFIG_BM_MESSAGE_SIZE; -} - -#endif /* CONFIG_BM_ASYNC */ +atomic_t count; static void producer_thread(void) { - LOG_INF("Benchmark 1 to %d: Dynamic memory, %sSYNC transmission and message size %u", - CONFIG_BM_ONE_TO, IS_ENABLED(CONFIG_BM_ASYNC) ? "A" : "", CONFIG_BM_MESSAGE_SIZE); + LOG_INF("Benchmark 1 to %d using %s to transmit with message size: %u bytes", + CONFIG_BM_ONE_TO, + IS_ENABLED(CONFIG_BM_LISTENERS) + ? "LISTENERS" + : (IS_ENABLED(CONFIG_BM_SUBSCRIBERS) ? "SUBSCRIBERS" : "MSG_SUBSCRIBERS"), + CONFIG_BM_MESSAGE_SIZE); - struct bm_msg msg; + struct bm_msg msg = {{0}}; - for (uint64_t i = (CONFIG_BM_MESSAGE_SIZE - 1); i > 0; --i) { - msg.bytes[i] = i; - } + uint16_t message_size = CONFIG_BM_MESSAGE_SIZE; + + memcpy(msg.bytes, &message_size, sizeof(message_size)); uint64_t start_ns = GET_ARCH_TIME_NS(); for (uint64_t internal_count = BYTES_TO_BE_SENT / CONFIG_BM_ONE_TO; internal_count > 0; internal_count -= CONFIG_BM_MESSAGE_SIZE) { - zbus_chan_pub(&bm_channel, &msg, K_MSEC(200)); + zbus_chan_pub(&bm_channel, &msg, K_FOREVER); } uint64_t end_ns = GET_ARCH_TIME_NS(); - uint64_t duration = end_ns - start_ns; + uint64_t duration_ns = end_ns - start_ns; - if (duration == 0) { + if (duration_ns == 0) { LOG_ERR("Something wrong. Duration is zero!\n"); k_oops(); } - uint64_t i = ((BYTES_TO_BE_SENT * NSEC_PER_SEC) / MB(1)) / duration; - uint64_t f = ((BYTES_TO_BE_SENT * NSEC_PER_SEC * 100) / MB(1) / duration) % 100; + uint64_t i = ((BYTES_TO_BE_SENT * NSEC_PER_SEC) / MB(1)) / duration_ns; + uint64_t f = ((BYTES_TO_BE_SENT * NSEC_PER_SEC * 100) / MB(1) / duration_ns) % 100; - LOG_INF("Bytes sent = %lld, received = %lu", BYTES_TO_BE_SENT, atomic_get(&count)); + LOG_INF("Bytes sent = %llu, received = %lu", BYTES_TO_BE_SENT, atomic_get(&count)); LOG_INF("Average data rate: %llu.%lluMB/s", i, f); - LOG_INF("Duration: %lld.%09llus", duration / NSEC_PER_SEC, duration % NSEC_PER_SEC); + LOG_INF("Duration: %llu.%09llus", duration_ns / NSEC_PER_SEC, duration_ns % NSEC_PER_SEC); - printk("\n@%llu\n", duration); + printk("\n@%llu\n", duration_ns / 1000); } -K_THREAD_DEFINE(producer_thread_id, PRODUCER_STACK_SIZE, producer_thread, NULL, NULL, NULL, 5, 0, - 0); +K_THREAD_DEFINE(producer_thread_id, PRODUCER_STACK_SIZE * 2, producer_thread, NULL, NULL, NULL, 5, + 0, 0); diff --git a/samples/subsys/zbus/benchmark/src/lis.c b/samples/subsys/zbus/benchmark/src/lis.c new file mode 100644 index 000000000000000..e589baafaf88176 --- /dev/null +++ b/samples/subsys/zbus/benchmark/src/lis.c @@ -0,0 +1,48 @@ + +/* + * Copyright (c) 2023 Rodrigo Peixoto + * SPDX-License-Identifier: Apache-2.0 + */ +#include "messages.h" + +#include +#include +#include +#include + +#define CONSUMER_STACK_SIZE (CONFIG_IDLE_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE) + +extern atomic_t count; +static void s_cb(const struct zbus_channel *chan); + +ZBUS_CHAN_DECLARE(bm_channel); + +#define SFY(i, _) s##i + +#define CONSUMERS_NAME_LIST LISTIFY(CONFIG_BM_ONE_TO, SFY, (, /* separator */)) + +#define CREATE_OBSERVER(s) ZBUS_LISTENER_DEFINE(s, s_cb) + +FOR_EACH(CREATE_OBSERVER, (;), CONSUMERS_NAME_LIST) + ; + +#define CREATE_OBSERVATIONS(s) ZBUS_CHAN_ADD_OBS(bm_channel, s, 3) + +FOR_EACH(CREATE_OBSERVATIONS, (;), CONSUMERS_NAME_LIST) + ; + +static void s_cb(const struct zbus_channel *chan) +{ + + if (IS_ENABLED(CONFIG_BM_FAIRPLAY)) { + struct bm_msg msg_received; + + memcpy(zbus_chan_msg(chan), &msg_received, chan->message_size); + + atomic_add(&count, *((uint16_t *)msg_received.bytes)); + } else { + const struct bm_msg *msg_received = zbus_chan_const_msg(chan); + + atomic_add(&count, *((uint16_t *)msg_received->bytes)); + } +} diff --git a/samples/subsys/zbus/benchmark/src/msg_sub.c b/samples/subsys/zbus/benchmark/src/msg_sub.c new file mode 100644 index 000000000000000..ea2557cf6c5ab67 --- /dev/null +++ b/samples/subsys/zbus/benchmark/src/msg_sub.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Rodrigo Peixoto + * SPDX-License-Identifier: Apache-2.0 + */ +#include "messages.h" + +#include +#include +#include +#include + +#define CONSUMER_STACK_SIZE (CONFIG_IDLE_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE) + +extern atomic_t count; + +ZBUS_CHAN_DECLARE(bm_channel); + +#define SFY(i, _) s##i + +#define CONSUMERS_NAME_LIST LISTIFY(CONFIG_BM_ONE_TO, SFY, (, /* separator */)) + +#define CREATE_OBSERVER(s) ZBUS_MSG_SUBSCRIBER_DEFINE(s) + +FOR_EACH(CREATE_OBSERVER, (;), CONSUMERS_NAME_LIST) + ; + +#define CREATE_OBSERVATIONS(s) ZBUS_CHAN_ADD_OBS(bm_channel, s, 3) + +FOR_EACH(CREATE_OBSERVATIONS, (;), CONSUMERS_NAME_LIST) + ; + +#define S_TASK(name) \ + void name##_task(void) \ + { \ + const struct zbus_channel *chan; \ + struct bm_msg msg_received; \ + \ + while (1) { \ + if (zbus_sub_wait_msg(&name, &chan, &msg_received, K_FOREVER) == 0) { \ + atomic_add(&count, *((uint16_t *)msg_received.bytes)); \ + } else { \ + k_oops(); \ + } \ + } \ + } \ + \ + K_THREAD_DEFINE(name##_id, CONSUMER_STACK_SIZE, name##_task, NULL, NULL, NULL, 3, 0, 0); + +#define CREATE_TASKS(s) S_TASK(s) +FOR_EACH(CREATE_TASKS, (;), CONSUMERS_NAME_LIST) + ; diff --git a/samples/subsys/zbus/benchmark/src/sub.c b/samples/subsys/zbus/benchmark/src/sub.c new file mode 100644 index 000000000000000..63a141bf9a30450 --- /dev/null +++ b/samples/subsys/zbus/benchmark/src/sub.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Rodrigo Peixoto + * SPDX-License-Identifier: Apache-2.0 + */ +#include "messages.h" + +#include +#include +#include +#include + +#define CONSUMER_STACK_SIZE (CONFIG_IDLE_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE) + +extern atomic_t count; + +ZBUS_CHAN_DECLARE(bm_channel); + +#define SFY(i, _) s##i + +#define CONSUMERS_NAME_LIST LISTIFY(CONFIG_BM_ONE_TO, SFY, (, /* separator */)) + +#define CREATE_OBSERVER(s) ZBUS_SUBSCRIBER_DEFINE(s, 4) + +FOR_EACH(CREATE_OBSERVER, (;), CONSUMERS_NAME_LIST) + ; + +#define CREATE_OBSERVATIONS(s) ZBUS_CHAN_ADD_OBS(bm_channel, s, 3) + +FOR_EACH(CREATE_OBSERVATIONS, (;), CONSUMERS_NAME_LIST) + ; + +#define S_TASK(name) \ + void name##_task(void) \ + { \ + const struct zbus_channel *chan; \ + \ + while (1) { \ + if (zbus_sub_wait(&name, &chan, K_FOREVER) == 0) { \ + if (zbus_chan_claim(chan, K_FOREVER) != 0) { \ + k_oops(); \ + } \ + if (IS_ENABLED(CONFIG_BM_FAIRPLAY)) { \ + struct bm_msg message; \ + \ + memcpy(zbus_chan_msg(chan), &message, chan->message_size); \ + \ + atomic_add(&count, *((uint16_t *)message.bytes)); \ + } else { \ + const struct bm_msg *msg_received = \ + zbus_chan_const_msg(chan); \ + \ + atomic_add(&count, *((uint16_t *)msg_received->bytes)); \ + } \ + zbus_chan_finish(chan); \ + } else { \ + k_oops(); \ + } \ + } \ + } \ + \ + K_THREAD_DEFINE(name##_id, CONSUMER_STACK_SIZE, name##_task, NULL, NULL, NULL, 3, 0, 0); + +#define CREATE_TASKS(s) S_TASK(s) +FOR_EACH(CREATE_TASKS, (;), CONSUMERS_NAME_LIST) + ;