/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _OSI_BLOCKED_FIFO_H_ #define _OSI_BLOCKED_FIFO_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * \brief opaque blocked FIFO data struct */ typedef struct osiBlockedFifo osiBlockedFifo_t; /** * \brief create a blocked FIFO * * \p alignment should be power of 2. \p data, \p size and \p block_size * should be aligned with \p alignment. \p size should be multiple of * \p block_size. * * \p block_count is the count for block management count. Usually it is * larger than \p size/block_size. * * \param data memory for blocked FIFO * \param size memory size * \param alignment block starting address alignment * \param block_size maximum block size * \param block_count block management count * \return * - blocked FIFO * - NULL if parameters are invalid or out of memory */ osiBlockedFifo_t *osiBlockedFifoCreate(void *data, unsigned size, unsigned alignment, unsigned block_size, unsigned block_count); /** * \brief reset the blocked FIFO * * \param fifo the blocked FIFO pointer */ void osiBlockedFifoReset(osiBlockedFifo_t *fifo); /** * \brief delete the blocked FIFO * * When \p fifo is NULL, nothing will be done * * \param fifo the blocked FIFO pointer */ void osiBlockedFifoDelete(osiBlockedFifo_t *fifo); /** * \brief put data into blocked FIFO * * \p size can be larger than \p block_size. In this case, multiple blocks * will be used. * * The byte count put into blocked FIFO may be less than the specified * \p size. * * When there is pending external put, it will return 0. * * \param fifo the blocked FIFO pointer * \param data data to be put * \param size data size to be put * \return * - byte count put into the blocked FIFO. * - -1 on invalid parameters */ int osiBlockedFifoPut(osiBlockedFifo_t *fifo, const void *data, unsigned size); /** * \brief get data from blocked FIFO * * \p size can be larger than \p block_size. In this case, multiple blocks * will be used. * * The byte count get from blocked FIFO may be less than the specified * \p size. * * When there is pending external get, it will return 0. * * \param fifo the blocked FIFO pointer * \param data memory for output data * \param size memory size * \return * - byte count get from the blocked FIFO. * - -1 on invalid parameters */ int osiBlockedFifoGet(osiBlockedFifo_t *fifo, void *data, unsigned size); /** * \brief request a bufer for external put * * Request a buffer for external put. When returned buffer is not NULL, * the buffer size is \p block_size, and the buffer is linear. * * When there are no spaces and \p take_lst is false, it will return * NULL. When \p take_last is true, it will drop the latest put buffer. * With proper configuration (\p block_count is not less than 4), it never * returns NULL. * * Only one pending request is permitted. That is, after * \p osiBlockedFifoPutRequest is called, and before * \p osiBlockedFifoPutDone is called, it will return NULL. * * \param fifo the blocked FIFO pointer * \param take_last drop and take the latest put buffer if set as true * \return * - linear put buffer address * - NULL if no spaces */ void *osiBlockedFifoPutRequest(osiBlockedFifo_t *fifo, bool take_last); /** * \brief external put is done * * This should be called after external put is done. * * \param fifo the blocked FIFO pointer * \param size the real put size * \return * - true on success * - false on invalid parameter, or not requested */ bool osiBlockedFifoPutDone(osiBlockedFifo_t *fifo, unsigned size); /** * \brief request buffer for external get * * When the return buffer is not NULL, \p size will not exceed \p block_size. * * Only one pending request is permitted. That is, after * \p osiBlockedFifoGutRequest is called, and before * \p osiBlockedFifoGutDone is called, it will return NULL. * * To ensure that the returned address is aligned: * - Not to call \p osiBlockedFifoGet * - At \p osiBlockedFifoGetDone, \p size is the same as output value of * \p osiBlockedFifoGetRequest. That is, the buffer of * \p osiBlockedFifoGetRequest should be consumed as a whole. * * \param fifo the blocked FIFO pointer * \param size requested buffer size * \return * - requested buffer * - NULL on blocked FIFO empty, or there is a pending get */ const void *osiBlockedFifoGetRequest(osiBlockedFifo_t *fifo, unsigned *size); /** * \brief external get is done * * This should be called after external get is done. \p size is the real * consumed byte count. * * When there is no pending external get, it will return false. * * \param fifo the blocked FIFO pointer * \param size the real consumed size * \return * - true on success * - false on invalid parameter, or not requested */ bool osiBlockedFifoGetDone(osiBlockedFifo_t *fifo, unsigned size); /** * \brief external get block is done * * This should be called after external get is done. Comparing to * \p osiBlockedFifoGetDone, \p size is not needed. And it means the * requested is consumed, and caller doesn't need to keep requested size. * * When there is no pending external get, it will return false. * * \param fifo the blocked FIFO pointer * \return * - true on success * - false on invalid parameter, or not requested */ bool osiBlockedFifoGetBlockDone(osiBlockedFifo_t *fifo); /** * \brief get block size * * \param fifo the blocked FIFO pointer * \return block size, constant property */ unsigned osiBlockedFifoBlockSize(osiBlockedFifo_t *fifo); /** * \brief whether the blocked FIFO is empty * * No byte count will be counted for pending external put. * * \param fifo the blocked FIFO pointer * \return * - true if the blocked FIFO is empty */ bool osiBlockedFifoIsEmpty(osiBlockedFifo_t *fifo); /** * \brief whether the blocked FIFO is full * * When there is pending external put, it will be considered as *not full*. * * There are 2 senerio of full: * - There are no memory spaces. * - Block count reaches \p block_count. * * \param fifo the blocked FIFO pointer * \return * - true if the blocked FIFO is full */ bool osiBlockedFifoIsFull(osiBlockedFifo_t *fifo); /** * \brief byte count in blocked FIFO * * \param fifo the blocked FIFO pointer * \return approximate byte count */ unsigned osiBlockedFifoBytes(osiBlockedFifo_t *fifo); /** * \brief space in blocked FIFO * * Due to there are holes in blocked FIFO, the space is inaccurate. * * \param fifo the blocked FIFO pointer * \return approximate space */ unsigned osiBlockedFifoSpace(osiBlockedFifo_t *fifo); /** * \brief show blocked FIFO blocks in trace * * It is for debug only. * * \param fifo the blocked FIFO pointer */ void osiBlockedFifoDumpInfo(osiBlockedFifo_t *fifo); #ifdef __cplusplus } #endif #endif