Xenomai API  2.6.5
Message queue services.
Collaboration diagram for Message queue services.:

Files

file  queue.c
 This file is part of the Xenomai project.
 

Functions

int rt_queue_create (RT_QUEUE *q, const char *name, size_t poolsize, size_t qlimit, int mode)
 Create a message queue. More...
 
int rt_queue_delete (RT_QUEUE *q)
 Delete a message queue. More...
 
void * rt_queue_alloc (RT_QUEUE *q, size_t size)
 Allocate a message queue buffer. More...
 
int rt_queue_free (RT_QUEUE *q, void *buf)
 Free a message queue buffer. More...
 
int rt_queue_send (RT_QUEUE *q, void *mbuf, size_t size, int mode)
 Send a message to a queue. More...
 
int rt_queue_write (RT_QUEUE *q, const void *buf, size_t size, int mode)
 Write a message to a queue. More...
 
ssize_t rt_queue_receive (RT_QUEUE *q, void **bufp, RTIME timeout)
 Receive a message from a queue. More...
 
ssize_t rt_queue_receive_until (RT_QUEUE *q, void **bufp, RTIME timeout)
 Receive a message from a queue (with absolute timeout date). More...
 
ssize_t rt_queue_read (RT_QUEUE *q, void *buf, size_t size, RTIME timeout)
 Read a message from a queue. More...
 
ssize_t rt_queue_read_until (RT_QUEUE *q, void *buf, size_t size, RTIME timeout)
 Read a message from a queue (with absolute timeout date). More...
 
int rt_queue_flush (RT_QUEUE *q)
 Flush a message queue. More...
 
int rt_queue_inquire (RT_QUEUE *q, RT_QUEUE_INFO *info)
 Inquire about a message queue. More...
 
int rt_queue_bind (RT_QUEUE *q, const char *name, RTIME timeout)
 Bind to a shared message queue. More...
 
int rt_queue_unbind (RT_QUEUE *q)
 Unbind from a shared message queue. More...
 

Detailed Description

Queue services.

Message queueing is a method by which real-time tasks can exchange or pass data through a Xenomai-managed queue of messages. Messages can vary in length and be assigned different types or usages. A message queue can be created by one task and used by multiple tasks that send and/or receive messages to the queue.

This implementation is based on a zero-copy scheme for message buffers. Message buffer pools are built over the nucleus's heap objects, which in turn provide the needed support for exchanging messages between kernel and user-space using direct memory mapping.

Function Documentation

void* rt_queue_alloc ( RT_QUEUE *  q,
size_t  size 
)

Allocate a message queue buffer.

This service allocates a message buffer from the queue's internal pool which can be subsequently filled by the caller then passed to rt_queue_send() for sending.

Parameters
qThe descriptor address of the affected queue.
sizeThe requested size in bytes of the buffer. Zero is an acceptable value, meaning that the message will not carry any payload data; the receiver will thus receive a zero-sized message.
Returns
The address of the allocated message buffer upon success, or NULL if the allocation fails.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: never.

References xnheap_alloc().

Referenced by rt_queue_write().

int rt_queue_bind ( RT_QUEUE *  q,
const char *  name,
RTIME  timeout 
)

Bind to a shared message queue.

This user-space only service retrieves the uniform descriptor of a given shared Xenomai message queue identified by its symbolic name. If the queue does not exist on entry, this service blocks the caller until a queue of the given name is created.

