IntrOS
Loading...
Searching...
No Matches
osmessagequeue.h
1/******************************************************************************
2
3 @file IntrOS: osmessagequeue.h
4 @author Rajmund Szymanski
5 @date 17.11.2025
6 @brief This file contains definitions for IntrOS.
7
8 ******************************************************************************
9
10 Copyright (c) 2018-2022 Rajmund Szymanski. All rights reserved.
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to
14 deal in the Software without restriction, including without limitation the
15 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 sell copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 IN THE SOFTWARE.
29
30 ******************************************************************************/
31
32#ifndef __INTROS_MSG_H
33#define __INTROS_MSG_H
34
35#include "oskernel.h"
36#include "osclock.h"
37
43
47
48typedef struct __msh msh_t;
49
50__PACKED_STRUCT __msh
51{
52 size_t size;
53#ifndef __cplusplus // ISO C++ forbids flexible array member
54 char data[];
55#endif
56};
57
58#define MSG_SIZE( size ) \
59 ( (size_t)( size ) + sizeof(msh_t) )
60
64
65typedef struct __msg msg_t;
66
67struct __msg
68{
69 obj_t obj;
70
71 size_t count;
72 size_t limit;
73 size_t size;
74
75 size_t head;
76 size_t tail;
77 char * data;
78};
79
80typedef struct __msg msg_id [];
81
82/******************************************************************************
83 *
84 * Name : _MSG_INIT
85 *
86 * Description : create and initialize a message queue object
87 *
88 * Parameters
89 * limit : size of a queue (max number of stored messages)
90 * size : max size of a single message (in bytes)
91 * data : message queue data buffer
92 *
93 * Return : message queue object
94 *
95 * Note : for internal use
96 *
97 ******************************************************************************/
98
99#define _MSG_INIT( _limit, _size, _data ) \
100 { _OBJ_INIT(), 0, _limit * MSG_SIZE(_size), MSG_SIZE(_size), 0, 0, _data }
101
102/******************************************************************************
103 *
104 * Name : _MSG_DATA
105 *
106 * Description : create a message queue data
107 *
108 * Parameters
109 * limit : size of a queue (max number of stored messages)
110 * size : max size of a single message (in bytes)
111 *
112 * Return : message queue data
113 *
114 * Note : for internal use
115 *
116 ******************************************************************************/
117
118#ifndef __cplusplus
119#define _MSG_DATA( _limit, _size ) (char[_limit * MSG_SIZE(_size)]){ 0 }
120#endif
121
130#define OS_MSG_BUFFER( buf, limit, size ) \
131 char buf[limit * MSG_SIZE(size)]
132
141#define OS_MSG( msg, limit, size ) \
142 static char msg##__buf[limit * MSG_SIZE(size)]; \
143 msg_t msg[] = { _MSG_INIT( limit, size, msg##__buf ) }
144
145/** static alias of OS_MSG() */
146#define static_MSG( msg, limit, size ) \
147 static char msg##__buf[limit * MSG_SIZE(size)]; \
148 static msg_t msg[] = { _MSG_INIT( limit, size, msg##__buf ) }
149
160
161#ifndef __cplusplus
162#define MSG_INIT( limit, size ) \
163 _MSG_INIT( limit, size, _MSG_DATA( limit, size ) )
164#endif
165
176
177#ifndef __cplusplus
178#define MSG_CREATE( limit, size ) \
179 { MSG_INIT ( limit, size ) }
180/** alias of MSG_CREATE() */
181#define MSG_NEW \
182 MSG_CREATE
183#endif
184
185#ifdef __cplusplus
186extern "C" {
187#endif
188
198void msg_init( msg_t *msg, size_t size, void *data, size_t bufsize );
199
208void msg_reset( msg_t *msg );
209
211__STATIC_INLINE
212void msg_kill( msg_t *msg ) { msg_reset(msg); }
213
230int msg_take( msg_t *msg, void *data, size_t size, size_t *read );
231
233__STATIC_INLINE
234int msg_tryWait( msg_t *msg, void *data, size_t size, size_t *read ) { return msg_take(msg, data, size, read); }
235
236#if OS_ATOMICS
238int msg_takeAsync( msg_t *msg, void *data, size_t size, size_t *read );
239#endif
240
259int msg_waitFor( msg_t *msg, void *data, size_t size, size_t *read, cnt_t delay );
260
277int msg_waitUntil( msg_t *msg, void *data, size_t size, size_t *read, cnt_t time );
278
294
295__STATIC_INLINE
296int msg_wait( msg_t *msg, void *data, size_t size, size_t *read ) { return msg_waitFor(msg, data, size, read, INFINITE); }
297
298#if OS_ATOMICS
300int msg_waitAsync( msg_t *msg, void *data, size_t size, size_t *read );
301#endif
302
318int msg_give( msg_t *msg, const void *data, size_t size );
319
320#if OS_ATOMICS
322int msg_giveAsync( msg_t *msg, const void *data, size_t size );
323#endif
324
342int msg_sendFor( msg_t *msg, const void *data, size_t size, cnt_t delay );
343
359int msg_sendUntil( msg_t *msg, const void *data, size_t size, cnt_t time );
360
375
376__STATIC_INLINE
377int msg_send( msg_t *msg, const void *data, size_t size ) { return msg_sendFor(msg, data, size, INFINITE); }
378
379#if OS_ATOMICS
381int msg_sendAsync( msg_t *msg, const void *data, size_t size );
382#endif
383
396int msg_push( msg_t *msg, const void *data, size_t size );
397
406size_t msg_count( msg_t *msg );
407
416size_t msg_space( msg_t *msg );
417
426size_t msg_limit( msg_t *msg );
427
435
436__STATIC_INLINE
437size_t msg_size( msg_t *msg ) { return msg->size - sizeof(size_t); }
438
439#ifdef __cplusplus
440}
441#endif
442
443/* -------------------------------------------------------------------------- */
444
445#if defined(__cplusplus)
446namespace intros {
447
455
456template<unsigned limit_, size_t size_>
457struct MessageQueueT : public __msg
458{
460 constexpr
461 MessageQueueT(): __msg _MSG_INIT(limit_, size_, data_) {}
462
463 ~MessageQueueT() { assert(__msg::obj.queue == nullptr); }
464
465 /// move constructor
466 MessageQueueT( MessageQueueT&& _src ): __msg _MSG_INIT(limit_, size_, data_)
467 {
468 assert(_src.__msg::count == 0 && _src.obj.queue == nullptr);
469 (void) _src;
470 }
471
472 MessageQueueT( const MessageQueueT& ) = delete;
473 MessageQueueT& operator=( MessageQueueT&& ) = delete;
474 MessageQueueT& operator=( const MessageQueueT& ) = delete;
476 void reset () { msg_reset (this); }
477 void kill () { msg_kill (this); }
478 int take ( void *_data, size_t _size, size_t *_read = nullptr ) { return msg_take (this, _data, _size, _read); }
479 int tryWait ( void *_data, size_t _size, size_t *_read = nullptr ) { return msg_tryWait (this, _data, _size, _read); }
480 template<typename T>
481 int waitFor ( void *_data, size_t _size, size_t *_read, const T& _delay ) { return msg_waitFor (this, _data, _size, _read, Clock::count(_delay)); }
482 template<typename T>
483 int waitUntil( void *_data, size_t _size, size_t *_read, const T& _time ) { return msg_waitUntil(this, _data, _size, _read, Clock::until(_time)); }
484 int wait ( void *_data, size_t _size, size_t *_read = nullptr ) { return msg_wait (this, _data, _size, _read); }
485 int give ( const void *_data, size_t _size ) { return msg_give (this, _data, _size); }
486 template<typename T>
487 int sendFor ( const void *_data, size_t _size, const T& _delay ) { return msg_sendFor (this, _data, _size, Clock::count(_delay)); }
488 template<typename T>
489 int sendUntil( const void *_data, size_t _size, const T& _time ) { return msg_sendUntil(this, _data, _size, Clock::until(_time)); }
490 int send ( const void *_data, size_t _size ) { return msg_send (this, _data, _size); }
491 int push ( const void *_data, size_t _size ) { return msg_push (this, _data, _size); }
492 size_t count () { return msg_count (this); }
493 size_t space () { return msg_space (this); }
494 size_t limit () { return msg_limit (this); }
495 size_t size () { return msg_size (this); }
496#if OS_ATOMICS
497 int takeAsync( void *_data, size_t _size, size_t *_read = nullptr ) { return msg_takeAsync(this, _data, _size, _read); }
498 int waitAsync( void *_data, size_t _size, size_t *_read = nullptr ) { return msg_waitAsync(this, _data, _size, _read); }
499 int giveAsync( const void *_data, size_t _size ) { return msg_giveAsync(this, _data, _size); }
500 int sendAsync( const void *_data, size_t _size ) { return msg_sendAsync(this, _data, _size); }
501#endif
502
503 private:
504 char data_[limit_ * MSG_SIZE(size_)];
505};
506
514
515template<unsigned limit_, class C>
516struct MessageQueueTT : public MessageQueueT<limit_, sizeof(C)>
517{
519 constexpr
520 MessageQueueTT(): MessageQueueT<limit_, sizeof(C)>() {}
522 int take ( C *_data, size_t *_read = nullptr ) { return msg_take (this, _data, sizeof(C), _read); }
523 int tryWait ( C *_data, size_t *_read = nullptr ) { return msg_tryWait (this, _data, sizeof(C), _read); }
524 template<typename T>
525 int waitFor ( C *_data, size_t *_read, const T& _delay ) { return msg_waitFor (this, _data, sizeof(C), _read, Clock::count(_delay)); }
526 template<typename T>
527 int waitUntil( C *_data, size_t *_read, const T& _time ) { return msg_waitUntil(this, _data, sizeof(C), _read, Clock::until(_time)); }
528 int wait ( C *_data, size_t *_read = nullptr ) { return msg_wait (this, _data, sizeof(C), _read); }
529 int give ( const C *_data ) { return msg_give (this, _data, sizeof(C)); }
530 template<typename T>
531 int sendFor ( const C *_data, const T& _delay ) { return msg_sendFor (this, _data, sizeof(C), Clock::count(_delay)); }
532 template<typename T>
533 int sendUntil( const C *_data, const T& _time ) { return msg_sendUntil(this, _data, sizeof(C), Clock::until(_time)); }
534 int send ( const C *_data ) { return msg_send (this, _data, sizeof(C)); }
535 int push ( const C *_data ) { return msg_push (this, _data, sizeof(C)); }
536#if OS_ATOMICS
537 int takeAsync( C *_data, size_t *_read = nullptr ) { return msg_takeAsync(this, _data, sizeof(C), _read); }
538 int waitAsync( C *_data, size_t *_read = nullptr ) { return msg_waitAsync(this, _data, sizeof(C), _read); }
539 int giveAsync( const C *_data ) { return msg_giveAsync(this, _data, sizeof(C)); }
540 int sendAsync( const C *_data ) { return msg_sendAsync(this, _data, sizeof(C)); }
541#endif
542};
543
544} // namespace
545#endif//__cplusplus
546
547/* -------------------------------------------------------------------------- */
548
550
551#endif//__INTROS_MSG_H
#define INFINITE
infinite waiting
Definition osbase.h:250
int msg_sendAsync(msg_t *msg, const void *data, size_t size)
Async alias of msg_send().
int msg_push(msg_t *msg, const void *data, size_t size)
try to transfer data to the message queue object, remove the oldest data if the message queue object ...
int msg_sendUntil(msg_t *msg, const void *data, size_t size, cnt_t time)
try to transfer data to the message queue object, wait until given timepoint while the message queue ...
int msg_wait(msg_t *msg, void *data, size_t size, size_t *read)
try to transfer data from the message queue object, wait indefinitely while the message queue object ...
Definition osmessagequeue.h:295
size_t msg_count(msg_t *msg)
return the amount of data contained in the message queue
void msg_kill(msg_t *msg)
alias of msg_reset()
Definition osmessagequeue.h:211
int msg_give(msg_t *msg, const void *data, size_t size)
try to transfer data to the message queue object, don't wait if the message queue object is full
char data[]
message data
Definition osmessagequeue.h:54
size_t msg_limit(msg_t *msg)
return the size of the message queue
int msg_waitFor(msg_t *msg, void *data, size_t size, size_t *read, cnt_t delay)
try to transfer data from the message queue object, wait for given duration of time while the message...
size_t msg_space(msg_t *msg)
return the amount of free space in the message queue
int msg_take(msg_t *msg, void *data, size_t size, size_t *read)
try to transfer data from the message queue object, don't wait if the message queue object is empty
int msg_send(msg_t *msg, const void *data, size_t size)
try to transfer data to the message queue object, wait indefinitely while the message queue object is...
Definition osmessagequeue.h:376
int msg_sendFor(msg_t *msg, const void *data, size_t size, cnt_t delay)
try to transfer data to the message queue object, wait for given duration of time while the message q...
void msg_reset(msg_t *msg)
reset the message queue object and wake up all waiting tasks with 'E_STOPPED' event value
int msg_tryWait(msg_t *msg, void *data, size_t size, size_t *read)
alias of msg_take()
Definition osmessagequeue.h:233
void msg_init(msg_t *msg, size_t size, void *data, size_t bufsize)
initialize a message queue object
int msg_giveAsync(msg_t *msg, const void *data, size_t size)
Async alias of msg_give().
struct __msh msh_t
message header
Definition osmessagequeue.h:48
size_t msg_size(msg_t *msg)
return max size of a message in the message queue
Definition osmessagequeue.h:436
int msg_waitAsync(msg_t *msg, void *data, size_t size, size_t *read)
Async alias of msg_wait().
int msg_takeAsync(msg_t *msg, void *data, size_t size, size_t *read)
Async alias of msg_take().
int msg_waitUntil(msg_t *msg, void *data, size_t size, size_t *read, cnt_t time)
try to transfer data from the message queue object, wait until given timepoint while the message queu...
static constexpr rep until(const std::chrono::time_point< Clock, _Duration > &_time)
time point in ticks, rounded up to whole ticks (only a time point of this clock)
Definition osclock.h:109
static constexpr rep count(const std::chrono::duration< _Rep, _Period > &_delay)
delay in ticks, rounded up to whole ticks; negative delay: IMMEDIATE, delay out of range: INFINITE
Definition osclock.h:102
constexpr MessageQueueTT()
constructor, see the constructor parameters of the class
Definition osmessagequeue.h:519
int sendAsync(const C *_data)
msg_sendAsync()
Definition osmessagequeue.h:539
int send(const C *_data)
msg_send()
Definition osmessagequeue.h:533
int tryWait(C *_data, size_t *_read=nullptr)
msg_tryWait()
Definition osmessagequeue.h:522
int giveAsync(const C *_data)
msg_giveAsync()
Definition osmessagequeue.h:538
int takeAsync(C *_data, size_t *_read=nullptr)
msg_takeAsync()
Definition osmessagequeue.h:536
int sendFor(const C *_data, const T &_delay)
msg_sendFor()
Definition osmessagequeue.h:530
int give(const C *_data)
msg_give()
Definition osmessagequeue.h:528
int waitUntil(C *_data, size_t *_read, const T &_time)
msg_waitUntil()
Definition osmessagequeue.h:526
int sendUntil(const C *_data, const T &_time)
msg_sendUntil()
Definition osmessagequeue.h:532
int take(C *_data, size_t *_read=nullptr)
msg_take()
Definition osmessagequeue.h:521
int wait(C *_data, size_t *_read=nullptr)
msg_wait()
Definition osmessagequeue.h:527
int push(const C *_data)
msg_push()
Definition osmessagequeue.h:534
int waitFor(C *_data, size_t *_read, const T &_delay)
msg_waitFor()
Definition osmessagequeue.h:524
int waitAsync(C *_data, size_t *_read=nullptr)
msg_waitAsync()
Definition osmessagequeue.h:537
create and initialize a message queue object
Definition osmessagequeue.h:457
size_t space()
msg_space()
Definition osmessagequeue.h:492
void reset()
msg_reset()
Definition osmessagequeue.h:475
int push(const void *_data, size_t _size)
msg_push()
Definition osmessagequeue.h:490
size_t limit()
msg_limit()
Definition osmessagequeue.h:493
int sendUntil(const void *_data, size_t _size, const T &_time)
msg_sendUntil()
Definition osmessagequeue.h:488
int wait(void *_data, size_t _size, size_t *_read=nullptr)
msg_wait()
Definition osmessagequeue.h:483
int takeAsync(void *_data, size_t _size, size_t *_read=nullptr)
msg_takeAsync()
Definition osmessagequeue.h:496
int tryWait(void *_data, size_t _size, size_t *_read=nullptr)
msg_tryWait()
Definition osmessagequeue.h:478
void kill()
msg_kill()
Definition osmessagequeue.h:476
size_t count()
msg_count()
Definition osmessagequeue.h:491
size_t size()
msg_size()
Definition osmessagequeue.h:494
constexpr MessageQueueT()
constructor, see the constructor parameters of the class
Definition osmessagequeue.h:460
int waitAsync(void *_data, size_t _size, size_t *_read=nullptr)
msg_waitAsync()
Definition osmessagequeue.h:497
int sendAsync(const void *_data, size_t _size)
msg_sendAsync()
Definition osmessagequeue.h:499
int waitFor(void *_data, size_t _size, size_t *_read, const T &_delay)
msg_waitFor()
Definition osmessagequeue.h:480
int give(const void *_data, size_t _size)
msg_give()
Definition osmessagequeue.h:484
int take(void *_data, size_t _size, size_t *_read=nullptr)
msg_take()
Definition osmessagequeue.h:477
int giveAsync(const void *_data, size_t _size)
msg_giveAsync()
Definition osmessagequeue.h:498
int sendFor(const void *_data, size_t _size, const T &_delay)
msg_sendFor()
Definition osmessagequeue.h:486
int send(const void *_data, size_t _size)
msg_send()
Definition osmessagequeue.h:489
int waitUntil(void *_data, size_t _size, size_t *_read, const T &_time)
msg_waitUntil()
Definition osmessagequeue.h:482