C language to implement FIFO code

Recently, the author needed C language to implement a FIFO when working on a project, and started to refer to the following codes of these two masters.

Great God One:

C language to implement FIFO code_c language fifo-CSDN blog

Great God Two:

C language to implement FIFO code_c language fifo-CSDN blog

Combining the advantages and disadvantages of the code written by the two masters, I added the is_empty member variable on the basis of the master one to implement a ring FIFO. Write first and then read. If it is full, you cannot write again. If it is empty, you cannot read again.

The fifo.c file code is as follows:

#include "fifo.h"
#include "xil_types.h"
/**
* @brief fifo structure
*/

typedef struct
{
    int ptr_write;
    int ptr_read;
    bool is_full;
    bool is_empty;
    //The number of elements stored in fifo, not the byte size
    int item_sum;
    //Element size. Unit: bytes
    int item_size;
    void *fifo_ptr;
}Fifo;

int FifoAddr;

/**
* @brief Create fifo
* @param item_sum: the number of elements in fifo. Note that it is not the number of bytes
* @param item_size: element size. Unit: bytes
* @return fifo index
*/

int fifo_create(int item_sum, int item_size)
{
    Fifo *fifo = (Fifo *)malloc(sizeof(Fifo));
    fifo->item_sum = item_sum;
    fifo->item_size = item_size;
    fifo->ptr_write = 0;
    fifo->ptr_read = 0;
    fifo->is_full = false;
    fifo->is_empty = true;
    fifo->fifo_ptr = (void *)malloc(item_sum * item_size);
    if(NULL == fifo->fifo_ptr)
    {
    xil_printf("malloc failed");
    }
    return (int)fifo;
}

/**
* @brief delete fifo
* @param fifo_index: fifo index
*/

void fifo_delete(int fifo_index)
{
    Fifo *fifo = (Fifo *)fifo_index;
    free(fifo->fifo_ptr);
    fifo->fifo_ptr = NULL;
    free(fifo);
    fifo = NULL;
}

/**
* @brief fifo checks whether it can be written
* @param fifo_index: fifo index
* @retval false: cannot be written. true: can be written
*/

bool fifo_writeable(int fifo_index)
{
    Fifo *fifo = (Fifo *)fifo_index;
    return !fifo->is_full;
}

/**
* @brief fifo writing
* @param fifo_index: fifo index
* @param frame: write element pointer
* @return false:failure.true:success
*/

bool fifo_write(int fifo_index, void *data)
{
    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->is_full)
{
return false;
}

    memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size);
    fifo->ptr_write + + ;

    if (fifo->ptr_write >= fifo->item_sum)
   {
fifo->ptr_write = 0;
   }

    fifo->is_empty = false;
if (fifo->ptr_write == fifo->ptr_read)
{
fifo->is_full = true;
}

return true;
}

/**
* @brief fifo batch writing
* @param fifo_index: fifo index
* @param data: write element pointer
* @param item_num: the number of elements written
* @return false:failure.true:success
*/

bool fifo_write_batch(int fifo_index, void *data, int item_num)
{
    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo_writeable_item_count((int)fifo) < item_num)
    {
        return false;
    }

    memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size * item_num);
    fifo->ptr_write + = item_num;

    if (fifo->ptr_write >= fifo->item_sum)
   {
fifo->ptr_write = fifo->ptr_write - fifo->item_sum + item_num - 1;
   }

    fifo->is_empty = false;
if (fifo->ptr_write == fifo->ptr_read)
{
fifo->is_full = true;
}
    return true;
}

/**
* @brief fifo checks whether it can be read
* @param fifo_index: fifo index
* @return false: cannot be read. true: can be read
*/

bool fifo_readable(int fifo_index)
{
    Fifo *fifo = (Fifo *)fifo_index;
    return !fifo->is_empty;
}

/**
* @brief fifo read
* @param fifo_index: fifo index
* @param data: read data
* @return false: failure.true: success
*/

