Loading...
Searching...
No Matches
ringbuf.h
Go to the documentation of this file.
/*
* (c) 2010 Björn Döbel <doebel@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#pragma once
#include <l4/shmc/shmc.h>
#include <l4/util/assert.h>
#include <l4/sys/compiler.h>
#include <l4/sys/thread.h>
L4_BEGIN_DECLS
/*
* Turn on ringbuf poisoning. This will add magic values to the ringbuf
* header as well as each packet header and check that these values are
* valid all the time.
*/
#define L4SHMC_RINGBUF_POISONING 1
typedef struct
{
volatile l4_uint32_t lock;
unsigned data_size;
#if L4SHMC_RINGBUF_POISONING
char magic1;
#endif
unsigned next_read;
unsigned next_write;
#if L4SHMC_RINGBUF_POISONING
char magic2;
#endif
unsigned bytes_filled;
unsigned sender_waits;
#if L4SHMC_RINGBUF_POISONING
char magic3;
#endif
char data[];
} l4shmc_ringbuf_head_t;
typedef struct
{
l4shmc_area_t *_area;
l4_cap_idx_t _owner;
l4shmc_chunk_t _chunk;
unsigned _size;
char *_chunkname;
char *_signame;
l4shmc_ringbuf_head_t *_addr;
l4shmc_signal_t _signal_full;
l4shmc_signal_t _signal_empty;
} l4shmc_ringbuf_t;
#define L4SHMC_RINGBUF_HEAD(ringbuf) ((l4shmc_ringbuf_head_t*)((ringbuf)->_addr))
#define L4SHMC_RINGBUF_DATA(ringbuf) (L4SHMC_RINGBUF_HEAD(ringbuf)->data)
#define L4SHMC_RINGBUF_DATA_SIZE(ringbuf) ((ringbuf)->_size - sizeof(l4shmc_ringbuf_head_t))
enum lock_content
{
lock_cont_min = 4,
locked = 5,
unlocked = 6,
lock_cont_max = 7,
};
static L4_CV inline void l4shmc_rb_lock(l4shmc_ringbuf_head_t *head)
{
ASSERT_NOT_NULL(head);
ASSERT_ASSERT(head->lock > lock_cont_min);
ASSERT_ASSERT(head->lock < lock_cont_max);
while (!l4util_cmpxchg32(&head->lock, unlocked, locked))
l4_thread_yield();
}
static L4_CV inline void l4shmc_rb_unlock(l4shmc_ringbuf_head_t *head)
{
ASSERT_NOT_NULL(head);
ASSERT_ASSERT(head->lock > lock_cont_min);
ASSERT_ASSERT(head->lock < lock_cont_max);
head->lock = unlocked;
}
/******************
* Initialization *
******************/
L4_CV int l4shmc_rb_init_buffer(l4shmc_ringbuf_t *buf, l4shmc_area_t *area,
char const *chunk_name,
char const *signal_name, unsigned size);
L4_CV void l4shmc_rb_deinit_buffer(l4shmc_ringbuf_t *buf);
/***************************
* RINGBUF SENDER *
***************************/
L4_CV int l4shmc_rb_attach_sender(l4shmc_ringbuf_t *buf, char const *signal_name,
l4_cap_idx_t owner);
L4_CV char *l4shmc_rb_sender_alloc_packet(l4shmc_ringbuf_head_t *head,
unsigned psize);
L4_CV void l4shmc_rb_sender_put_data(l4shmc_ringbuf_t *buf, char *addr,
char *data, unsigned dsize);
L4_CV int l4shmc_rb_sender_next_copy_in(l4shmc_ringbuf_t *buf, char *data,
unsigned size, int block_if_necessary);
L4_CV void l4shmc_rb_sender_commit_packet(l4shmc_ringbuf_t *buf);
/***************************
* RINGBUF RECEIVER *
***************************/
L4_CV int l4shmc_rb_init_receiver(l4shmc_ringbuf_t *buf, l4shmc_area_t *area,
char const *chunk_name,
char const *signal_name);
L4_CV void l4shmc_rb_attach_receiver(l4shmc_ringbuf_t *buf, l4_cap_idx_t owner);
L4_CV int l4shmc_rb_receiver_wait_for_data(l4shmc_ringbuf_t *buf, int blocking);
L4_CV int l4shmc_rb_receiver_copy_out(l4shmc_ringbuf_head_t *head, char *target,
unsigned *tsize);
L4_CV void l4shmc_rb_receiver_notify_done(l4shmc_ringbuf_t *buf);
L4_CV int l4shmc_rb_receiver_read_next_size(l4shmc_ringbuf_head_t *head);
L4_END_DECLS
compiler.h
L4 compiler related defines.
l4_uint32_t
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:29
l4_cap_idx_t
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:336
l4_thread_yield
l4_msgtag_t l4_thread_yield(void) L4_NOTHROW
Yield current time slice.
Definition thread.h:891
L4_CV
#define L4_CV
Define calling convention.
Definition linkage.h:33
L4_BEGIN_DECLS
#define L4_BEGIN_DECLS
Start section with C types and functions.
Definition compiler.h:165
L4_END_DECLS
#define L4_END_DECLS
End section with C types and functions.
Definition compiler.h:166
l4util_cmpxchg32
int l4util_cmpxchg32(volatile l4_uint32_t *dest, l4_uint32_t cmp_val, l4_uint32_t new_val)
Atomic compare and exchange (32 bit version).
Definition atomic.h:355
thread.h
Common thread related definitions.
l4shmc_rb_sender_commit_packet
void l4shmc_rb_sender_commit_packet(l4shmc_ringbuf_t *buf)
Tell the consumer that new data is available.
l4shmc_rb_sender_alloc_packet
char * l4shmc_rb_sender_alloc_packet(l4shmc_ringbuf_head_t *head, unsigned psize)
Allocate a packet of a given size within the ring buffer.
l4shmc_rb_attach_sender
int l4shmc_rb_attach_sender(l4shmc_ringbuf_t *buf, char const *signal_name, l4_cap_idx_t owner)
Attach to sender signal of a ring buffer.
l4shmc_rb_attach_receiver
void l4shmc_rb_attach_receiver(l4shmc_ringbuf_t *buf, l4_cap_idx_t owner)
Attach to receiver signal of a ring buffer.
l4shmc_rb_receiver_copy_out
int l4shmc_rb_receiver_copy_out(l4shmc_ringbuf_head_t *head, char *target, unsigned *tsize)
Copy data out of the buffer.
l4shmc_rb_deinit_buffer
void l4shmc_rb_deinit_buffer(l4shmc_ringbuf_t *buf)
De-init a ring buffer.
l4shmc_rb_init_receiver
int l4shmc_rb_init_receiver(l4shmc_ringbuf_t *buf, l4shmc_area_t *area, char const *chunk_name, char const *signal_name)
Initialize receive buffer.
l4shmc_rb_receiver_wait_for_data
int l4shmc_rb_receiver_wait_for_data(l4shmc_ringbuf_t *buf, int blocking)
Check if (and optionally block until) new data is ready.
l4shmc_rb_init_buffer
int l4shmc_rb_init_buffer(l4shmc_ringbuf_t *buf, l4shmc_area_t *area, char const *chunk_name, char const *signal_name, unsigned size)
Initialize a ring buffer by creating an SHMC chunk and the corresponding signals.
l4shmc_rb_receiver_read_next_size
int l4shmc_rb_receiver_read_next_size(l4shmc_ringbuf_head_t *head)
Have a look at the ring buffer and see which size the next packet to be read has.
l4shmc_rb_sender_next_copy_in
int l4shmc_rb_sender_next_copy_in(l4shmc_ringbuf_t *buf, char *data, unsigned size, int block_if_necessary)
Copy in packet from an external data source.
l4shmc_rb_receiver_notify_done
void l4shmc_rb_receiver_notify_done(l4shmc_ringbuf_t *buf)
Notify producer that space is available.
l4shmc_rb_sender_put_data
void l4shmc_rb_sender_put_data(l4shmc_ringbuf_t *buf, char *addr, char *data, unsigned dsize)
Copy data into a previously allocated packet.
shmc.h
Shared memory library header file.
l4shmc_ringbuf_head_t
Head field of a ring buffer.
Definition ringbuf.h:60
l4shmc_ringbuf_head_t::sender_waits
unsigned sender_waits
sender waiting?
Definition ringbuf.h:72
l4shmc_ringbuf_head_t::next_read
unsigned next_read
offset to next read packet
Definition ringbuf.h:66
l4shmc_ringbuf_head_t::next_write
unsigned next_write
offset to next write packet
Definition ringbuf.h:67
l4shmc_ringbuf_head_t::data
char data[]
tail pointer -> data
Definition ringbuf.h:76
l4shmc_ringbuf_head_t::bytes_filled
unsigned bytes_filled
bytes filled in buffer
Definition ringbuf.h:71
l4shmc_ringbuf_t
Ring buffer.
Definition ringbuf.h:86
l4shmc_ringbuf_t::_signame
char * _signame
base name of the ring buffer signals
Definition ringbuf.h:92
l4shmc_ringbuf_t::_area
l4shmc_area_t * _area
L4SHM area this buffer is located in.
Definition ringbuf.h:87
l4shmc_ringbuf_t::_chunk
l4shmc_chunk_t _chunk
chunk descriptor
Definition ringbuf.h:89
l4shmc_ringbuf_t::_signal_full
l4shmc_signal_t _signal_full
"full" signal - triggered when data is produced
Definition ringbuf.h:94
l4shmc_ringbuf_t::_addr
l4shmc_ringbuf_head_t * _addr
pointer to ring buffer head
Definition ringbuf.h:93
l4shmc_ringbuf_t::_owner
l4_cap_idx_t _owner
owner (attached to send/recv signal)
Definition ringbuf.h:88
l4shmc_ringbuf_t::_size
unsigned _size
chunk size // XXX do we need this?
Definition ringbuf.h:90
l4shmc_ringbuf_t::_chunkname
char * _chunkname
name of the ring buffer chunk
Definition ringbuf.h:91
l4shmc_ringbuf_t::_signal_empty
l4shmc_signal_t _signal_empty
"empty" signal - triggered when data is consumed
Definition ringbuf.h:95
assert.h
Some useful assert-style macros.