diff options
| author | hathach <[email protected]> | 2025-11-22 00:51:18 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2025-11-22 00:51:18 +0700 |
| commit | 793d3b5dd14ae4459ce7fbfdf9f4815973fea0e9 (patch) | |
| tree | 89acd311db51ab21499a622bccc7ba6358b009a8 /src/common/tusb_fifo.c | |
| parent | c9b623aa63d24d58a7a5e55dd296afd1261b2ab8 (diff) | |
more tusb fifo refactor: ff_peek_local() lock mutex if need to correct read pointer. More rename
Diffstat (limited to 'src/common/tusb_fifo.c')
| -rw-r--r-- | src/common/tusb_fifo.c | 107 |
1 files changed, 48 insertions, 59 deletions
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index c83f323e6..463a059f0 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -51,9 +51,8 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) { } #else - -#define _ff_lock(_mutex) -#define _ff_unlock(_mutex) + #define ff_lock(_mutex) + #define ff_unlock(_mutex) #endif @@ -65,8 +64,8 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si return false; } - _ff_lock(f->mutex_wr); - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_wr); + ff_lock(f->mutex_rd); f->buffer = (uint8_t *)buffer; f->depth = depth; @@ -75,8 +74,8 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si f->rd_idx = 0u; f->wr_idx = 0u; - _ff_unlock(f->mutex_wr); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_wr); + ff_unlock(f->mutex_rd); return true; } @@ -217,8 +216,8 @@ static void _ff_push_n(tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t w } // get one item from fifo WITHOUT updating read pointer -static inline void _ff_pull(tu_fifo_t *f, void *app_buf, uint16_t rel) { - memcpy(app_buf, f->buffer + (rel * f->item_size), f->item_size); +TU_ATTR_ALWAYS_INLINE static inline void _ff_pull(tu_fifo_t *f, void *buf, uint16_t ptr) { + memcpy(buf, f->buffer + (ptr * f->item_size), f->item_size); } // get n items from fifo WITHOUT updating read pointer @@ -316,7 +315,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t advance_index(uint16_t depth, uint1 return new_idx; } -// index to pointer, simply a modulo with minus. +// index to pointer (0..depth-1), simply a modulo with minus. TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t idx) { // Only run at most 3 times since index is limit in the range of [0..2*depth) while (idx >= depth) { @@ -326,8 +325,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id } // Works on local copies of w -// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo i.e -// tu_ff_overflow_count() = depth +// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo TU_ATTR_ALWAYS_INLINE static inline uint16_t ff_correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; if (wr_idx >= f->depth) { @@ -337,30 +335,25 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t ff_correct_read_index(tu_fifo_t *f, } f->rd_idx = rd_idx; - return rd_idx; } -// Works on local copies of w and r -// Must be protected by mutexes since in case of an overflow read pointer gets modified -static bool _tu_fifo_peek(tu_fifo_t *f, void *p_buffer, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); - - // nothing to peek - if (cnt == 0) { - return false; +// peek() using local write/read index. Be careful, caller must not lock mutex, since this Will also try to lock mutex +// in case of overflowed to correct read index +static bool ff_peek_local(tu_fifo_t *f, void *p_buffer, uint16_t wr_idx, uint16_t rd_idx) { + const uint16_t ovf_count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); + if (ovf_count == 0) { + return false; // nothing to peek } - // Check overflow and correct if required - if (cnt > f->depth) { + // Correct read index if overflow + if (ovf_count > f->depth) { + ff_lock(f->mutex_rd); rd_idx = ff_correct_read_index(f, wr_idx); + ff_unlock(f->mutex_rd); } - uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); - - // Peek data - _ff_pull(f, p_buffer, rd_ptr); - + _ff_pull(f, p_buffer, idx2ptr(f->depth, rd_idx)); return true; } @@ -399,7 +392,7 @@ uint16_t tu_fifo_write_n_access(tu_fifo_t *f, const void *data, uint16_t n, tu_f return 0; } - _ff_lock(f->mutex_wr); + ff_lock(f->mutex_wr); uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; @@ -462,13 +455,13 @@ uint16_t tu_fifo_write_n_access(tu_fifo_t *f, const void *data, uint16_t n, tu_f TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx); } - _ff_unlock(f->mutex_wr); + ff_unlock(f->mutex_wr); return n; } uint16_t tu_fifo_read_n_access(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_access_mode_t access_mode) { - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_rd); // Peek the data // f->rd_idx might get modified in case of an overflow so we can not use a local variable @@ -477,15 +470,15 @@ uint16_t tu_fifo_read_n_access(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_a // Advance read pointer f->rd_idx = advance_index(f->depth, f->rd_idx, n); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_rd); return n; } // Only use in case tu_fifo_overflow() returned true! void tu_fifo_correct_read_pointer(tu_fifo_t *f) { - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_rd); ff_correct_read_index(f, f->wr_idx); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_rd); } /******************************************************************************/ @@ -505,16 +498,15 @@ void tu_fifo_correct_read_pointer(tu_fifo_t *f) { */ /******************************************************************************/ bool tu_fifo_read(tu_fifo_t *f, void *buffer) { - _ff_lock(f->mutex_rd); - // Peek the data // f->rd_idx might get modified in case of an overflow so we can not use a local variable - bool ret = _tu_fifo_peek(f, buffer, f->wr_idx, f->rd_idx); - - // Advance pointer - f->rd_idx = advance_index(f->depth, f->rd_idx, ret); + const bool ret = ff_peek_local(f, buffer, f->wr_idx, f->rd_idx); + if (ret) { + ff_lock(f->mutex_rd); + f->rd_idx = advance_index(f->depth, f->rd_idx, 1); + ff_unlock(f->mutex_rd); + } - _ff_unlock(f->mutex_rd); return ret; } @@ -532,10 +524,7 @@ bool tu_fifo_read(tu_fifo_t *f, void *buffer) { */ /******************************************************************************/ bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) { - _ff_lock(f->mutex_rd); - bool ret = _tu_fifo_peek(f, p_buffer, f->wr_idx, f->rd_idx); - _ff_unlock(f->mutex_rd); - return ret; + return ff_peek_local(f, p_buffer, f->wr_idx, f->rd_idx); } /******************************************************************************/ @@ -554,9 +543,9 @@ bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) { */ /******************************************************************************/ uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) { - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_rd); uint16_t ret = tu_fifo_peek_n_access(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_INC_ADDR_RW8); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_rd); return ret; } @@ -577,7 +566,7 @@ uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) { */ /******************************************************************************/ bool tu_fifo_write(tu_fifo_t *f, const void *data) { - _ff_lock(f->mutex_wr); + ff_lock(f->mutex_wr); bool ret; const uint16_t wr_idx = f->wr_idx; @@ -591,7 +580,7 @@ bool tu_fifo_write(tu_fifo_t *f, const void *data) { ret = true; } - _ff_unlock(f->mutex_wr); + ff_unlock(f->mutex_wr); return ret; } @@ -605,14 +594,14 @@ bool tu_fifo_write(tu_fifo_t *f, const void *data) { */ /******************************************************************************/ bool tu_fifo_clear(tu_fifo_t *f) { - _ff_lock(f->mutex_wr); - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_wr); + ff_lock(f->mutex_rd); f->rd_idx = 0; f->wr_idx = 0; - _ff_unlock(f->mutex_wr); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_wr); + ff_unlock(f->mutex_rd); return true; } @@ -631,13 +620,13 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { return true; } - _ff_lock(f->mutex_wr); - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_wr); + ff_lock(f->mutex_rd); f->overwritable = overwritable; - _ff_unlock(f->mutex_wr); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_wr); + ff_unlock(f->mutex_rd); return true; } @@ -706,9 +695,9 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) { - _ff_lock(f->mutex_rd); + ff_lock(f->mutex_rd); rd_idx = ff_correct_read_index(f, wr_idx); - _ff_unlock(f->mutex_rd); + ff_unlock(f->mutex_rd); cnt = f->depth; } |
