blob: eb91286564c7c516de851fa9728d4a6b53c37e1a [file] [log] [blame]
Jeenu Viswambharane3f22002017-09-22 08:32:10 +01001/*
Roberto Vargas05712702018-02-12 12:36:17 +00002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Jeenu Viswambharane3f22002017-09-22 08:32:10 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00007#ifndef PUBSUB_H
8#define PUBSUB_H
Jeenu Viswambharane3f22002017-09-22 08:32:10 +01009
10#define __pubsub_start_sym(event) __pubsub_##event##_start
11#define __pubsub_end_sym(event) __pubsub_##event##_end
12
13#ifdef __LINKER__
14
15/* For the linker ... */
16
17#define __pubsub_section(event) __pubsub_##event
18
19/*
20 * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler
21 * contexts. In linker context, this collects pubsub sections for each event,
22 * placing guard symbols around each.
23 */
24#define REGISTER_PUBSUB_EVENT(event) \
25 __pubsub_start_sym(event) = .; \
26 KEEP(*(__pubsub_section(event))); \
27 __pubsub_end_sym(event) = .
28
29#else /* __LINKER__ */
30
31/* For the compiler ... */
32
Jeenu Viswambharane3f22002017-09-22 08:32:10 +010033#include <assert.h>
34#include <cdefs.h>
35#include <stddef.h>
36
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000037#include <arch_helpers.h>
38
Jeenu Viswambharane3f22002017-09-22 08:32:10 +010039#define __pubsub_section(event) __section("__pubsub_" #event)
40
41/*
42 * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols
43 * exported by the linker required for the other pubsub macros to work.
44 */
45#define REGISTER_PUBSUB_EVENT(event) \
46 extern pubsub_cb_t __pubsub_start_sym(event)[]; \
47 extern pubsub_cb_t __pubsub_end_sym(event)[]
48
49/*
50 * Have the function func called back when the specified event happens. This
51 * macro places the function address into the pubsub section, which is picked up
52 * and invoked by the invoke_pubsubs() function via. the PUBLISH_EVENT* macros.
Roberto Vargas05712702018-02-12 12:36:17 +000053 *
54 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Jeenu Viswambharane3f22002017-09-22 08:32:10 +010055 */
56#define SUBSCRIBE_TO_EVENT(event, func) \
Roberto Vargas05712702018-02-12 12:36:17 +000057 extern pubsub_cb_t __cb_func_##func##event __pubsub_section(event); \
58 pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = (func)
Jeenu Viswambharane3f22002017-09-22 08:32:10 +010059
60/*
61 * Iterate over subscribed handlers for a defined event. 'event' is the name of
62 * the event, and 'subscriber' a local variable of type 'pubsub_cb_t *'.
63 */
64#define for_each_subscriber(event, subscriber) \
65 for (subscriber = __pubsub_start_sym(event); \
66 subscriber < __pubsub_end_sym(event); \
67 subscriber++)
68
69/*
70 * Publish a defined event supplying an argument. All subscribed handlers are
71 * invoked, but the return value of handlers are ignored for now.
72 */
73#define PUBLISH_EVENT_ARG(event, arg) \
74 do { \
75 pubsub_cb_t *subscriber; \
76 for_each_subscriber(event, subscriber) { \
77 (*subscriber)(arg); \
78 } \
79 } while (0)
80
81/* Publish a defined event with NULL argument */
82#define PUBLISH_EVENT(event) PUBLISH_EVENT_ARG(event, NULL)
83
84/* Subscriber callback type */
85typedef void* (*pubsub_cb_t)(const void *arg);
86
87#endif /* __LINKER__ */
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +000088#endif /* PUBSUB_H */