Project
Loading...
Searching...
No Matches
x9.h
Go to the documentation of this file.
1/*
2 X9 - high performance message passing library.
3 Copyright (c) 2023, Diogo Flores
4
5 BSD 2-Clause License (https://opensource.org/license/bsd-2-clause/)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 * Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following disclaimer
15 in the documentation and/or other materials provided with the
16 distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 You can contact the author at: diogoxflores@gmail.com
31*/
32
33#ifndef O2_FRAMEWORK_FOUDATION_X9_H_
34#define O2_FRAMEWORK_FOUDATION_X9_H_
35
36#ifdef __cplusplus
37extern "C" {
38#define restrict __restrict__
39#endif
40
41#include <stdbool.h> /* bool */
42#include <stdint.h> /* uint64_t */
43
44/* --- Opaque types --- */
45
46typedef struct x9_node_internal x9_node;
47typedef struct x9_inbox_internal x9_inbox;
48
49/* --- Public API --- */
50
51/* Creates a x9_inbox with a buffer of size 'sz', which must be positive and
52 * mod 2 == 0, a 'name', which can be used for comparison by calling
53 * 'x9_inbox_name_is' or for selecting a specific x9_inbox from a x9_node by
54 * calling 'x9_select_inbox_from_node', and a 'msg_sz' which the inbox is
55 * expected to receive.
56 *
57 * Example:
58 * x9_inbox* inbox = x9_create_inbox(512, "ibx", sizeof(<some struct>));*/
59__attribute__((nonnull)) x9_inbox* x9_create_inbox(
60 uint64_t const sz, char const* restrict const name, uint64_t const msg_sz);
61
62/* Variadic function that creates a 'x9_node', which is an abstraction that
63 * unifies x9_inbox(es).
64 * 'name' can be used for comparison by calling 'x9_node_name_is',
65 * 'n_inboxes' must be > 0 and equal the number of inboxes passed to the
66 * function to be attached to the x9_node.
67 *
68 * Example:
69 * x9_node* node = x9_create_node("my_node", 3, inbox_1, inbox_2, inbox_3);*/
70__attribute__((nonnull)) x9_node* x9_create_node(char* restrict const name,
71 uint64_t const n_inboxes,
72 ...);
73
74/* Returns 'true' if the 'inbox' is valid, 'false' otherwise.
75 * Should always be called after 'x9_create_inbox' to validate the correct
76 * initialization of the underlying data structure, and after calling
77 * 'x9_select_inbox_from_node' to ensure that the user selected a valid inbox.
78 * If the return value is 'false', and it's unclear why it is so, the user can
79 * enable the 'X9_DEBUG' macro at compile time for precise error information.*/
80bool x9_inbox_is_valid(x9_inbox const* const inbox);
81
82/* Returns 'true' if the 'node' is valid, 'false' otherwise.
83 * Should always be called after 'x9_create_node' to validate the correct
84 * initialization of the underlying data structure.
85 * If the return value is 'false', and it's unclear why it is so, the user can
86 * enable the 'X9_DEBUG' macro at compile time for precise error information.*/
87bool x9_node_is_valid(x9_node const* const node);
88
89/* Selects a x9_inbox from a 'node' by its 'name'.
90 * Returns NULL if the 'node' does not contain an x9_inbox with such 'name'.*/
91__attribute__((nonnull)) x9_inbox* x9_select_inbox_from_node(
92 x9_node const* const node, char const* restrict const name);
93
94/* Returns 'true' if the 'inbox' name == 'cmp', 'false' otherwise.*/
95__attribute__((nonnull)) bool x9_inbox_name_is(x9_inbox const* const inbox,
96 char const* restrict const cmp);
97
98/* Returns 'true' if the 'node' name == 'cmp', 'false' otherwise.*/
99__attribute__((nonnull)) bool x9_node_name_is(x9_node const* const node,
100 char const* restrict const cmp);
101
102/* Frees the 'inbox' data structure and its internal components. */
103__attribute__((nonnull)) void x9_free_inbox(x9_inbox* const inbox);
104
105/* Frees the 'node' data structure and its internal components. */
106__attribute__((nonnull)) void x9_free_node(x9_node* const node);
107
108/* Frees the 'node' and all the x9_inbox(es) attached to it.
109 * IMPORTANT: should only be used when the attached x9_inbox(es) are not shared
110 * with other nodes.*/
111__attribute__((nonnull)) void x9_free_node_and_attached_inboxes(
112 x9_node* const node);
113
114/* Returns 'true' if a message was read, 'false' otherwise.
115 * If 'true', the message will be written to 'outparam'.
116 * IMPORTANT: Can only be used to read from inboxes where the thread calling
117 * this function is the only thread reading from said 'inbox'.*/
118__attribute__((nonnull)) bool x9_read_from_inbox(
119 x9_inbox* const inbox,
120 uint64_t const msg_sz,
121 void* restrict const outparam);
122
123/* Reads the next unread message in the 'inbox' to 'outparam'.
124 * Uses spinning, that is, it wil not return until it has read a message, and
125 * it will keep checking if a message was written and try to read it. */
126__attribute__((nonnull)) void x9_read_from_inbox_spin(
127 x9_inbox* const inbox,
128 uint64_t const msg_sz,
129 void* restrict const outparam);
130
131/* Returns 'true' if a message was read, 'false' otherwise.
132 * If 'true', the msg contents will be written to the 'outparam'.
133 * Use this function when multiple threads read from the same inbox. */
134__attribute__((nonnull)) bool x9_read_from_shared_inbox(
135 x9_inbox* const inbox,
136 uint64_t const msg_sz,
137 void* restrict const outparam);
138
139/* Reads the next unread message in the 'inbox' to 'outparam'.
140 * Use this function when multiple threads read from the same inbox.
141 * Uses spinning, that is, it wil not return until it has read a message, and
142 * it will keep checking if a message was written and try to read it. */
143__attribute__((nonnull)) void x9_read_from_shared_inbox_spin(
144 x9_inbox* const inbox,
145 uint64_t const msg_sz,
146 void* restrict const outparam);
147
148/* Returns 'true' if the message was written to the 'inbox', 'false'
149 * otherwise. */
150__attribute__((nonnull)) bool x9_write_to_inbox(
151 x9_inbox* const inbox,
152 uint64_t const msg_sz,
153 void const* restrict const msg);
154
155/* Writes the 'msg' to the 'inbox'.
156 * Uses spinning, that is, it wil not not return until it has written the
157 * 'msg', and it will keep checking if the destination inbox has a free
158 * slot that it can write the 'msg' to. */
159__attribute__((nonnull)) void x9_write_to_inbox_spin(
160 x9_inbox* const inbox,
161 uint64_t const msg_sz,
162 void const* restrict const msg);
163
164/* Writes the same 'msg' to all 'node' inboxes.
165 * Calls 'x9_write_to_inbox_spin' in the background.
166 * Users must guarantee that all 'node' inboxes accept messages of the
167 * same type (or at least of the same 'msg_sz') */
168__attribute__((nonnull)) void x9_broadcast_msg_to_all_node_inboxes(
169 x9_node const* const node,
170 uint64_t const msg_sz,
171 void const* restrict const msg);
172
173#ifdef __cplusplus
174}
175#endif
176#endif // O2_FRAMEWORK_FOUDATION_X9_H_
struct x9_node_internal x9_node
Definition AsyncQueue.h:20
struct x9_inbox_internal x9_inbox
Definition AsyncQueue.h:19
GLuint const GLchar * name
Definition glcorearb.h:781
uint64_t const n_inboxes
Definition x9.h:71
char const *restrict const cmp
Definition x9.h:96
uint64_t const bool x9_inbox_is_valid(x9_inbox const *const inbox)
uint64_t const void *restrict const outparam
Definition x9.h:121
char const *restrict const uint64_t const msg_sz
Definition x9.h:60
uint64_t const void const *restrict const msg
Definition x9.h:153
bool x9_node_is_valid(x9_node const *const node)