blob: b2cbc1d3184547cb17afb91e7665682973a9100f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#ifndef __SYS_MSG_H
#define __SYS_MSG_H
#include <stdint.h>
#include <stdlib.h>
#include <builtins.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef void* msg_q_t;
struct msg_t
{
uint32_t type;
uint32_t __reserved__async;
uint64_t data[2];
void* extra_data;
};
// Message queue interfaces.
/** @fn msg_q_create
* @brief Create a new message queue.
*
* @return msg_q_t handle
*/
msg_q_t msg_q_create();
/** @fn msg_q_destroy
* @brief Deallocate a message queue previously allocated with msg_q_create()
*
* @param[in] q - handle to message queue to destroy
*/
void msg_q_destroy( msg_q_t q );
/** @fn msg_q_register
* @brief Assign a name to a message queue.
*
* @param[in] q - handle of message queue to name
* @param[in] name - name
*
* @return Result of msg_sendrecv where zero indicates success
*/
int msg_q_register(msg_q_t q, const char* name);
/** @fn msg_q_resolve
* @brief Given the name of a message queue, return the handle to it.
*
* @param[in] name - name of message queue
*
* @return message queue handle or null if name not found.
*/
msg_q_t msg_q_resolve(const char* name);
// Message interfaces.
/** @fn msg_allocate
* @brief Allocate space for message
* @return Pointer to message
*/
ALWAYS_INLINE
inline msg_t* msg_allocate() { return (msg_t*)malloc(sizeof(msg_t)); }
/** @fn msg_free
* @brief Free a msg_t
* @param[in] msg - message to free
*/
ALWAYS_INLINE
inline void msg_free(msg_t* m) { free(m); }
/** @fn msg_send
* @brief Send a message asynchronously.
*
* This call adds the message queue then returns
* to the caller. Any process waiting for a message
* in the queue will awake with this message.
*
* @param[in] q - message queue
* @param[in] msg - message
* @return Always returns zero.
*/
int msg_send(msg_q_t q, msg_t* msg);
/** @fn msg_sendrecv
* @brief Send a message to a server and get a response synchronously.
*
* The calling [client] thread blocks until the recipient [server] receives
* and replies to the message.
*
* @param[in] q - message queue
* @param[in,out] msg - message
* @return Zero on success, else negative.
*/
int msg_sendrecv(msg_q_t q, msg_t* msg);
/** @fn msg_respond
* @brief Respond to a synchronous message.
*
* This is how server-side code responds to synchronous
* messaging when clients call msg_sendrecv().
*
* @param[in] q - message queue
* @param[in] msg - response message
* @return Zero on success, else negative.
*/
int msg_respond(msg_q_t q, msg_t* msg);
/** @fn msg_wait
* @brief Read a message from the message queue.
*
* If a message is already on the queue, this call will return immediately
* with the message. Otherwise the calling thread will block and wait for
* a message.
*
* @param[in] q - message queue to read
* @return the message posted to the queue
*/
msg_t* msg_wait(msg_q_t q);
/** @fn msg_is_async
* @brief Indicates if message is asynchronous.
*
* Tests the message field "__reserved__async" which appears to be set to 0 to indicate asynchronous, and 1 to indicate synchronous message.
*
* @return true if asynchronous message
*/
ALWAYS_INLINE
inline uint32_t msg_is_async(msg_t* msg)
{ return 0 == msg->__reserved__async; }
#ifdef __cplusplus
}
#endif
#endif
|