bool fifo_read(int fifo_index, void *data)
{
    Fifo *fifo = (Fifo *)fifo_index;
    if(fifo->is_empty)
{
return false;
}
    memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size);
    fifo->ptr_read + + ;

    if (fifo->ptr_read >= fifo->item_sum)
{
        fifo->ptr_read = 0;
}

    fifo->is_full = false;
if (fifo->ptr_read == fifo->ptr_write)
{
fifo->is_empty = true;
}

return true;
}

/**
* @brief fifo batch reading
* @param fifo_index: fifo index
* @param data: read data
* @param item_num: the number of elements read
* @return false: failure.true: success
*/

bool fifo_read_batch(int fifo_index, void *data, int item_num)
{
    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo_readable_item_count((int)fifo) < item_num)
    {
        return false;
    }

    memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size * item_num);
    fifo->ptr_read + = item_num;

    if (fifo->ptr_read >= fifo->item_sum)
   {
fifo->ptr_read = fifo->ptr_read - fifo->item_sum + item_num - 1;
   }

    fifo->is_full = false;
if (fifo->ptr_read == fifo->ptr_write)
{
fifo->is_empty = true;
}

    return true;
}

/**
* @brief The number of elements readable by fifo
* @param fifo_index: fifo index
* @return number of elements
*/

int fifo_readable_item_count(int fifo_index)
{
Fifo *fifo = (Fifo *)fifo_index;

if (fifo->ptr_write >= fifo->ptr_read)
{
return (fifo->ptr_write - fifo->ptr_read);
}

else
{
return (fifo->item_sum - fifo->ptr_read + fifo->ptr_write);
}
}

/**
* @brief The number of elements that fifo can write
* @param fifo_index: fifo index
* @return number of elements
*/

int fifo_writeable_item_count(int fifo_index)
{
Fifo *fifo = (Fifo *)fifo_index;

if (fifo->ptr_write < fifo->ptr_read)
{
return (fifo->ptr_read - fifo->ptr_write);
}
else
{
return (fifo->item_sum - fifo->ptr_write + fifo->ptr_read);
}
}

The fifo.h file code is as follows:

#ifndef _FIFO_H_
#define _FIFO_H_

#include "stdlib.h"
#include "stdio.h"
#include "stdarg.h"
#include "stdbool.h"
#include "string.h"
#include "math.h"

extern int FifoAddr;
/**
* @brief Create fifo
* @param item_sum: the number of elements in fifo. Note that it is not the number of bytes
* @param item_size: element size. Unit: bytes
* @return fifo index
*/

int fifo_create(int item_sum, int item_size);

/**
* @brief delete fifo
* @param fifo_index: fifo index
*/

void fifo_delete(int fifo_index);

/**
* @brief fifo checks whether it can be written
* @param fifo_index: fifo index
* @retval false: cannot be written. true: can be written
*/

bool fifo_writeable(int fifo_index);

/**
* @brief fifo writing
* @param fifo_index: fifo index
* @param frame: write element pointer
* @return false:failure.true:success
*/

bool fifo_write(int fifo_index, void *data);

/**
* @brief fifo batch writing
* @param fifo_index: fifo index
* @param data: write element pointer
* @param @param item_num: the number of elements written
* @return false:failure.true:success
*/

bool fifo_write_batch(int fifo_index, void *data, int item_num);

/**
* @brief fifo checks whether it can be read
* @param fifo_index: fifo index
* @return false: cannot be read. true: can be read
*/

bool fifo_readable(int fifo_index);

/**
* @brief fifo read
* @param fifo_index: fifo index
* @param data: read data
* @return false: failure.true: success
*/

bool fifo_read(int fifo_index, void *data);

/**
* @brief fifo batch reading
* @param fifo_index: fifo index
* @param data: read data
* @param item_num: the number of elements read
* @return false: failure.true: success
*/

bool fifo_read_batch(int fifo_index, void *data, int item_num);

/**
* @brief The number of elements readable by fifo
* @param fifo_index: fifo index
* @return number of elements
*/

int fifo_readable_item_count(int fifo_index);

/**
* @brief The number of elements that fifo can write
* @param fifo_index: fifo index
* @return number of elements
*/

int fifo_writeable_item_count(int fifo_index);

#endif