Parameters
nameA valid NULL-terminated name which identifies the queue to bind to.
qThe address of a queue descriptor retrieved by the operation. Contents of this memory is undefined upon failure.
timeoutThe number of clock ticks to wait for the registration to occur (see note). Passing TM_INFINITE causes the caller to block indefinitely until the object is registered. Passing TM_NONBLOCK causes the service to return immediately without waiting if the object is not registered on entry.
Returns
0 is returned upon success. Otherwise:
  • -EFAULT is returned if q or name is referencing invalid memory.
  • -EINTR is returned if rt_task_unblock() has been called for the waiting task before the retrieval has completed.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and the searched object is not registered on entry.
  • -ETIMEDOUT is returned if the object cannot be retrieved within the specified amount of time.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context). This error may also be returned whenever the call attempts to bind from a user-space application to a local queue defined from kernel space (i.e. Q_SHARED was not passed to rt_queue_create()).
  • -ENOENT is returned if the special file /dev/rtheap (character-mode, major 10, minor 254) is not available from the filesystem. This device is needed to map the memory pool used by the shared queue into the caller's address space. udev-based systems should not need manual creation of such device entry.

Environments:

This service can be called from:

  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied or timeout specifies a non-blocking operation.

Note
The timeout value will be interpreted as jiffies if the native skin is bound to a periodic time base (see CONFIG_XENO_OPT_NATIVE_PERIOD), or nanoseconds otherwise.
Examples:
msg_queue.c.
int rt_queue_create ( RT_QUEUE *  q,
const char *  name,
size_t  poolsize,
size_t  qlimit,
int  mode 
)

Create a message queue.

Create a message queue object that allows multiple tasks to exchange data through the use of variable-sized messages. A message queue is created empty. Message queues can be local to the kernel space, or shared between kernel and user-space.

This service needs the special character device /dev/rtheap (10,254) when called from user-space tasks.

Parameters
qThe address of a queue descriptor Xenomai will use to store the queue-related data. This descriptor must always be valid while the message queue is active therefore it must be allocated in permanent memory.
nameAn ASCII string standing for the symbolic name of the queue. When non-NULL and non-empty, this string is copied to a safe place into the descriptor, and passed to the registry package if enabled for indexing the created queue. Shared queues must be given a valid name.
poolsizeThe size (in bytes) of the message buffer pool which is going to be pre-allocated to the queue. Message buffers will be claimed and released to this pool. The buffer pool memory is not extensible, so this value must be compatible with the highest message pressure that could be expected.
qlimitThis parameter allows to limit the maximum number of messages which can be queued at any point in time. Sending to a full queue begets an error. The special value Q_UNLIMITED can be passed to specify an unlimited amount.
modeThe queue creation mode. The following flags can be OR'ed into this bitmask, each of them affecting the new queue:
  • Q_FIFO makes tasks pend in FIFO order on the queue for consuming messages.
  • Q_PRIO makes tasks pend in priority order on the queue.
  • Q_SHARED causes the queue to be sharable between kernel and user-space tasks. Otherwise, the new queue is only available for kernel-based usage. This flag is implicitly set when the caller is running in user-space. This feature requires the real-time support in user-space to be configured in (CONFIG_XENO_OPT_PERVASIVE).
  • Q_DMA causes the buffer pool associated to the queue to be allocated in physically contiguous memory, suitable for DMA operations with I/O devices. A 128Kb limit exists for poolsize when this flag is passed.
Returns
0 is returned upon success. Otherwise:
  • -EEXIST is returned if the name is already in use by some registered object.
  • -EINVAL is returned if poolsize is null, greater than the system limit, or name is null or empty for a shared queue.
  • -ENOMEM is returned if not enough system memory is available to create or register the queue. Additionally, and if Q_SHARED has been passed in mode, errors while mapping the buffer pool in the caller's address space might beget this return code too.
  • -EPERM is returned if this service was called from an invalid context.
  • -ENOSYS is returned if mode specifies Q_SHARED, but the real-time support in user-space is unavailable.
  • -ENOENT is returned if /dev/rtheap can't be opened.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • User-space task (switches to secondary mode)

Rescheduling: possible.

References rt_queue_delete(), xnheap_init(), xnheap_set_label(), xnregistry_enter(), and xnsynch_init().

int rt_queue_delete ( RT_QUEUE *  q)

Delete a message queue.

Destroy a message queue and release all the tasks currently pending on it. A queue exists in the system since rt_queue_create() has been called to create it, so this service must be called in order to destroy it afterwards.

