blob: d474ff641ad48780c54d923453d4cedb90a99dab [file] [log] [blame]
/******************************************************************************
Copyright (c) 2006-2015 Lantiq Deutschland GmbH
Copyright (c) 2015 Lantiq Beteiligungs-GmbH & Co.KG
Copyright 2018, Intel Corporation.
For licensing information, see the file 'LICENSE' in the root folder of
this software module.
******************************************************************************/
/**
\file dxs_fifo.c
Implementation of DxS fifo functions.
*/
/* ========================================================================== */
/* Includes */
/* ========================================================================== */
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include "dxs_config.h"
#include "dxs_fifo.h"
#include "dxs_error.h"
/* ========================================================================== */
/* Macro definitions */
/* ========================================================================== */
/* two fifos per device:
one for messages, one for command outbox data */
#define FIFOS_PER_DEVICE 2
/* ========================================================================== */
/* Type definitions */
/* ========================================================================== */
/* ========================================================================== */
/* Global variables */
/* ========================================================================== */
/** placeholder for the fifos */
FIFO_t dxs_fifos[DXS_MAX_DEVICES * FIFOS_PER_DEVICE];
/* ========================================================================== */
/* Function prototypes */
/* ========================================================================== */
/* ========================================================================== */
/* Function implementation */
/* ========================================================================== */
/**
Function fifo_init
\param elements - elements
\return
- FIFO_t
*/
FIFO_t* fifo_init (uint32_t elements)
{
FIFO_t *p;
int idx;
for (idx=0; idx<(DXS_MAX_DEVICES * FIFOS_PER_DEVICE); idx++)
{
p = &dxs_fifos[idx];
if (!p->in_use)
break;
}
if (idx == (DXS_MAX_DEVICES * FIFOS_PER_DEVICE))
{
return NULL;
}
p->magic = DXS_FIFO_MAGIC_CODE;
if (elements > MAX_FIFO_SIZE)
elements = MAX_FIFO_SIZE;
p->fifo_size = elements;
p->count = p->wr_idx = p->rd_idx = 0;
pthread_mutex_init(&p->mtx, NULL);
p->in_use = 1;
return p;
}
/**
Function fifo_destroy
\param fifo - pointer to FIFO_t
*/
void fifo_destroy (FIFO_t *fifo)
{
int err;
err = pthread_mutex_unlock(&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
err = pthread_mutex_destroy(&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
fifo->in_use = 0;
fifo->magic = 0;
}
/**
Function fifo_flush
\param fifo - pointer to FIFO_t
*/
void fifo_flush (FIFO_t *fifo)
{
int err;
err = pthread_mutex_lock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
fifo->count = fifo->wr_idx = fifo->rd_idx = 0;
err = pthread_mutex_unlock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
}
/**
Function fifo_count
\param fifo - pointer to FIFO_t
\return
- uint32_t count
*/
uint32_t fifo_count (FIFO_t *fifo)
{
return fifo->count;
}
/**
Function fifo_put
\param fifo - pointer to FIFO_t
\param data - pointer to data
\param size - size
\return
DXS_FIFO_INV
DXS_FIFO_FULL
DXS_FIFO_OK
*/
int32_t fifo_put (FIFO_t *fifo, void *data, uint32_t size)
{
FIFO_Elem_t *p;
int err;
if (fifo->magic != DXS_FIFO_MAGIC_CODE)
return DXS_FIFO_INV;
if (fifo->count == fifo->fifo_size)
return DXS_FIFO_FULL;
err = pthread_mutex_lock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
p = &fifo->elem[fifo->wr_idx];
p->data = data;
p->size = size;
fifo->count++;
if (++fifo->wr_idx == fifo->fifo_size)
fifo->wr_idx = 0;
err = pthread_mutex_unlock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
return DXS_FIFO_OK;
}
/**
Function fifo_get
\param fifo - pointer to FIFO_t
\param data - pointer to data
\param size - pointer size
\return
DXS_FIFO_INV
DXS_FIFO_EMPTY
DXS_FIFO_OK
*/
int32_t fifo_get (FIFO_t *fifo, void **data, uint32_t *size)
{
FIFO_Elem_t *p;
int err;
if (fifo->magic != DXS_FIFO_MAGIC_CODE)
return DXS_FIFO_INV;
if (fifo->count == 0)
return DXS_FIFO_EMPTY;
err = pthread_mutex_lock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
p = &fifo->elem[fifo->rd_idx];
*data = p->data;
*size = p->size;
fifo->count--;
if (++fifo->rd_idx == fifo->fifo_size)
fifo->rd_idx = 0;
err = pthread_mutex_unlock (&fifo->mtx);
if (err != 0)
DXS_ERROR_PUSH(err);
return DXS_FIFO_OK;
}