µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os::rtos::message_queue Class Reference

POSIX compliant message queue, using the default RTOS allocator. More...

#include <cmsis-plus/rtos/os.h>

+ Inheritance diagram for os::rtos::message_queue:

Classes

class  arena
 Storage for a static message queue. More...
 
class  attributes
 Message queue attributes. More...
 

Public Types

using allocator_type = memory::allocator< thread::stack::allocation_element_t >
 Default RTOS allocator.
 
using index_t = message_queue::size_t
 Type of list index storage.
 
using msg_size_t = uint16_t
 Type of message size storage.
 
using priority_t = uint8_t
 Type of message priority storage.
 
using size_t = uint8_t
 Type of a queue size storage.
 

Public Member Functions

template<typename T >
constexpr std::size_t compute_allocated_size_bytes (std::size_t msgs, std::size_t msg_size_bytes)
 Calculator for queue storage requirements.
 
Constructors & Destructor
 message_queue (std::size_t msgs, std::size_t msg_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
 Construct a message queue object instance.
 
 message_queue (const char *name, std::size_t msgs, std::size_t msg_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
 Construct a named message queue object instance.
 
virtual ~message_queue ()
 Destruct the message queue object instance.
 
Operators
bool operator== (const message_queue &rhs) const
 Compare memory queues.
 
Public Member Functions
result_t send (const void *msg, std::size_t nbytes, priority_t mprio=default_priority)
 Send a message to the queue.
 
result_t try_send (const void *msg, std::size_t nbytes, priority_t mprio=default_priority)
 Try to send a message to the queue.
 
result_t timed_send (const void *msg, std::size_t nbytes, clock::duration_t timeout, priority_t mprio=default_priority)
 Send a message to the queue with timeout.
 
result_t receive (void *msg, std::size_t nbytes, priority_t *mprio=nullptr)
 Receive a message from the queue.
 
result_t try_receive (void *msg, std::size_t nbytes, priority_t *mprio=nullptr)
 Try to receive a message from the queue.
 
result_t timed_receive (void *msg, std::size_t nbytes, clock::duration_t timeout, priority_t *mprio=nullptr)
 Receive a message from the queue with timeout.
 
std::size_t capacity (void) const
 Get queue capacity.
 
std::size_t length (void) const
 Get queue length.
 
std::size_t msg_size (void) const
 Get message size.
 
bool empty (void) const
 Check if the queue is empty.
 
bool full (void) const
 Check if the queue is full.
 
result_t reset (void)
 Reset the message queue.
 
Public Member Functions
const char * name (void) const
 Get object name.
 

Static Public Member Functions

Operators
static void * operator new (std::size_t bytes)
 Allocate space for a new object instance using the RTOS system allocator.
 
static void * operator new (std::size_t bytes, void *ptr)
 Emplace a new object instance.
 
static void * operator new[] (std::size_t bytes)
 Allocate space for an array of new object instances using the RTOS system allocator.
 
static void * operator new[] (std::size_t bytes, void *ptr)
 Emplace an array of new object instances.
 
static void operator delete (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated object instance. using the RTOS system allocator.
 
static void operator delete[] (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated array of object. instances using the RTOS system allocator.
 

Static Public Attributes

static constexpr priority_t default_priority = 0
 Default message priority.
 
static const attributes initializer
 Default message queue initialiser.
 
static constexpr msg_size_t max_msg_size = 0xFFFF
 Maximum message size.
 
static constexpr priority_t max_priority = 0xFF
 Maximum message priority.
 
static constexpr message_queue::size_t max_size = 0xFF
 Maximum queue size.
 
static constexpr index_t no_index = max_size
 Index value to represent an illegal index.
 

Detailed Description

POSIX message queues allow threads to exchange data in the form of messages. Messages are transferred to and from a queue using send() and receive(). Each message has an associated priority, and messages are always delivered to the receiving process highest priority first.

The storage for the message queue is allocated dynamically, using the RTOS specific allocator (os::memory::allocator).

For special cases, the storage can be allocated outside the class and specified via the mq_queue_address and mq_queue_size_bytes attributes.

message_queue is a representative instance of the message_queue_allocated template; it is also used by the C API.

Example
// Define the message type.
typedef struct {
uint32_t id;
} msg_t;
// Define the queue size.
constexpr uint32_t queue_size = 5;
// The queue storage is allocated dynamically on the heap.
message_queue mq { queue_size, sizeof(msg_t) };
void
consumer(void)
{
// Do something
msg_t msg;
for (; some_condition();)
{
mq.receive(&msg, sizeof(msg));
// Process message
if (msg.id == 7)
{
// Something special
}
}
// Do something else.
}
void
producer(void)
{
// Do something
msg_t msg;
msg.id = 7;
mq.send(&msg, sizeof(msg));
// Do something else.
}
POSIX compliant message queue, using the default RTOS allocator.
Definition os-mqueue.h:67
result_t receive(void *msg, std::size_t nbytes, priority_t *mprio=nullptr)
Receive a message from the queue.
POSIX compatibility
Inspired by mqd_t from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).

Definition at line 66 of file os-mqueue.h.

Constructor & Destructor Documentation

◆ message_queue() [1/2]

os::rtos::message_queue::message_queue ( std::size_t  msgs,
std::size_t  msg_size_bytes,
const attributes attr = initializer,
const allocator_type allocator = allocator_type () 
)
Parameters
[in]msgsThe number of messages.
[in]msg_size_bytesThe message size, in bytes.
[in]attrReference to attributes.
[in]allocatorReference to allocator. Default a local temporary instance.

This constructor shall initialise a message queue object with attributes referenced by attr. If the attributes specified by attr are modified later, the memory pool attributes shall not be affected. Upon successful initialisation, the state of the message queue object shall become initialised.

Only the message queue itself may be used for performing synchronisation. It is not allowed to make copies of message queue objects.

In cases where default message queue attributes are appropriate, the variable message_queue::initializer can be used to initialise message queue. The effect shall be equivalent to creating a message queue object with the simple constructor.

If the attributes define a storage area (via mq_queue_address and mq_queue_size_bytes), that storage is used, otherwise the storage is dynamically allocated using the RTOS specific allocator (rtos::memory::allocator).

If the attr attributes are modified after the message_queue creation, the message_queue attributes shall not be affected.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 395 of file os-mqueue.cpp.

398 : message_queue{ nullptr, msgs, msg_size_bytes, attr, allocator }
399 {
400 }
message_queue(std::size_t msgs, std::size_t msg_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a message queue object instance.
allocator_stateless_default_resource< T > allocator
Type of allocator used by the system objects. Must be stateless.
Definition os-types.h:53

◆ message_queue() [2/2]

os::rtos::message_queue::message_queue ( const char *  name,
std::size_t  msgs,
std::size_t  msg_size_bytes,
const attributes attr = initializer,
const allocator_type allocator = allocator_type () 
)
Parameters
[in]namePointer to name.
[in]msgsThe number of messages.
[in]msg_size_bytesThe message size, in bytes.
[in]attrReference to attributes.
[in]allocatorReference to allocator. Default a local temporary instance.

This constructor shall initialise a named message queue object with attributes referenced by attr. If the attributes specified by attr are modified later, the memory pool attributes shall not be affected. Upon successful initialisation, the state of the message queue object shall become initialised.

Only the message queue itself may be used for performing synchronisation. It is not allowed to make copies of message queue objects.

In cases where default message queue attributes are appropriate, the variable message_queue::initializer can be used to initialise message queue. The effect shall be equivalent to creating a message queue object with the simple constructor.

If the attributes define a storage area (via mq_queue_address and mq_queue_size_bytes), that storage is used, otherwise the storage is dynamically allocated using the RTOS specific allocator (rtos::memory::allocator).

If the attr attributes are modified after the message_queue creation, the message_queue attributes shall not be affected.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 431 of file os-mqueue.cpp.

436 {
437#if defined(OS_TRACE_RTOS_MQUEUE)
438 trace::printf ("%s() @%p %s %u %u\n", __func__, this, this->name (),
439 msgs, msg_size_bytes);
440#endif
441
442 if (attr.mq_queue_address != nullptr)
443 {
444 // Do not use any allocator at all.
445 internal_construct_ (msgs, msg_size_bytes, attr, nullptr, 0);
446 }
447 else
448 {
449 allocator_ = &allocator;
450
451 // If no user storage was provided via attributes,
452 // allocate it dynamically via the allocator.
453 allocated_queue_size_elements_
455 typename allocator_type::value_type> (msgs,
456 msg_size_bytes)
457 + sizeof (typename allocator_type::value_type) - 1)
458 / sizeof (typename allocator_type::value_type);
459
460 allocated_queue_addr_
461 = const_cast<allocator_type&> (allocator).allocate (
462 allocated_queue_size_elements_);
463
464 internal_construct_ (
465 msgs, msg_size_bytes, attr, allocated_queue_addr_,
466 allocated_queue_size_elements_
467 * sizeof (typename allocator_type::value_type));
468 }
469 }
object_named_system()
Construct a named system object instance.
Definition os-decls.h:760
const char * name(void) const
Get object name.
Definition os-decls.h:753
T value_type
Type of elements to be allocated.
Definition os-memory.h:543
constexpr std::size_t compute_allocated_size_bytes(std::size_t msgs, std::size_t msg_size_bytes)
Calculator for queue storage requirements.
Definition os-mqueue.h:253
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
memory::allocator< thread::stack::allocation_element_t > allocator_type
Default RTOS allocator.
Definition os-mqueue.h:224

References compute_allocated_size_bytes(), os::rtos::message_queue::attributes::mq_queue_address, and os::trace::printf().

◆ ~message_queue()

os::rtos::message_queue::~message_queue ( )
virtual

This destructor shall destroy the message queue object; the object becomes, in effect, uninitialised. An implementation may cause the destructor to set the object to an invalid value.

It shall be safe to destroy an initialised message queue object upon which no threads are currently blocked. Attempting to destroy a message queue object upon which other threads are currently blocked results in undefined behaviour.

If the storage for the message queue was dynamically allocated, it is deallocated using the same allocator.

Definition at line 485 of file os-mqueue.cpp.

486 {
487#if defined(OS_TRACE_RTOS_MQUEUE)
488 trace::printf ("%s() @%p %s\n", __func__, this, name ());
489#endif
490
491#if !defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
492
493 // There must be no threads waiting for this queue.
494 assert (send_list_.empty ());
495 assert (receive_list_.empty ());
496
497#endif
498
499 if (allocated_queue_addr_ != nullptr)
500 {
501 typedef
502 typename std::allocator_traits<allocator_type>::pointer pointer;
503
504 static_cast<allocator_type*> (const_cast<void*> (allocator_))
505 ->deallocate (reinterpret_cast<pointer> (allocated_queue_addr_),
506 allocated_queue_size_elements_);
507 }
508
509#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
510
511 port::message_queue::destroy (this);
512
513#endif
514 }

References os::rtos::memory::allocator_stateless_default_resource< T >::deallocate(), os::rtos::internal::object_named::name(), and os::trace::printf().

Member Function Documentation

◆ capacity()

std::size_t os::rtos::message_queue::capacity ( void  ) const
inline
Parameters
None.
Returns
The max number of messages that can be queued.
POSIX compatibility
Note
Can be invoked from Interrupt Service Routines. Extension to standard, no POSIX similar functionality identified.

Definition at line 1305 of file os-mqueue.h.

1306 {
1307 return msgs_;
1308 }

Referenced by full().

◆ compute_allocated_size_bytes()

template<typename T >
constexpr std::size_t os::rtos::message_queue::compute_allocated_size_bytes ( std::size_t  msgs,
std::size_t  msg_size_bytes 
)
inlineconstexpr
Parameters
msgsNumber of messages.
msg_size_bytesSize of message.
Returns
Total required storage in bytes, including internal alignment.

Definition at line 253 of file os-mqueue.h.

255 {
256 // Align each message
257 return (msgs
258 * ((msg_size_bytes + (sizeof (T) - 1)) & ~(sizeof (T) - 1)))
259 // Align the indices array
260 + ((2 * msgs * sizeof (index_t) + (sizeof (T) - 1))
261 & ~(sizeof (T) - 1))
262 // Align the priority array
263 + ((msgs * sizeof (priority_t) + (sizeof (T) - 1))
264 & ~(sizeof (T) - 1));
265 }
uint8_t priority_t
Type of message priority storage.
Definition os-mqueue.h:125
message_queue::size_t index_t
Type of list index storage.
Definition os-mqueue.h:108

Referenced by message_queue(), and os::rtos::message_queue_allocated< Allocator >::message_queue_allocated().

◆ empty()

bool os::rtos::message_queue::empty ( void  ) const
inline
Parameters
None.
Return values
trueThe queue has no messages.
falseThe queue has some messages.
POSIX compatibility
Extension to standard, no POSIX similar functionality identified.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1329 of file os-mqueue.h.

1330 {
1331 return (length () == 0);
1332 }
std::size_t length(void) const
Get queue length.
Definition os-mqueue.h:1293

References length().

◆ full()

bool os::rtos::message_queue::full ( void  ) const
inline
Parameters
None.
Return values
trueThe queue is full.
falseThe queue is not full.
POSIX compatibility
Extension to standard, no POSIX similar functionality identified.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1341 of file os-mqueue.h.

1342 {
1343 return (length () == capacity ());
1344 }
std::size_t capacity(void) const
Get queue capacity.
Definition os-mqueue.h:1305

References capacity(), and length().

◆ length()

std::size_t os::rtos::message_queue::length ( void  ) const
inline
Parameters
None.
Returns
The number of messages in the queue.
POSIX compatibility
Extension to standard, no POSIX similar functionality identified.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1293 of file os-mqueue.h.

1294 {
1295 return count_;
1296 }

Referenced by empty(), and full().

◆ msg_size()

std::size_t os::rtos::message_queue::msg_size ( void  ) const
inline
Parameters
None.
Returns
The message size, in bytes.
POSIX compatibility
Extension to standard, no POSIX similar functionality identified.
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1317 of file os-mqueue.h.

1318 {
1319 return msg_size_bytes_;
1320 }

◆ name()

const char * os::rtos::internal::object_named::name ( void  ) const
inlineinherited
Parameters
None.
Returns
A null terminated string.

All objects return a non-null string; anonymous objects return "-".

Note
Can be invoked from Interrupt Service Routines.

Definition at line 753 of file os-decls.h.

754 {
755 return name_;
756 }

Referenced by os::memory::lifo::lifo(), os::memory::malloc_memory_resource::malloc_memory_resource(), os::rtos::message_queue_typed< T, Allocator >::message_queue_typed(), os::memory::block_pool::~block_pool(), os::rtos::event_flags::~event_flags(), os::memory::first_fit_top::~first_fit_top(), os::memory::lifo::~lifo(), os::memory::malloc_memory_resource::~malloc_memory_resource(), os::rtos::memory_pool::~memory_pool(), ~message_queue(), os::rtos::mutex::~mutex(), os::rtos::semaphore::~semaphore(), os::rtos::thread::~thread(), os::rtos::timer::~timer(), os::rtos::memory_pool::alloc(), os::rtos::thread::cancel(), os::rtos::event_flags::clear(), os::rtos::mutex::consistent(), os::rtos::thread::detach(), os::memory::new_delete_memory_resource::do_allocate(), os::memory::block_pool::do_allocate(), os::memory::first_fit_top::do_allocate(), os::memory::lifo::do_allocate(), os::memory::malloc_memory_resource::do_allocate(), os::rtos::thread::flags_raise(), os::rtos::memory_pool::free(), os::rtos::event_flags::get(), os::rtos::thread::interrupt(), os::rtos::thread::join(), os::rtos::thread::kill(), os::rtos::internal::terminated_threads_list::link(), os::rtos::mutex::lock(), os::rtos::memory::memory_resource::out_of_memory_handler(), os::rtos::semaphore::post(), os::rtos::mutex::prio_ceiling(), os::rtos::mutex::prio_ceiling(), os::rtos::thread::priority(), os::rtos::thread::priority_inherited(), os::rtos::event_flags::raise(), receive(), os::rtos::memory_pool::reset(), reset(), os::rtos::mutex::reset(), os::rtos::semaphore::reset(), os::rtos::thread::resume(), send(), os::rtos::clock::sleep_for(), os::rtos::timer::start(), os::rtos::timer::stop(), os::rtos::memory_pool::timed_alloc(), os::rtos::mutex::timed_lock(), timed_receive(), timed_send(), os::rtos::semaphore::timed_wait(), os::rtos::event_flags::timed_wait(), os::rtos::memory::memory_resource::trace_print_statistics(), os::rtos::memory_pool::try_alloc(), os::rtos::mutex::try_lock(), try_receive(), try_send(), os::rtos::event_flags::try_wait(), os::rtos::semaphore::try_wait(), os::rtos::internal::ready_threads_list::unlink_head(), os::rtos::mutex::unlock(), os::rtos::event_flags::wait(), os::rtos::semaphore::wait(), and os::rtos::event_flags::waiting().

◆ operator delete()

void os::rtos::internal::object_named_system::operator delete ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited
Parameters
ptrPointer to object.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by a delete-expression to render the value of ptr invalid.

ptr shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced) operator new() which has not been invalidated by an intervening call to operator delete(void*).

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 120 of file os-inlines.h.

121 {
122 assert (!interrupts::in_handler_mode ());
123
124 rtos::memory::allocator<char> ().deallocate (static_cast<char*> (ptr),
125 bytes);
126 }
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101

References os::rtos::memory::allocator_stateless_default_resource< T >::deallocate(), and os::rtos::interrupts::in_handler_mode().

◆ operator delete[]()

void os::rtos::internal::object_named_system::operator delete[] ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited
Parameters
ptrPointer to array of objects.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by the array form of a delete-expression to render the value of ptr invalid.

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 141 of file os-inlines.h.

142 {
143 // Forward array deallocation to single element deallocation.
144 operator delete (ptr, bytes);
145 }

◆ operator new() [1/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes)
inlinestaticinherited
Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated object.

The allocation function (3.7.4.1) called by a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 43 of file os-inlines.h.

44 {
45 assert (!interrupts::in_handler_mode ());
46
47 return rtos::memory::allocator<char> ().allocate (bytes);
48 }

References os::rtos::memory::allocator_stateless_default_resource< T >::allocate(), and os::rtos::interrupts::in_handler_mode().

◆ operator new() [2/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited
Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced object.

The allocation function (3.7.4.1) called by a placement new-expression to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 80 of file os-inlines.h.

81 {
82 return ptr;
83 }

◆ operator new[]() [1/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes)
inlinestaticinherited
Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated array.

The allocation function (3.7.4.1) called by the array form of a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 61 of file os-inlines.h.

62 {
63 // Forward array allocation to single element allocation.
64 return operator new (bytes);
65 }

◆ operator new[]() [2/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited
Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced array.

The allocation function (3.7.4.1) called by the array form of a placement new-expression to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 97 of file os-inlines.h.

98 {
99 // Forward array allocation to single element allocation.
100 return operator new (bytes, ptr);
101 }

◆ operator==()

bool os::rtos::message_queue::operator== ( const message_queue rhs) const
inline
Return values
trueThe given memory queue is the same as this memory queue.
falseThe memory queues are different.

Identical message queues should have the same memory address.

POSIX compatibility
Extension to standard, no POSIX similar functionality identified.

Definition at line 1281 of file os-mqueue.h.

1282 {
1283 return this == &rhs;
1284 }

◆ receive()

result_t os::rtos::message_queue::receive ( void *  msg,
std::size_t  nbytes,
priority_t mprio = nullptr 
)
Parameters
[out]msgThe address where to store the dequeued message.
[in]nbytesThe size of the destination buffer. Must be lower than the value used when creating the queue.
[out]mprioThe address where to store the message priority. The default is nullptr.
Return values
result::okThe message was received.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, is greater than the message size attribute of the message queue.
EPERMCannot be invoked from an Interrupt Service Routines.
ENOTRECOVERABLEThe message could not be dequeued (extension to POSIX).
EBADMSGThe implementation has detected a data corruption problem with the message.
EINTRThe operation was interrupted.

The receive() function shall receive the oldest of the highest priority message(s) from the message queue. If the size of the buffer in bytes, specified by the nbytes argument, is less than the msg_size_bytes attribute of the message queue, the function shall fail and return an error. Otherwise, the selected message shall be removed from the queue and copied to the buffer pointed to by the msg argument.

If the value of nbytes is greater than message_queue::max_size, the result is implementation-defined.

If the argument mprio is not nullptr, the priority of the selected message shall be stored in the location referenced by mprio.

If the message queue is empty, receive() shall block until a message is enqueued on the message queue or until receive() is cancelled/interrupted. If more than one thread is waiting to receive a message when a message arrives at an empty queue and the Priority Scheduling option is supported, then the thread of highest priority that has been waiting the longest shall be selected to receive the message. Otherwise, it is unspecified which waiting thread receives the message.

POSIX compatibility
Inspired by mq_receive() with O_NONBLOCK not set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 1269 of file os-mqueue.cpp.

1270 {
1271#if defined(OS_TRACE_RTOS_MQUEUE)
1272 trace::printf ("%s(%p,%u) @%p %s\n", __func__, msg, nbytes, this,
1273 name ());
1274#endif
1275
1276 // Don't call this from interrupt handlers.
1278 // Don't call this from critical regions.
1279 os_assert_err (!scheduler::locked (), EPERM);
1280
1281 os_assert_err (msg != nullptr, EINVAL);
1282 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
1283
1284#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1285
1286 return port::message_queue::receive (this, msg, nbytes, mprio);
1287
1288#else
1289
1290 // Extra test before entering the loop, with its inherent weight.
1291 // Trade size for speed.
1292 {
1293 // ----- Enter critical section ---------------------------------------
1294 interrupts::critical_section ics;
1295
1296 if (internal_try_receive_ (msg, nbytes, mprio))
1297 {
1298 return result::ok;
1299 }
1300 // ----- Exit critical section ----------------------------------------
1301 }
1302
1303 thread& crt_thread = this_thread::thread ();
1304
1305 // Prepare a list node pointing to the current thread.
1306 // Do not worry for being on stack, it is temporarily linked to the
1307 // list and guaranteed to be removed before this function returns.
1308 internal::waiting_thread_node node{ crt_thread };
1309
1310 for (;;)
1311 {
1312 {
1313 // ----- Enter critical section -----------------------------------
1314 interrupts::critical_section ics;
1315
1316 if (internal_try_receive_ (msg, nbytes, mprio))
1317 {
1318 return result::ok;
1319 }
1320
1321 // Add this thread to the message queue receive waiting list.
1322 scheduler::internal_link_node (receive_list_, node);
1323 // state::suspended set in above link().
1324 // ----- Exit critical section ------------------------------------
1325 }
1326
1328
1329 // Remove the thread from the message queue receive waiting list,
1330 // if not already removed by send().
1331 scheduler::internal_unlink_node (node);
1332
1333 if (crt_thread.interrupted ())
1334 {
1335#if defined(OS_TRACE_RTOS_MQUEUE)
1336 trace::printf ("%s(%p,%u) EINTR @%p %s\n", __func__, msg, nbytes,
1337 this, name ());
1338#endif
1339 return EINTR;
1340 }
1341 }
1342
1343 /* NOTREACHED */
1344 return ENOTRECOVERABLE;
1345
1346#endif
1347 }
Standard thread.
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:179
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:858
thread & thread(void)
Get the current running thread.
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1101

References os::rtos::interrupts::in_handler_mode(), os::rtos::thread::interrupted(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::message_queue_typed< T, Allocator >::receive(), and os::rtos::message_queue_inclusive< T, N >::receive().

◆ reset()

result_t os::rtos::message_queue::reset ( void  )
Parameters
None.
Return values
result::okThe queue was reset.
EPERMCannot be invoked from an Interrupt Service Routines.

Clear both send and receive counter and return the queue to the initial state.

POSIX compatibility
Extension to standard, no POSIX similar functionality identified.
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 1596 of file os-mqueue.cpp.

1597 {
1598#if defined(OS_TRACE_RTOS_MQUEUE)
1599 trace::printf ("%s() @%p %s\n", __func__, this, name ());
1600#endif
1601
1602 // Don't call this from interrupt handlers.
1604
1605#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1606
1607 return port::message_queue::reset (this);
1608
1609#else
1610
1611 {
1612 // ----- Enter critical section ---------------------------------------
1613 interrupts::critical_section ics;
1614
1615 internal_init_ ();
1616 return result::ok;
1617 // ----- Exit critical section ----------------------------------------
1618 }
1619
1620#endif
1621 }

References os::rtos::interrupts::in_handler_mode(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, and os::trace::printf().

◆ send()

result_t os::rtos::message_queue::send ( const void *  msg,
std::size_t  nbytes,
priority_t  mprio = default_priority 
)
Parameters
[in]msgThe address of the message to enqueue.
[in]nbytesThe length of the message. Must be not higher than the value used when creating the queue.
[in]mprioThe message priority. The default is 0.
Return values
result::okThe message was enqueued.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, exceeds the message size attribute of the message queue.
EPERMCannot be invoked from an Interrupt Service Routines.
ENOTRECOVERABLEThe message could not be enqueue (extension to POSIX).
EINTRThe operation was interrupted.

The send() function shall add the message pointed to by the argument msg to the message queue. The nbytes argument specifies the length of the message, in bytes, pointed to by msg. The value of nbytes shall be less than or equal to the msg_size_bytes parameter of the message queue object, or send() shall fail.

If the specified message queue is not full, send() shall behave as if the message is inserted into the message queue at the position indicated by the mprio argument. A message with a larger numeric value of mprio shall be inserted before messages with lower values of mprio. A message shall be inserted after other messages in the queue, if any, with equal mprio. The value of mprio shall be less than message_queue::max_priority.

If the specified message queue is full, send() shall block until space becomes available to enqueue the message, or until send() is cancelled/interrupted. If more than one thread is waiting to send when space becomes available in the message queue and the Priority Scheduling option is supported, then the thread of the highest priority that has been waiting the longest shall be unblocked to send its message. Otherwise, it is unspecified which waiting thread is unblocked.

POSIX compatibility
Inspired by mq_send() with O_NONBLOCK not set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 929 of file os-mqueue.cpp.

930 {
931#if defined(OS_TRACE_RTOS_MQUEUE)
932 trace::printf ("%s(%p,%d,%d) @%p %s\n", __func__, msg, nbytes, mprio,
933 this, name ());
934#endif
935
936 // Don't call this from interrupt handlers.
938 // Don't call this from critical regions.
939 os_assert_err (!scheduler::locked (), EPERM);
940
941 os_assert_err (msg != nullptr, EINVAL);
942 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
943
944#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
945
946 return port::message_queue::send (this, msg, nbytes, mprio);
947
948#else
949
950 {
951 // ----- Enter critical section ---------------------------------------
952 interrupts::critical_section ics;
953
954 if (internal_try_send_ (msg, nbytes, mprio))
955 {
956 return result::ok;
957 }
958 // ----- Exit critical section ----------------------------------------
959 }
960
961 thread& crt_thread = this_thread::thread ();
962
963 // Prepare a list node pointing to the current thread.
964 // Do not worry for being on stack, it is temporarily linked to the
965 // list and guaranteed to be removed before this function returns.
966 internal::waiting_thread_node node{ crt_thread };
967
968 for (;;)
969 {
970 {
971 // ----- Enter critical section -----------------------------------
972 interrupts::critical_section ics;
973
974 if (internal_try_send_ (msg, nbytes, mprio))
975 {
976 return result::ok;
977 }
978
979 // Add this thread to the message queue send waiting list.
980 scheduler::internal_link_node (send_list_, node);
981 // state::suspended set in above link().
982 // ----- Exit critical section ------------------------------------
983 }
984
986
987 // Remove the thread from the message queue send waiting list,
988 // if not already removed by receive().
989 scheduler::internal_unlink_node (node);
990
991 if (crt_thread.interrupted ())
992 {
993#if defined(OS_TRACE_RTOS_MQUEUE)
994 trace::printf ("%s(%p,%d,%d) EINTR @%p %s\n", __func__, msg,
995 nbytes, mprio, this, name ());
996#endif
997 return EINTR;
998 }
999 }
1000
1001 /* NOTREACHED */
1002 return ENOTRECOVERABLE;
1003
1004#endif
1005 }

References os::rtos::interrupts::in_handler_mode(), os::rtos::thread::interrupted(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::message_queue_typed< T, Allocator >::send(), and os::rtos::message_queue_inclusive< T, N >::send().

◆ timed_receive()

result_t os::rtos::message_queue::timed_receive ( void *  msg,
std::size_t  nbytes,
clock::duration_t  timeout,
priority_t mprio = nullptr 
)
Parameters
[out]msgThe address where to store the dequeued message.
[in]nbytesThe size of the destination buffer. Must be lower than the value used when creating the queue.
[in]timeoutThe timeout duration.
[out]mprioThe address where to store the message priority. The default is nullptr.
Return values
result::okThe message was received.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, is greater than the message size attribute of the message queue.
EPERMCannot be invoked from an Interrupt Service Routines.
ENOTRECOVERABLEThe message could not be dequeued (extension to POSIX).
EBADMSGThe implementation has detected a data corruption problem with the message.
EINTRThe operation was interrupted.
ETIMEDOUTNo message arrived on the queue before the specified timeout expired.

The timed_receive() function shall receive the oldest of the highest priority message(s) from the message queue. If the size of the buffer in bytes, specified by the nbytes argument, is less than the msg_size_bytes attribute of the message queue, the function shall fail and return an error. Otherwise, the selected message shall be removed from the queue and copied to the buffer pointed to by the msg argument.

If the value of nbytes is greater than message_queue::max_size, the result is implementation-defined.

If the argument mprio is not nullptr, the priority of the selected message shall be stored in the location referenced by mprio.

If the message queue is empty, timed_receive() shall block until a message is enqueued on the message queue or until timed_receive() is cancelled/interrupted. If more than one thread is waiting to receive a message when a message arrives at an empty queue and the Priority Scheduling option is supported, then the thread of highest priority that has been waiting the longest shall be selected to receive the message. Otherwise, it is unspecified which waiting thread receives the message.

The timed_receive() function shall receive the oldest of the highest priority messages from the message queue as described for the receive() function. However, if no message exists on the queue to satisfy the receive, the wait for such a message shall be terminated when the specified timeout expires.

The timeout shall expire after the number of time units (that is when the value of that clock equals or exceeds (now()+duration). The resolution of the timeout shall be the resolution of the clock on which it is based.

Under no circumstance shall the operation fail with a timeout if a message can be removed from the message queue immediately.

The clock used for timeouts can be specified via the clock attribute. By default, the clock derived from the scheduler timer is used, and the durations are expressed in ticks.

Compatible with POSIX mq_receive() with O_NONBLOCK set. http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#

POSIX compatibility
Inspired by mq_timedreceive() with O_NONBLOCK not set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Differences from the standard:
  • the timeout is not expressed as an absolute time point, but as a relative number of timer ticks (by default, the SysTick clock for CMSIS).
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 1484 of file os-mqueue.cpp.

1486 {
1487#if defined(OS_TRACE_RTOS_MQUEUE)
1488 trace::printf ("%s(%p,%u,%u) @%p %s\n", __func__, msg, nbytes, timeout,
1489 this, name ());
1490#endif
1491
1492 // Don't call this from interrupt handlers.
1494 // Don't call this from critical regions.
1495 os_assert_err (!scheduler::locked (), EPERM);
1496
1497 os_assert_err (msg != nullptr, EINVAL);
1498 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
1499
1500#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1501
1502 return port::message_queue::timed_receive (this, msg, nbytes, timeout,
1503 mprio);
1504
1505#else
1506
1507 // Extra test before entering the loop, with its inherent weight.
1508 // Trade size for speed.
1509 {
1510 // ----- Enter critical section ---------------------------------------
1511 interrupts::critical_section ics;
1512
1513 if (internal_try_receive_ (msg, nbytes, mprio))
1514 {
1515 return result::ok;
1516 }
1517 // ----- Exit critical section ----------------------------------------
1518 }
1519
1520 thread& crt_thread = this_thread::thread ();
1521
1522 // Prepare a list node pointing to the current thread.
1523 // Do not worry for being on stack, it is temporarily linked to the
1524 // list and guaranteed to be removed before this function returns.
1525 internal::waiting_thread_node node{ crt_thread };
1526
1527 internal::clock_timestamps_list& clock_list = clock_->steady_list ();
1528 clock::timestamp_t timeout_timestamp = clock_->steady_now () + timeout;
1529
1530 // Prepare a timeout node pointing to the current thread.
1531 internal::timeout_thread_node timeout_node{ timeout_timestamp,
1532 crt_thread };
1533
1534 for (;;)
1535 {
1536 {
1537 // ----- Enter critical section -----------------------------------
1538 interrupts::critical_section ics;
1539
1540 if (internal_try_receive_ (msg, nbytes, mprio))
1541 {
1542 return result::ok;
1543 }
1544
1545 // Add this thread to the message queue receive waiting list,
1546 // and the clock timeout list.
1547 scheduler::internal_link_node (receive_list_, node, clock_list,
1548 timeout_node);
1549 // state::suspended set in above link().
1550 // ----- Exit critical section ------------------------------------
1551 }
1552
1554
1555 // Remove the thread from the semaphore waiting list,
1556 // if not already removed by send()and from the clock
1557 // timeout list, if not already removed by the timer.
1558 scheduler::internal_unlink_node (node, timeout_node);
1559
1560 if (crt_thread.interrupted ())
1561 {
1562#if defined(OS_TRACE_RTOS_MQUEUE)
1563 trace::printf ("%s(%p,%u,%u) EINTR @%p %s\n", __func__, msg,
1564 nbytes, timeout, this, name ());
1565#endif
1566 return EINTR;
1567 }
1568
1569 if (clock_->steady_now () >= timeout_timestamp)
1570 {
1571#if defined(OS_TRACE_RTOS_MQUEUE)
1572 trace::printf ("%s(%p,%u,%u) ETIMEDOUT @%p %s\n", __func__, msg,
1573 nbytes, timeout, this, name ());
1574#endif
1575 return ETIMEDOUT;
1576 }
1577 }
1578
1579 /* NOTREACHED */
1580 return ENOTRECOVERABLE;
1581
1582#endif
1583 }
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
Definition os-clocks.h:88

References os::rtos::interrupts::in_handler_mode(), os::rtos::thread::interrupted(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::message_queue_typed< T, Allocator >::timed_receive(), and os::rtos::message_queue_inclusive< T, N >::timed_receive().

◆ timed_send()

result_t os::rtos::message_queue::timed_send ( const void *  msg,
std::size_t  nbytes,
clock::duration_t  timeout,
priority_t  mprio = default_priority 
)
Parameters
[in]msgThe address of the message to enqueue.
[in]nbytesThe length of the message. Must be not higher than the value used when creating the queue.
[in]timeoutThe timeout duration.
[in]mprioThe message priority. The default is 0.
Return values
result::okThe message was enqueued.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, exceeds the message size attribute of the message queue.
EPERMCannot be invoked from an Interrupt Service Routines.
ETIMEDOUTThe timeout expired before the message could be added to the queue.
ENOTRECOVERABLEThe message could not be enqueue (extension to POSIX).
EINTRThe operation was interrupted.

The timed_send() function shall add the message pointed to by the argument msg to the message queue. The nbytes argument specifies the length of the message, in bytes, pointed to by msg. The value of nbytes shall be less than or equal to the msg_size_bytes attribute of the message queue object, or timed_send() shall fail.

If the message queue is not full, timed_send() shall behave as if the message is inserted into the message queue at the position indicated by the mprio argument. A message with a larger numeric value of mprio shall be inserted before messages with lower values of mprio. A message shall be inserted after other messages in the queue, if any, with equal mprio. The value of mprio shall be less than message_queue::max_priority.

If the message queue is full, the wait for sufficient room in the queue shall be terminated when the specified timeout expires.

The timeout shall expire after the number of time units (that is when the value of that clock equals or exceeds (now()+timeout). The resolution of the timeout shall be the resolution of the clock on which it is based.

Under no circumstance shall the operation fail with a timeout if there is sufficient room in the queue to add the message immediately.

The clock used for timeouts can be specified via the clock attribute. By default, the clock derived from the scheduler timer is used, and the durations are expressed in ticks.

POSIX compatibility
Inspired by mq_timedsend() with O_NONBLOCK not set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Differences from the standard:
  • the timeout is not expressed as an absolute time point, but as a relative number of timer ticks (by default, the SysTick clock for CMSIS).
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 1129 of file os-mqueue.cpp.

1131 {
1132#if defined(OS_TRACE_RTOS_MQUEUE)
1133 trace::printf ("%s(%p,%u,%u,%u) @%p %s\n", __func__, msg, nbytes, mprio,
1134 timeout, this, name ());
1135#endif
1136
1137 // Don't call this from interrupt handlers.
1139 // Don't call this from critical regions.
1140 os_assert_err (!scheduler::locked (), EPERM);
1141
1142 os_assert_err (msg != nullptr, EINVAL);
1143 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
1144
1145#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1146
1147 return port::message_queue::timed_send (this, msg, nbytes, timeout,
1148 mprio);
1149
1150#else
1151
1152 // Extra test before entering the loop, with its inherent weight.
1153 // Trade size for speed.
1154 {
1155 // ----- Enter critical section ---------------------------------------
1156 interrupts::critical_section ics;
1157
1158 if (internal_try_send_ (msg, nbytes, mprio))
1159 {
1160 return result::ok;
1161 }
1162 // ----- Exit critical section ----------------------------------------
1163 }
1164
1165 thread& crt_thread = this_thread::thread ();
1166
1167 // Prepare a list node pointing to the current thread.
1168 // Do not worry for being on stack, it is temporarily linked to the
1169 // list and guaranteed to be removed before this function returns.
1170 internal::waiting_thread_node node{ crt_thread };
1171
1172 internal::clock_timestamps_list& clock_list = clock_->steady_list ();
1173
1174 clock::timestamp_t timeout_timestamp = clock_->steady_now () + timeout;
1175
1176 // Prepare a timeout node pointing to the current thread.
1177 internal::timeout_thread_node timeout_node{ timeout_timestamp,
1178 crt_thread };
1179
1180 for (;;)
1181 {
1182 {
1183 // ----- Enter critical section -----------------------------------
1184 interrupts::critical_section ics;
1185
1186 if (internal_try_send_ (msg, nbytes, mprio))
1187 {
1188 return result::ok;
1189 }
1190
1191 // Add this thread to the semaphore waiting list,
1192 // and the clock timeout list.
1193 scheduler::internal_link_node (send_list_, node, clock_list,
1194 timeout_node);
1195 // state::suspended set in above link().
1196 // ----- Exit critical section ------------------------------------
1197 }
1198
1200
1201 // Remove the thread from the message queue send waiting list,
1202 // if not already removed by receive() and from the clock timeout
1203 // list, if not already removed by the timer.
1204 scheduler::internal_unlink_node (node, timeout_node);
1205
1206 if (crt_thread.interrupted ())
1207 {
1208#if defined(OS_TRACE_RTOS_MQUEUE)
1209 trace::printf ("%s(%p,%u,%u,%u) EINTR @%p %s\n", __func__, msg,
1210 nbytes, mprio, timeout, this, name ());
1211#endif
1212 return EINTR;
1213 }
1214
1215 if (clock_->steady_now () >= timeout_timestamp)
1216 {
1217#if defined(OS_TRACE_RTOS_MQUEUE)
1218 trace::printf ("%s(%p,%u,%u,%u) ETIMEDOUT @%p %s\n", __func__,
1219 msg, nbytes, mprio, timeout, this, name ());
1220#endif
1221 return ETIMEDOUT;
1222 }
1223 }
1224
1225 /* NOTREACHED */
1226 return ENOTRECOVERABLE;
1227
1228#endif
1229 }

References os::rtos::interrupts::in_handler_mode(), os::rtos::thread::interrupted(), os::rtos::scheduler::locked(), os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, os::trace::printf(), os::rtos::port::scheduler::reschedule(), and os::rtos::this_thread::thread().

Referenced by os::rtos::message_queue_typed< T, Allocator >::timed_send(), and os::rtos::message_queue_inclusive< T, N >::timed_send().

◆ try_receive()

result_t os::rtos::message_queue::try_receive ( void *  msg,
std::size_t  nbytes,
priority_t mprio = nullptr 
)
Parameters
[out]msgThe address where to store the dequeued message.
[in]nbytesThe size of the destination buffer. Must be lower than the value used when creating the queue.
[out]mprioThe address where to store the message priority. The default is nullptr.
Return values
result::okThe message was received.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, is greater than the message size attribute of the message queue.
ENOTRECOVERABLEThe message could not be dequeued (extension to POSIX).
EBADMSGThe implementation has detected a data corruption problem with the message.
EWOULDBLOCKThe specified message queue is empty.

The try_receive() function shall try to receive the oldest of the highest priority message(s) from the message queue. If the size of the buffer in bytes, specified by the nbytes argument, is less than the msg_size_bytes attribute of the message queue, the function shall fail and return an error. Otherwise, the selected message shall be removed from the queue and copied to the buffer pointed to by the msg argument.

If the value of nbytes is greater than message_queue::max_size, the result is implementation-defined.

If the argument mprio is not nullptr, the priority of the selected message shall be stored in the location referenced by mprio.

If the message queue is empty, no message shall be removed from the queue, and try_receive() shall return an error.

POSIX compatibility
Inspired by mq_receive() with O_NONBLOCK set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Differences from the standard:
  • for consistency reasons, EWOULDBLOCK is used, instead of EAGAIN
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1383 of file os-mqueue.cpp.

1385 {
1386#if defined(OS_TRACE_RTOS_MQUEUE)
1387 trace::printf ("%s(%p,%u) @%p %s\n", __func__, msg, nbytes, this,
1388 name ());
1389#endif
1390
1391 os_assert_err (msg != nullptr, EINVAL);
1392 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
1393
1394#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1395
1396 return port::message_queue::try_receive (this, msg, nbytes, mprio);
1397
1398#else
1399
1400 // Don't call this from high priority interrupts.
1401 assert (port::interrupts::is_priority_valid ());
1402
1403 {
1404 // ----- Enter critical section ---------------------------------------
1405 interrupts::critical_section ics;
1406
1407 if (internal_try_receive_ (msg, nbytes, mprio))
1408 {
1409 return result::ok;
1410 }
1411 else
1412 {
1413 return EWOULDBLOCK;
1414 }
1415 // ----- Exit critical section ----------------------------------------
1416 }
1417
1418#endif
1419 }

References os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, and os::trace::printf().

Referenced by os::rtos::message_queue_typed< T, Allocator >::try_receive(), and os::rtos::message_queue_inclusive< T, N >::try_receive().

◆ try_send()

result_t os::rtos::message_queue::try_send ( const void *  msg,
std::size_t  nbytes,
priority_t  mprio = default_priority 
)
Parameters
[in]msgThe address of the message to enqueue.
[in]nbytesThe length of the message. Must be not higher than the value used when creating the queue.
[in]mprioThe message priority. The default is 0.
Return values
result::okThe message was enqueued.
EWOULDBLOCKThe specified message queue is full.
EINVALA parameter is invalid or outside of a permitted range.
EMSGSIZEThe specified message length, nbytes, exceeds the message size attribute of the message queue.
ENOTRECOVERABLEThe message could not be enqueue (extension to POSIX).

The try_send() function shall try to add the message pointed to by the argument msg to the message queue. The nbytes argument specifies the length of the message, in bytes, pointed to by msg. The value of nbytes shall be less than or equal to the msg_size_bytes parameter of the message queue object, or try_send() shall fail.

If the message queue is not full, try_send() shall behave as if the message is inserted into the message queue at the position indicated by the mprio argument. A message with a larger numeric value of mprio shall be inserted before messages with lower values of mprio. A message shall be inserted after other messages in the queue, if any, with equal mprio. The value of mprio shall be less than message_queue::max_priority.

If the message queue is full, the message shall not be queued and try_send() shall return an error.

POSIX compatibility
Inspired by mq_send() with O_NONBLOCK set, from <mqueue.h> (IEEE Std 1003.1, 2013 Edition).
Differences from the standard:
  • for consistency reasons, EWOULDBLOCK is used, instead of EAGAIN
Note
Can be invoked from Interrupt Service Routines.

Definition at line 1042 of file os-mqueue.cpp.

1044 {
1045#if defined(OS_TRACE_RTOS_MQUEUE)
1046 trace::printf ("%s(%p,%u,%u) @%p %s\n", __func__, msg, nbytes, mprio,
1047 this, name ());
1048#endif
1049
1050 os_assert_err (msg != nullptr, EINVAL);
1051 os_assert_err (nbytes <= msg_size_bytes_, EMSGSIZE);
1052
1053#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
1054
1055 return port::message_queue::try_send (this, msg, nbytes, mprio);
1056
1057#else
1058 // Don't call this from high priority interrupts.
1059 assert (port::interrupts::is_priority_valid ());
1060
1061 {
1062 // ----- Enter critical section ---------------------------------------
1063 interrupts::critical_section ics;
1064
1065 if (internal_try_send_ (msg, nbytes, mprio))
1066 {
1067 return result::ok;
1068 }
1069 else
1070 {
1071 return EWOULDBLOCK;
1072 }
1073 // ----- Exit critical section ----------------------------------------
1074 }
1075
1076#endif
1077 }

References os::rtos::internal::object_named::name(), os::rtos::result::ok, os_assert_err, and os::trace::printf().

Referenced by os::rtos::message_queue_typed< T, Allocator >::try_send(), and os::rtos::message_queue_inclusive< T, N >::try_send().


The documentation for this class was generated from the following files: