- BlockingFifo: semaphore management fixed
This commit is contained in:
parent
ca97d1718a
commit
d14a4e9c2f
@ -9,34 +9,34 @@
|
|||||||
|
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
BlockingFifo *eth_bfifo_new(uint32_t size) {
|
EthBlockingFifo *eth_bfifo_new(uint32_t size) {
|
||||||
uint32_t allocSize = sizeof(BlockingFifo) + size; // calculate full allocation size
|
uint32_t allocSize = sizeof(EthBlockingFifo) + size; // calculate full allocation size
|
||||||
BlockingFifo * fifo = (BlockingFifo *) dynmem_alloc(allocSize); // allocate data block at the end
|
EthBlockingFifo * fifo = (EthBlockingFifo *) dynmem_alloc(allocSize); // allocate data block at the end
|
||||||
ASSERT_NULL(fifo);
|
ASSERT_NULL(fifo);
|
||||||
memset(fifo, 0, sizeof(BlockingFifo));
|
memset(fifo, 0, sizeof(EthBlockingFifo));
|
||||||
fifo->size = size;
|
fifo->size = size;
|
||||||
fifo->nonEmpty = ETHLIB_OS_SEM_CREATE(1);
|
fifo->nonEmpty = ETHLIB_OS_SEM_CREATE(1);
|
||||||
ETHLIB_OS_SEM_WAIT(fifo->nonEmpty); // FIFO is empty
|
|
||||||
fifo->notFull = ETHLIB_OS_SEM_CREATE(1);
|
fifo->notFull = ETHLIB_OS_SEM_CREATE(1);
|
||||||
|
ETHLIB_OS_SEM_POST(fifo->notFull);
|
||||||
return fifo;
|
return fifo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eth_bfifo_destroy(BlockingFifo * bfifo) {
|
void eth_bfifo_destroy(EthBlockingFifo * bfifo) {
|
||||||
ETHLIB_OS_SEM_DESTROY(bfifo->nonEmpty);
|
ETHLIB_OS_SEM_DESTROY(bfifo->nonEmpty);
|
||||||
ETHLIB_OS_SEM_DESTROY(bfifo->notFull);
|
ETHLIB_OS_SEM_DESTROY(bfifo->notFull);
|
||||||
bfifo->size = 0;
|
bfifo->size = 0;
|
||||||
dynmem_free(bfifo);
|
dynmem_free(bfifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_get_used(const BlockingFifo *bfifo) {
|
uint32_t eth_bfifo_get_used(const EthBlockingFifo *bfifo) {
|
||||||
return bfifo->absWriteIdx - bfifo->absReadIdx;
|
return bfifo->absWriteIdx - bfifo->absReadIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_get_free(const BlockingFifo * bfifo) {
|
uint32_t eth_bfifo_get_free(const EthBlockingFifo * bfifo) {
|
||||||
return bfifo->size - eth_bfifo_get_used(bfifo);
|
return bfifo->size - eth_bfifo_get_used(bfifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
|
uint32_t eth_bfifo_push_try(EthBlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
|
||||||
if (eth_bfifo_get_free(bfifo) == 0) {
|
if (eth_bfifo_get_free(bfifo) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -44,7 +44,7 @@ uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
|
uint32_t eth_bfifo_push(EthBlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
|
||||||
ETHLIB_OS_SEM_WAIT(bfifo->notFull); // take not full semaphore
|
ETHLIB_OS_SEM_WAIT(bfifo->notFull); // take not full semaphore
|
||||||
|
|
||||||
// calculate copy size, limit if required
|
// calculate copy size, limit if required
|
||||||
@ -79,7 +79,7 @@ uint32_t eth_bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t siz
|
|||||||
return copySize;
|
return copySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size) {
|
uint32_t eth_bfifo_peek(EthBlockingFifo * bfifo, uint8_t * dst, uint32_t size) {
|
||||||
// determine copy size
|
// determine copy size
|
||||||
uint32_t usedArea = eth_bfifo_get_used(bfifo);
|
uint32_t usedArea = eth_bfifo_get_used(bfifo);
|
||||||
uint32_t copySize = MIN(size, usedArea);
|
uint32_t copySize = MIN(size, usedArea);
|
||||||
@ -94,7 +94,7 @@ uint32_t eth_bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size) {
|
|||||||
return copySize;
|
return copySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t eth_bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size) {
|
uint32_t eth_bfifo_pop(EthBlockingFifo *bfifo, uint8_t *dst, uint32_t size) {
|
||||||
ETHLIB_OS_SEM_WAIT(bfifo->nonEmpty);
|
ETHLIB_OS_SEM_WAIT(bfifo->nonEmpty);
|
||||||
|
|
||||||
// if destination is given, then also perform a copy
|
// if destination is given, then also perform a copy
|
||||||
@ -114,10 +114,10 @@ uint32_t eth_bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size) {
|
|||||||
|
|
||||||
usedArea = eth_bfifo_get_used(bfifo);
|
usedArea = eth_bfifo_get_used(bfifo);
|
||||||
if (usedArea > 0) { // FIFO is NOT empty
|
if (usedArea > 0) { // FIFO is NOT empty
|
||||||
ETHLIB_OS_SEM_POST(&bfifo->nonEmpty);
|
ETHLIB_OS_SEM_POST(bfifo->nonEmpty);
|
||||||
}
|
}
|
||||||
if (usedArea != bfifo->size) { // FIFO is NOT full
|
if (usedArea != bfifo->size) { // FIFO is NOT full
|
||||||
ETHLIB_OS_SEM_POST(&bfifo->notFull);
|
ETHLIB_OS_SEM_POST(bfifo->notFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
return popSize;
|
return popSize;
|
||||||
|
@ -19,27 +19,27 @@ typedef struct {
|
|||||||
uint32_t size; ///< Size of the storage area
|
uint32_t size; ///< Size of the storage area
|
||||||
ETHLIB_OS_SEM_TYPE notFull, nonEmpty; ///< Semaphore, protecting read and write operations
|
ETHLIB_OS_SEM_TYPE notFull, nonEmpty; ///< Semaphore, protecting read and write operations
|
||||||
uint8_t data[]; ///< Window data storage
|
uint8_t data[]; ///< Window data storage
|
||||||
} BlockingFifo;
|
} EthBlockingFifo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new blocking FIFO.
|
* Create new blocking FIFO.
|
||||||
* @param size size of the FIFO in bytes
|
* @param size size of the FIFO in bytes
|
||||||
* @return newly allocated FIFO
|
* @return newly allocated FIFO
|
||||||
*/
|
*/
|
||||||
BlockingFifo * eth_bfifo_new(uint32_t size);
|
EthBlockingFifo * eth_bfifo_new(uint32_t size);
|
||||||
|
|
||||||
void eth_bfifo_destroy(BlockingFifo * bfifo);
|
void eth_bfifo_destroy(EthBlockingFifo * bfifo);
|
||||||
|
|
||||||
uint32_t eth_bfifo_get_used(const BlockingFifo * bfifo);
|
uint32_t eth_bfifo_get_used(const EthBlockingFifo * bfifo);
|
||||||
|
|
||||||
uint32_t eth_bfifo_get_free(const BlockingFifo * bfifo);
|
uint32_t eth_bfifo_get_free(const EthBlockingFifo * bfifo);
|
||||||
|
|
||||||
uint32_t eth_bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size);
|
uint32_t eth_bfifo_push(EthBlockingFifo * bfifo, const uint8_t * data, uint32_t size);
|
||||||
|
|
||||||
uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size);
|
uint32_t eth_bfifo_push_try(EthBlockingFifo * bfifo, const uint8_t * data, uint32_t size);
|
||||||
|
|
||||||
uint32_t eth_bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size);
|
uint32_t eth_bfifo_peek(EthBlockingFifo * bfifo, uint8_t * dst, uint32_t size);
|
||||||
|
|
||||||
uint32_t eth_bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size);
|
uint32_t eth_bfifo_pop(EthBlockingFifo *bfifo, uint8_t *dst, uint32_t size);
|
||||||
|
|
||||||
#endif //ETHERLIB_TEST_BLOCKING_FIFO_H
|
#endif //ETHERLIB_TEST_BLOCKING_FIFO_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user