Xenomai API  2.6.5
Buffer services.
Collaboration diagram for Buffer services.:

Files

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

Functions

int rt_buffer_create (RT_BUFFER *bf, const char *name, size_t bufsz, int mode)
 Create a buffer. More...
 
int rt_buffer_delete (RT_BUFFER *bf)
 Delete a buffer. More...
 
ssize_t rt_buffer_write (RT_BUFFER *bf, const void *ptr, size_t len, RTIME timeout)
 Write to a buffer. More...
 
ssize_t rt_buffer_write_until (RT_BUFFER *bf, const void *ptr, size_t len, RTIME timeout)
 Write to a buffer (with absolute timeout date). More...
 
ssize_t rt_buffer_read (RT_BUFFER *bf, void *ptr, size_t len, RTIME timeout)
 Read from a buffer. More...
 
int rt_buffer_clear (RT_BUFFER *bf)
 Clear a buffer. More...
 
int rt_buffer_inquire (RT_BUFFER *bf, RT_BUFFER_INFO *info)
 Inquire about a buffer. More...
 
int rt_buffer_bind (RT_BUFFER *bf, const char *name, RTIME timeout)
 Bind to a buffer. More...
 
static int rt_buffer_unbind (RT_BUFFER *bf)
 Unbind from a buffer. More...
 

Detailed Description

Buffer services.

A buffer is a lightweight IPC object, implementing a fast, one-way Producer-Consumer data path. All messages written are buffered in a single memory area in strict FIFO order, until read either in blocking or non-blocking mode.

Message are always atomically handled on the write side (i.e. no interleave, no short writes), whilst only complete messages are normally returned to the read side. However, short reads may happen under a well-defined situation (see note in rt_buffer_read()), albeit they can be fully avoided by proper use of the buffer.

Function Documentation

int rt_buffer_bind ( RT_BUFFER *  bf,
const char *  name,
RTIME  timeout 
)

Bind to a buffer.

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

Parameters
nameA valid NULL-terminated name which identifies the buffer to bind to.
bfThe address of a buffer 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 bf 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).

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 nanosebfs otherwise.
int rt_buffer_clear ( RT_BUFFER *  bf)

Clear a buffer.

Empties a buffer from any data.

Parameters
bfThe descriptor address of the cleared buffer.
Returns
0 is returned upon success. Otherwise:
  • -EINVAL is returned if bf is not a buffer descriptor.
  • -EIDRM is returned if bf is a deleted buffer descriptor.

Environments:

This service can be called from:

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

Rescheduling: possible, as a consequence of resuming tasks that wait for buffer space in rt_buffer_write().

References xnpod_schedule(), and xnsynch_flush().

int rt_buffer_create ( RT_BUFFER *  bf,
const char *  name,
size_t  bufsz,
int  mode 
)

Create a buffer.

Create a synchronization object that allows tasks to send and receive data asynchronously via a memory buffer. Data may be of an arbitrary length, albeit this IPC is best suited for small to medium-sized messages, since data always have to be copied to the buffer during transit. Large messages may be more efficiently handled by message queues (RT_QUEUE) via rt_queue_send()/rt_queue_receive() services.

Parameters
bfThe address of a buffer descriptor Xenomai will use to store the buffer-related data. This descriptor must always be valid while the buffer is active therefore it must be allocated in permanent memory.
nameAn ASCII string standing for the symbolic name of the buffer. 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 buffer.
bufszThe size of the buffer space available to hold data. The required memory is obtained from the system heap.
modeThe buffer creation mode. The following flags can be OR'ed into this bitmask, each of them affecting the new buffer:
  • B_FIFO makes tasks pend in FIFO order for reading data from the buffer.
  • B_PRIO makes tasks pend in priority order for reading data from the buffer.

This parameter also applies to tasks blocked on the buffer's output queue (see rt_buffer_write()).

