cariboulabs-cariboulite/software/libcariboulite/src/datatypes/tsqueue.h

112 wiersze
3.4 KiB
C

#ifndef __TSQUEUE_H__
#define __TSQUEUE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdint.h>
#define TSQUEUE_TIMEOUT (1)
#define TSQUEUE_OK (0)
#define TSQUEUE_BUFFER_FULL (-1)
#define TSQUEUE_MEM_ALLOC_FAILED (-2)
#define TSQUEUE_SEM_INIT_FAILED (-3)
#define TSQUEUE_MUTEX_INIT_FAILED (-4)
#define TSQUEUE_NOT_INITIALIZED (-5)
#define TSQUEUE_FAILED_FULL (-6)
#define TSQUEUE_SEM_FAILED (-7)
#define TSQUEUE_FAILED_EMPTY (-8)
typedef struct
{
uint8_t *data;
int length;
uint32_t metadata; // can be a pointer context, a number, a set of flags, etc.
} tsqueue_item_st;
typedef struct
{
tsqueue_item_st *items;
int max_num_items;
int item_size_bytes;
int current_num_of_items;
int head;
int tail;
// The mutex lock, and the semaphores
pthread_mutex_t mutex;
sem_t full, empty;
int sema_inited;
int num_items_dropped;
} tsqueue_st;
/*
* Init the queue
* q: a pointer to a pre-allocated structure
* item_size_bytes: the maximal container size of each item in the queue (bytes)
* total_element_count: the total capacity of the cyclic queue
*/
int tsqueue_init(tsqueue_st* q, int item_size_bytes, int total_element_count);
/*
* Release the queue
*/
int tsqueue_release(tsqueue_st* q);
/*
* Push an item to the queue
* item: the contents of the item to be pushed. The item contents are cloned (copied)
* to the internal local copy, thus, this parameter may be changed as needed after the call
* Note: if the queue is full, the function returned immediatelly with an error. This dunctionality can
* be changed by letting the function block until space is freed up in the queue. When there is not
* sufficient space in the queue, the item is dropped and the "dropped" counter is increased.
*/
int tsqueue_insert_push_item(tsqueue_st* q, tsqueue_item_st* item, int timeout_us, int override);
/*
* Push a buffer to the queue
* The same as before, but rather than an "item", a specific buffer, length and metadata are
* cloned into the internal item local copy, and pushed to the queue
*/
int tsqueue_insert_push_buffer(tsqueue_st* q, uint8_t* buffer, int length, uint32_t metadata, int timeout_us, int override);
/*
* Pop an item from the queue with timeout
* item: the output of the function is a pointer to a single cell in the queue that has been
* popped. This item pointer is not cloned to the user but rather passed by reference.
* it is up to the user to create his own private copy of its contents as soon as he gets
* the pointer.
* Note: this function blocked until there is anything to pop. If the queue is empty, the queue will
* hold the calling thread in a blocking condition.
* For no timeout option pass 0 to timeout_ms
*/
int tsqueue_pop_item(tsqueue_st* q, tsqueue_item_st** item, int timeout_us);
/*
* Return the current number of items in the queue
*/
int tsqueue_number_of_items(tsqueue_st* q);
/*
* Clears the "dropped" counter value to zero.
*/
int tsqueue_reset_dropped_counter(tsqueue_st* q);
/*
* Return the current count value of the dropped items - those we wanted to push but couldn't due
* to insufficient capacity
*/
int tsqueue_get_number_of_dropped(tsqueue_st* q);
#ifdef __cplusplus
}
#endif
#endif // __TSQUEUE_H__