Parameters
qThe descriptor address of the affected queue.
Returns
0 is returned upon success. Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -EPERM is returned if this service was called from an asynchronous context.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • User-space task (switches to secondary mode).

Rescheduling: possible.

Referenced by rt_queue_create().

int rt_queue_flush ( RT_QUEUE *  q)

Flush a message queue.

This service discards all unread messages from a message queue.

Parameters
qThe descriptor address of the affected queue.
Returns
The number of messages flushed is returned upon success. Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: never.

References rt_queue_free().

int rt_queue_free ( RT_QUEUE *  q,
void *  buf 
)

Free a message queue buffer.

This service releases a message buffer returned by rt_queue_receive() to the queue's internal pool.

Parameters
qThe descriptor address of the affected queue.
bufThe address of the message buffer to free. Even zero-sized messages carrying no payload data must be freed, since they are assigned a valid memory space to store internal information.
Returns
0 is returned upon success, or -EINVAL if buf is not a valid message buffer previously allocated by the rt_queue_alloc() service, or the caller did not get ownership of the message through a successful return from rt_queue_receive().

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: never.

References xnheap_test_and_free().

Referenced by rt_queue_flush().

int rt_queue_inquire ( RT_QUEUE *  q,
RT_QUEUE_INFO *  info 
)

Inquire about a message queue.

Return various information about the status of a given queue.

Parameters
qThe descriptor address of the inquired queue.
infoThe address of a structure the queue information will be written to.
Returns
0 is returned and status information is written to the structure pointed at by info upon success. Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: never.

ssize_t rt_queue_read ( RT_QUEUE *  q,
void *  buf,
size_t  size,
RTIME  timeout 
)

Read a message from a queue.

This service retrieves the next message available from the given queue. Unless otherwise specified, the caller is blocked for a given amount of time if no message is immediately available on entry. This services differs from rt_queue_receive() in that it copies back the payload data to a user-defined memory area, instead of returning a pointer to the message buffer holding such data.

Parameters
qThe descriptor address of the message queue to read from.
bufA pointer to a memory area which will be written upon success with the message contents. The internal message buffer conveying the data is automatically freed by this call.
sizeThe length in bytes of the memory area pointed to by buf. Messages larger than size are truncated appropriately.
timeoutThe number of clock ticks to wait for a message to arrive (see note). Passing TM_INFINITE causes the caller to block indefinitely until some message is eventually available. Passing TM_NONBLOCK causes the service to return immediately without waiting if no message is available on entry.
Returns
The number of bytes available from the received message is returned upon success, which might be greater than the actual number of bytes copied to the destination buffer if the message has been truncated. Zero is a possible value corresponding to a zero-sized message passed to rt_queue_send() or rt_queue_write(). Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ETIMEDOUT is returned if timeout is different from TM_NONBLOCK and no message is available within the specified amount of time.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no message is immediately available on entry.
  • -EINTR is returned if rt_task_unblock() has been called for the waiting task before any data was available.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine only if timeout is equal to TM_NONBLOCK.
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied or timeout specifies a non-blocking operation.

Note
The timeout value will be interpreted as jiffies if the native skin is bound to a periodic time base (see CONFIG_XENO_OPT_NATIVE_PERIOD), or nanoseconds otherwise.

References pthread_setcanceltype().

ssize_t rt_queue_read_until ( RT_QUEUE *  q,
void *  buf,
size_t  size,
RTIME  timeout 
)

Read a message from a queue (with absolute timeout date).

This service retrieves the next message available from the given queue. Unless otherwise specified, the caller is blocked for a given amount of time if no message is immediately available on entry. This services differs from rt_queue_receive() in that it copies back the payload data to a user-defined memory area, instead of returning a pointer to the message buffer holding such data.