Returns
0 is returned upon success. Otherwise:
  • -ENOMEM is returned if the system fails to get enough dynamic memory from the global real-time heap in order to register the buffer.
  • -EEXIST is returned if the name is already in use by some registered object.
  • -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.

References rt_buffer_delete(), xnregistry_enter(), and xnsynch_init().

int rt_buffer_delete ( RT_BUFFER *  bf)

Delete a buffer.

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

Parameters
bfThe descriptor address of the buffer to delete.
Returns
0 is returned upon success. Otherwise:
  • -EINVAL is returned if bf is not a buffer descriptor.
  • -EIDRM is returned if bf is a deleted buffer 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.

References xnpod_schedule(), and xnregistry_remove().

Referenced by rt_buffer_create().

int rt_buffer_inquire ( RT_BUFFER *  bf,
RT_BUFFER_INFO *  info 
)

Inquire about a buffer.

Return various information about the status of a given buffer.

Parameters
bfThe descriptor address of the inquired buffer.
infoThe address of a structure the buffer 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 bf is not a buffer descriptor.
  • -EIDRM is returned if bf is a deleted buffer 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_buffer_read ( RT_BUFFER *  bf,
void *  ptr,
size_t  len,
RTIME  timeout 
)

Read from a buffer.

Reads the next message from the specified buffer. If no message is available on entry, the caller is allowed to block until enough data is written to the buffer.

Parameters
bfThe descriptor address of the buffer to read from.
ptrA pointer to a memory area which will be written upon success with the received data.
lenThe length in bytes of the memory area pointed to by ptr. Under normal circumstances, rt_buffer_read() only returns entire messages as specified by the len argument, or an error value. However, short reads are allowed when a potential deadlock situation is detected (see note below).
timeoutThe number of clock ticks to wait for a message to be available from the buffer (see note). Passing TM_INFINITE causes the caller to block indefinitely until enough data is available. Passing TM_NONBLOCK causes the service to return immediately without blocking in case not enough data is available.
Returns
The number of bytes read from the buffer is returned upon success. Otherwise:
  • -ETIMEDOUT is returned if timeout is different from TM_NONBLOCK and not enough data is available within the specified amount of time to form a complete message.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and not enough data is immediately available on entry to form a complete message.
  • -EINTR is returned if rt_task_unblock() has been called for the reading task before enough data became available to form a complete message.
  • -EINVAL is returned if bf is not a buffer descriptor, or len is greater than the actual buffer length.
  • -EIDRM is returned if bf is a deleted buffer descriptor.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).
  • -ENOMEM is returned if not enough memory is available from the system heap to hold a temporary copy of the message (user-space call only).
Note
A short read (i.e. fewer bytes returned than requested by len) may happen whenever a pathological use of the buffer is encountered. This condition only arises when the system detects that one or more writers are waiting for sending data, while a reader would have to wait for receiving a complete message at the same time. For instance, consider the following sequence, involving a 1024-byte buffer (bf) and two threads:

writer thread > rt_write_buffer(&bf, ptr, 1, TM_INFINITE); (one byte to read, 1023 bytes available for sending) writer thread > rt_write_buffer(&bf, ptr, 1024, TM_INFINITE); (writer blocks - no space for another 1024-byte message) reader thread > rt_read_buffer(&bf, ptr, 1024, TM_INFINITE); (short read - a truncated (1-byte) message is returned)

In order to prevent both threads to wait for each other indefinitely, a short read is allowed, which may be completed by a subsequent call to rt_buffer_read() or rt_buffer_read_until(). If that case arises, thread priorities, buffer and/or message lengths should likely be fixed, in order to eliminate such condition.

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine (non-blocking call only)
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied and no task is waiting for buffer space to be released for the same buffer (see rt_buffer_write()), 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 xnbufd_map_kwrite(), and xnbufd_unmap_kwrite().

int rt_buffer_unbind ( RT_BUFFER *  bf)
inlinestatic

Unbind from a buffer.

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

Parameters
bfThe address of a buffer descriptor to unbind from.
Returns
0 is always returned.

