@@ -124,8 +124,8 @@ int k_msgq_cleanup(struct k_msgq *msgq)
124
124
return 0 ;
125
125
}
126
126
127
-
128
- int z_impl_k_msgq_put ( struct k_msgq * msgq , const void * data , k_timeout_t timeout )
127
+ static inline int put_msg_in_queue ( struct k_msgq * msgq , const void * data ,
128
+ k_timeout_t timeout , bool put_at_back )
129
129
{
130
130
__ASSERT (!arch_is_in_isr () || K_TIMEOUT_EQ (timeout , K_NO_WAIT ), "" );
131
131
@@ -150,13 +150,31 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout
150
150
arch_thread_return_value_set (pending_thread , 0 );
151
151
z_ready_thread (pending_thread );
152
152
} else {
153
- /* put message in queue */
154
153
__ASSERT_NO_MSG (msgq -> write_ptr >= msgq -> buffer_start &&
155
154
msgq -> write_ptr < msgq -> buffer_end );
156
- (void )memcpy (msgq -> write_ptr , (char * )data , msgq -> msg_size );
157
- msgq -> write_ptr += msgq -> msg_size ;
158
- if (msgq -> write_ptr == msgq -> buffer_end ) {
159
- msgq -> write_ptr = msgq -> buffer_start ;
155
+ if (put_at_back ) {
156
+ /*
157
+ * writing a message to the back of the queue is
158
+ * simple and effective: copy the message, then
159
+ * increment write_ptr.
160
+ */
161
+ (void )memcpy (msgq -> write_ptr , (char * )data , msgq -> msg_size );
162
+ msgq -> write_ptr += msgq -> msg_size ;
163
+ if (msgq -> write_ptr == msgq -> buffer_end ) {
164
+ msgq -> write_ptr = msgq -> buffer_start ;
165
+ }
166
+ } else {
167
+ /*
168
+ * writing a message to the head of the queue can
169
+ * be achieved by simply decrementing the read pointer
170
+ * to open space at the front of the queue, then
171
+ * copying the message to the newly created space.
172
+ */
173
+ if (msgq -> read_ptr == msgq -> buffer_start ) {
174
+ msgq -> read_ptr = msgq -> buffer_end ;
175
+ }
176
+ msgq -> read_ptr -= msgq -> msg_size ;
177
+ (void )memcpy (msgq -> read_ptr , (char * )data , msgq -> msg_size );
160
178
}
161
179
msgq -> used_msgs ++ ;
162
180
resched = handle_poll_events (msgq );
@@ -187,6 +205,17 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout
187
205
return result ;
188
206
}
189
207
208
+
209
+ int z_impl_k_msgq_put (struct k_msgq * msgq , const void * data , k_timeout_t timeout )
210
+ {
211
+ return put_msg_in_queue (msgq , data , timeout , true);
212
+ }
213
+
214
+ int z_impl_k_msgq_put_front (struct k_msgq * msgq , const void * data , k_timeout_t timeout )
215
+ {
216
+ return put_msg_in_queue (msgq , data , timeout , false);
217
+ }
218
+
190
219
#ifdef CONFIG_USERSPACE
191
220
static inline int z_vrfy_k_msgq_put (struct k_msgq * msgq , const void * data ,
192
221
k_timeout_t timeout )
@@ -197,6 +226,16 @@ static inline int z_vrfy_k_msgq_put(struct k_msgq *msgq, const void *data,
197
226
return z_impl_k_msgq_put (msgq , data , timeout );
198
227
}
199
228
#include <zephyr/syscalls/k_msgq_put_mrsh.c>
229
+
230
+ static inline int z_vrfy_k_msgq_put_front (struct k_msgq * msgq , const void * data ,
231
+ k_timeout_t timeout )
232
+ {
233
+ K_OOPS (K_SYSCALL_OBJ (msgq , K_OBJ_MSGQ ));
234
+ K_OOPS (K_SYSCALL_MEMORY_READ (data , msgq -> msg_size ));
235
+
236
+ return z_impl_k_msgq_put_front (msgq , data , timeout );
237
+ }
238
+ #include <zephyr/syscalls/k_msgq_put_front_mrsh.c>
200
239
#endif /* CONFIG_USERSPACE */
201
240
202
241
void z_impl_k_msgq_get_attrs (struct k_msgq * msgq , struct k_msgq_attrs * attrs )
0 commit comments