Parameters
qThe descriptor address of the message queue to read from.
bufA pointer to a memory area which will be written upon success with the message contents. The internal message buffer conveying the data is automatically freed by this call.
sizeThe length in bytes of the memory area pointed to by buf. Messages larger than size are truncated appropriately.
timeoutThe absolute date specifying a time limit to wait for a message to arrive (see note). Passing TM_INFINITE causes the caller to block indefinitely until some message is eventually available. Passing TM_NONBLOCK causes the service to return immediately without waiting if no message is available on entry.
Returns
The number of bytes available from the received message is returned upon success, which might be greater than the actual number of bytes copied to the destination buffer if the message has been truncated. Zero is a possible value corresponding to a zero-sized message passed to rt_queue_send() or rt_queue_write(). Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ETIMEDOUT is returned if the absolute timeout date is reached before a message arrives.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no message is immediately available on entry.
  • -EINTR is returned if rt_task_unblock() has been called for the waiting task before any data was available.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine only if timeout is equal to TM_NONBLOCK.
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied or timeout specifies a non-blocking operation.

Note
The timeout value will be interpreted as jiffies if the native skin is bound to a periodic time base (see CONFIG_XENO_OPT_NATIVE_PERIOD), or nanoseconds otherwise.

References pthread_setcanceltype().

ssize_t rt_queue_receive ( RT_QUEUE *  q,
void **  bufp,
RTIME  timeout 
)

Receive a message from a queue.

This service retrieves the next message available from the given queue. Unless otherwise specified, the caller is blocked for a given amount of time if no message is immediately available on entry.

Parameters
qThe descriptor address of the message queue to receive from.
bufpA pointer to a memory location which will be written upon success with the address of the received message. Once consumed, the message space should be freed using rt_queue_free().
timeoutThe number of clock ticks to wait for a message to arrive (see note). Passing TM_INFINITE causes the caller to block indefinitely until some message is eventually available. Passing TM_NONBLOCK causes the service to return immediately without waiting if no message is available on entry.
Returns
The number of bytes available from the received message is returned upon success. Zero is a possible value corresponding to a zero-sized message passed to rt_queue_send(). Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ETIMEDOUT is returned if timeout is different from TM_NONBLOCK and no message is available within the specified amount of time.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no message is immediately available on entry.
  • -EINTR is returned if rt_task_unblock() has been called for the waiting task before any data was available.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine only if timeout is equal to TM_NONBLOCK.
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied or timeout specifies a non-blocking operation.

Note
The timeout value will be interpreted as jiffies if the native skin is bound to a periodic time base (see CONFIG_XENO_OPT_NATIVE_PERIOD), or nanoseconds otherwise.

References pthread_setcanceltype().

ssize_t rt_queue_receive_until ( RT_QUEUE *  q,
void **  bufp,
RTIME  timeout 
)

Receive a message from a queue (with absolute timeout date).

This service retrieves the next message available from the given queue. Unless otherwise specified, the caller is blocked for a given amount of time if no message is immediately available on entry.

Parameters
qThe descriptor address of the message queue to receive from.
bufpA pointer to a memory location which will be written upon success with the address of the received message. Once consumed, the message space should be freed using rt_queue_free().
timeoutThe absolute date specifying a time limit to wait for a message to arrive (see note). Passing TM_INFINITE causes the caller to block indefinitely until some message is eventually available. Passing TM_NONBLOCK causes the service to return immediately without waiting if no message is available on entry.
Returns
The number of bytes available from the received message is returned upon success. Zero is a possible value corresponding to a zero-sized message passed to rt_queue_send(). Otherwise:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ETIMEDOUT is returned if the absolute timeout date is reached before a message arrives.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no message is immediately available on entry.
  • -EINTR is returned if rt_task_unblock() has been called for the waiting task before any data was available.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine only if timeout is equal to TM_NONBLOCK.
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied or timeout specifies a non-blocking operation.

Note
The timeout value will be interpreted as jiffies if the native skin is bound to a periodic time base (see CONFIG_XENO_OPT_NATIVE_PERIOD), or nanoseconds otherwise.

References pthread_setcanceltype().