This service can be called from:

  • User-space task.

Rescheduling: never.

ssize_t rt_buffer_write ( RT_BUFFER *  bf,
const void *  ptr,
size_t  len,
RTIME  timeout 
)

Write to a buffer.

Writes a message to the specified buffer. If not enough buffer space is available on entry to hold the message, the caller is allowed to block until enough room is freed. Data written by rt_buffer_write() calls can be read in FIFO order by subsequent rt_buffer_read() calls. Messages sent via rt_buffer_write() are handled atomically (no interleave, no short writes).

Parameters
bfThe descriptor address of the buffer to write to.
ptrThe address of the message data to be written to the buffer.
lenThe length in bytes of the message data. Zero is a valid value, in which case the buffer is left untouched, and zero is returned to the caller. No partial message is ever sent.
timeoutThe number of clock ticks to wait for enough buffer space to be available to hold the message (see note). Passing TM_INFINITE causes the caller to block indefinitely until enough buffer space is available. Passing TM_NONBLOCK causes the service to return immediately without blocking in case of buffer space shortage.
Returns
The number of bytes written to the buffer is returned upon success. Otherwise:
  • -ETIMEDOUT is returned if timeout is different from TM_NONBLOCK and no buffer space is available within the specified amount of time to hold the message.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no buffer space is immediately available on entry to hold the message.
  • -EINTR is returned if rt_task_unblock() has been called for the writing task before enough buffer space became available to hold the message.
  • -EINVAL is returned if bf is not a buffer descriptor, or len is greater than the actual buffer length.
  • -EIDRM is returned if bf is a deleted buffer descriptor.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).
  • -ENOMEM is returned if not enough memory is available from the system heap to hold a temporary copy of the message (user-space call only).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine (non-blocking call only)
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied and no task is waiting for messages on the same buffer, 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 xnbufd_map_kread(), and xnbufd_unmap_kread().

ssize_t rt_buffer_write_until ( RT_BUFFER *  bf,
const void *  ptr,
size_t  len,
RTIME  timeout 
)

Write to a buffer (with absolute timeout date).

Writes a message to the specified buffer. If not enough buffer space is available on entry to hold the message, the caller is allowed to block until enough room is freed, or a timeout elapses.

Parameters
bfThe descriptor address of the buffer to write to.
ptrThe address of the message data to be written to the buffer.
lenThe length in bytes of the message data. Zero is a valid value, in which case the buffer is left untouched, and zero is returned to the caller.
timeoutThe absolute date specifying a time limit to wait for enough buffer space to be available to hold the message (see note). Passing TM_INFINITE causes the caller to block indefinitely until enough buffer space is available. Passing TM_NONBLOCK causes the service to return immediately without blocking in case of buffer space shortage.
Returns
The number of bytes written to the buffer is returned upon success. Otherwise:
  • -ETIMEDOUT is returned if the absolute timeout date is reached before enough buffer space is available to hold the message.
  • -EWOULDBLOCK is returned if timeout is equal to TM_NONBLOCK and no buffer space is immediately available on entry to hold the message.
  • -EINTR is returned if rt_task_unblock() has been called for the writing task before enough buffer space became available to hold the message.
  • -EINVAL is returned if bf is not a buffer descriptor, or len is greater than the actual buffer length.
  • -EIDRM is returned if bf is a deleted buffer descriptor.
  • -EPERM is returned if this service should block, but was called from a context which cannot sleep (e.g. interrupt, non-realtime context).
  • -ENOMEM is returned if not enough memory is available from the system heap to hold a temporary copy of the message (user-space call only).

Environments:

This service can be called from:

  • Kernel module initialization/cleanup code
  • Interrupt service routine (non-blocking call only)
  • Kernel-based task
  • User-space task (switches to primary mode)

Rescheduling: always unless the request is immediately satisfied and no task is waiting for messages on the same buffer, 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 xnbufd_map_kread(), and xnbufd_unmap_kread().