123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #ifndef PUBSUB_H
- #define PUBSUB_H
- #ifdef __LINKER__
- /* For the linker ... */
- #define __pubsub_start_sym(event) __pubsub_##event##_start
- #define __pubsub_end_sym(event) __pubsub_##event##_end
- #define __pubsub_section(event) .__pubsub_##event
- /*
- * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler
- * contexts. In linker context, this collects pubsub sections for each event,
- * placing guard symbols around each.
- */
- #if defined(USE_ARM_LINK)
- #define REGISTER_PUBSUB_EVENT(event) \
- __pubsub_start_sym(event) +0 FIXED \
- { \
- *(__pubsub_section(event)) \
- } \
- __pubsub_end_sym(event) +0 FIXED EMPTY 0 \
- { \
- /* placeholder */ \
- }
- #else
- #define REGISTER_PUBSUB_EVENT(event) \
- __pubsub_start_sym(event) = .; \
- KEEP(*(__pubsub_section(event))); \
- __pubsub_end_sym(event) = .
- #endif
- #else /* __LINKER__ */
- /* For the compiler ... */
- #include <assert.h>
- #include <cdefs.h>
- #include <stddef.h>
- #include <arch_helpers.h>
- #if defined(USE_ARM_LINK)
- #define __pubsub_start_sym(event) Load$$__pubsub_##event##_start$$Base
- #define __pubsub_end_sym(event) Load$$__pubsub_##event##_end$$Base
- #else
- #define __pubsub_start_sym(event) __pubsub_##event##_start
- #define __pubsub_end_sym(event) __pubsub_##event##_end
- #endif
- #define __pubsub_section(event) __section(".__pubsub_" #event)
- /*
- * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols
- * exported by the linker required for the other pubsub macros to work.
- */
- #define REGISTER_PUBSUB_EVENT(event) \
- extern pubsub_cb_t __pubsub_start_sym(event)[]; \
- extern pubsub_cb_t __pubsub_end_sym(event)[]
- /*
- * Have the function func called back when the specified event happens. This
- * macro places the function address into the pubsub section, which is picked up
- * and invoked by the invoke_pubsubs() function via the PUBLISH_EVENT* macros.
- *
- * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
- */
- #define SUBSCRIBE_TO_EVENT(event, func) \
- extern pubsub_cb_t __cb_func_##func##event __pubsub_section(event); \
- pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = (func)
- /*
- * Iterate over subscribed handlers for a defined event. 'event' is the name of
- * the event, and 'subscriber' a local variable of type 'pubsub_cb_t *'.
- */
- #define for_each_subscriber(event, subscriber) \
- for (subscriber = __pubsub_start_sym(event); \
- subscriber < __pubsub_end_sym(event); \
- subscriber++)
- /*
- * Publish a defined event supplying an argument. All subscribed handlers are
- * invoked, but the return value of handlers are ignored for now.
- */
- #define PUBLISH_EVENT_ARG(event, arg) \
- do { \
- pubsub_cb_t *subscriber; \
- for_each_subscriber(event, subscriber) { \
- (*subscriber)(arg); \
- } \
- } while (0)
- /* Publish a defined event with NULL argument */
- #define PUBLISH_EVENT(event) PUBLISH_EVENT_ARG(event, NULL)
- /* Subscriber callback type */
- typedef void* (*pubsub_cb_t)(const void *arg);
- #endif /* __LINKER__ */
- #endif /* PUBSUB_H */
|