int rt_queue_send ( RT_QUEUE *  q,
void *  mbuf,
size_t  size,
int  mode 
)

Send a message to a queue.

This service sends a complete message to a given queue. The message must have been allocated by a previous call to rt_queue_alloc().

Parameters
qThe descriptor address of the message queue to send to.
mbufThe address of the message buffer to be sent. The message buffer must have been allocated using the rt_queue_alloc() service. Once passed to rt_queue_send(), the memory pointed to by mbuf is no more under the control of the sender and thus should not be referenced by it anymore; deallocation of this memory must be handled on the receiving side.
sizeThe size in bytes of the message. Zero is a valid value, in which case an empty message will be sent.
modeA set of flags affecting the operation:
  • Q_URGENT causes the message to be prepended to the message queue, ensuring a LIFO ordering.
  • Q_NORMAL causes the message to be appended to the message queue, ensuring a FIFO ordering.
  • Q_BROADCAST causes the message to be sent to all tasks currently waiting for messages. The message is not copied; a reference count is maintained instead so that the message will remain valid until the last receiver releases its own reference using rt_queue_free(), after which the message space will be returned to the queue's internal pool.
Returns
Upon success, this service returns the number of receivers which got awaken as a result of the operation. If zero is returned, no task was waiting on the receiving side of the queue, and the message has been enqueued. Upon error, one of the following error codes is returned:
  • -EINVAL is returned if q is not a message queue descriptor, or mbuf is not a valid message buffer obtained from a previous call to rt_queue_alloc().
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ENOMEM is returned if queuing the message would exceed the limit defined for the queue at creation.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: possible.

References pthread_setcanceltype(), xnpod_schedule(), and xnsynch_wakeup_one_sleeper().

Referenced by rt_queue_write().

int rt_queue_unbind ( RT_QUEUE *  q)

Unbind from a shared message queue.

This user-space only service unbinds the calling task from the message queue object previously retrieved by a call to rt_queue_bind().

Unbinding from a message queue when it is no more needed is especially important in order to properly release the mapping resources used to attach the shared queue memory to the caller's address space.

Parameters
qThe address of a queue descriptor to unbind from.
Returns
0 is returned upon success. Otherwise:
  • -EINVAL is returned if q is invalid or not bound.

This service can be called from:

  • User-space task.

Rescheduling: never.

Examples:
msg_queue.c.
int rt_queue_write ( RT_QUEUE *  q,
const void *  buf,
size_t  size,
int  mode 
)

Write a message to a queue.

This service writes a complete message to a given queue. This service differs from rt_queue_send() in that it accepts a pointer to the raw data to be sent, instead of a canned message buffer.

Parameters
qThe descriptor address of the message queue to write to.
bufThe address of the message data to be written to the queue. A message buffer will be allocated internally to convey the data.
sizeThe size in bytes of the message data. Zero is a valid value, in which case an empty message will be sent.
modeA set of flags affecting the operation:
  • Q_URGENT causes the message to be prepended to the message queue, ensuring a LIFO ordering.
  • Q_NORMAL causes the message to be appended to the message queue, ensuring a FIFO ordering.
  • Q_BROADCAST causes the message to be sent to all tasks currently waiting for messages. The message is not copied; a reference count is maintained instead so that the message will remain valid until all receivers get a copy of the message, after which the message space will be returned to the queue's internal pool.
Returns
Upon success, this service returns the number of receivers which got awaken as a result of the operation. If zero is returned, no task was waiting on the receiving side of the queue, and the message has been enqueued. Upon error, one of the following error codes is returned:
  • -EINVAL is returned if q is not a message queue descriptor.
  • -EIDRM is returned if q is a deleted queue descriptor.
  • -ENOMEM is returned if queuing the message would exceed the limit defined for the queue at creation, or if no memory can be obtained to convey the message data internally.
  • -ESRCH is returned if a q represents a stale userland handle

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task

Rescheduling: possible.

References pthread_setcanceltype(), rt_queue_alloc(), and rt_queue_send().