wiki:library_mwmr

Version 22 (modified by alain, 9 years ago) (diff)

--

The MWMR Library

The mwmr_channel.c and mwmr_channel.h files define an user-level communication middleware, for parallel multi-threads applications.

It supports channelized communications , when the communication scheme can be statically described by a Task and Communication Graph. Each MWMR (Multi-Writer Multi-Reader) channel can be accessed concurently by one or several writer(s) and by one or several reader(s). It is implemented as a software FIFO, protected by a build-in, user-level spin_lock.

This software FIFO can be directly accessed by an hardware coprocessor, thanks to the vci_mwmr_controller, but we only describe here the software API that can be used by a software applications.

An MWMR transaction transfer an integer number of items between a thread private buffer and the MWMR communication channel. An item is the smallest quantity of data that can be atomically transfered. It is an integer number of 32 bits words (uint32_t).

An mwmr_channel_t communication channel is therefore defined by two parameters:

  • The width parameter define the number of words contained in an item (can be 1).
  • The nitems parameter define the max number of items that can be stored in the FIFO.

In the user code, an MWMR channel must be defined by two global variables:

  • a channel descriptor is a variable of type mwmr_channel_t.
  • a data buffer is an array of 32 bits words.

WARNING (i) The MWMR channel, can be accessed by several tasks, but it must be initialized by one single task.

WARNING (ii) The channel must be declared in a non cacheable segment, if the platform does not provide hardware cache coherence.

The mwmr_read() and mwmr_write() blocking functions can be used to implement a parallel application complying with the KPN (Kahn Process Network) semantic. The nb_mwmr_read() and nb_mwmr_write() non blocking functions can be used to implement various higher level communication protocols.

Communication Channel Initialisation

void mwmr_init( mwmr_channel_t* mwmr, uint32_t* buffer , uint32_t width , uint32_t items )

This function initializes the MWMR channel descriptor (including the lock protecting exclusive access).

  • mwmr : MWMR channel descriptor base address.
  • buffer : data buffer (unsigned int) base address.
  • width : number of 32 bits words contained in an item.
  • nitems : max number of items in the channel.

It must be called by one single task.

Communication Channel Blocking Access

void mwmr_write( mwmr_channel_t* mwmr, uint32_t* buffer , uint32_t items )

This function transfer (nitems * width) 32 bits words from a task private buffer to the MWMR channel.

  • mwmr : MWMR channel virtual base address.
  • buffer : virtual base address of local buffer.
  • items : number of items to be transfered.

It takes the lock for exclusive access before testing the channel state. If there is not enough space in mwmr channel to write nitems, it writes as many items as possible, releases the lock, does not return, but retry to take the lock to transfer the rest of the data... up to completion.

void mwmr_read( mwmr_channel_t* mwmr, uint32_t* buffer , uint32_t items )

This function transfer (nitems * width) 32 bits words from the MWMR channel to a task private buffer.

  • mwmr : MWMR channel virtual base address.
  • buffer : virtual base address of local buffer.
  • items : number of items to be transfered.

It takes the lock for exclusive access before testing the channel state. If there is not enough space in mwmr channel to write nitems, it writes as many items as possible, releases the lock, does not return, but retry to take the lock to transfer the rest of the data... up to completion.

Communication Channel Non Blocking Access

uint32_t nb_mwmr_write( mwmr_channel_t* mwmr , uint32_t* buffer , uint32_t items )

This function request to transfer (nitems * width) 32 bits words from a task private buffer tot he MWMR channel.

  • mwmr : MWMR channel virtual base address.
  • buffer : virtual base address of local buffer.
  • items : number of items to be transfered.

It takes the lock for exclusive access before testing the channel state. If there is not enough free space in the channel, it transfer as many items as possible, releases the lock, and returns the number of actually transfered items (it can be 0).

uint32_t nb_mwmr_write( mwmr_channel_t* mwmr , uint32_t* buffer , uint32_t items )

This function request to transfer (nitems * width) 32 bits words from the MWMR channel to a task private buffer.

  • mwmr : MWMR channel virtual base address.
  • buffer : virtual base address of local buffer.
  • items : number of items to be transfered.

It takes the lock for exclusive access before testing the channel state. If there is not enough data in the channel, it transfer as many items as possible, releases the lock, and returns the number of actually transfered items (it can be 0).

Besides the MWMR channels, the MWMR library provide another - optional - service: The mwmr_bufio_t buffer (and the associated access functions) can be used to implement a private input or output buffer, and move data to or from a shared MWMR communication channel. This buffer can be declared as a local variable in the stack of the reader/writer thread, and simplifies the access to the MWMR channel when the transfered data have a non fixed format, and must be analysed or produced byte per byte:

  • the buffer descriptor contains a byte pointer.
  • an input buffer is automatically refill from the associated MWMR channel when it becomes empty.
  • an output buffer is automatically transferred to the associated MWMR channel when it becomes full.

Private Buffer Initialization

void mwmr_bufio_init( mwmr_bufio_t* bufio , uint8_t* buffer , uint32_t size , uint32_t is_input , mwmr_channel_t* mwmr )

This function initializes the BUFIO descriptor.

  • bufio : pointer on the BUFIO descriptor.
  • buffer : pointer on the private buffer.
  • size : number of bytes in the private buffer / must be multiple of 4.
  • is_input : buffer type / input buffer when non-zero.
  • mwmr : pointer on the associated MWMR channel descriptor.

Input Bufio Access

uint8_t mwmr_bufio_read_byte( mwmr_bufio_t* bufio )

This blocking function returns one single byte from the <bufio> input buffer. The bufio is automatically refill from the associated MWMR channel if required.

uint16_t mwmr_bufio_read_half( mwmr_bufio_t* bufio )

This blocking function returns two bytes from the <bufio> input buffer. The bufio is automatically refill from the associated MWMR channel if required.

uint32_t mwmr_bufio_read_word( mwmr_bufio_t* bufio )

This blocking function returns four bytes from the <bufio> input buffer. The bufio is automatically refill from the associated MWMR channel if required.

void mwmr_bufio_skip( mwmr_bufio_t* bufio , uint32_t length )

This function discard <length> bytes from the <bufio> input buffer. The bufio is automatically refill from the associated MWMR channel if required.

void mwmr_bufio_align( mwmr_bufio_t* bufio )

This function discard as many bytes as required to align the buffo pointer on the next item boundary.

Output Bufio Access

void mwmr_bufio_write_byte( mwmr_bufio_t* bufio , uint8_t value )

This blocking function writes one byte the <bufio> output buffer. The bufio is automatically flushed to the associated MWMR channel if required.

void mwmr_bufio_write_half( mwmr_bufio_t* bufio , uint16_t value )

This blocking function writes two bytes into the <bufio> output buffer. The bufio is automatically flushed to the associated MWMR channel if required.

void mwmr_bufio_write_word( mwmr_bufio_t* bufio , uint32_t value )

This blocking function writes four bytes into the <bufio> output buffer. The bufio is automatically flushed to the associated MWMR channel if required.

void mwmr_bufio_flush( mwmr_bufio_t* bufio )

This function moves the current content of the <bufio> output buffer to the associated MWMR channel when it is non empty. It introduces padding zeros if the number of bytes contained in the bufio is not multiple of the item size.