1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

core/lib/cib: add several new peek functions

This patch adds calls to be able to peek at items other than just the
oldest item in a cib based FIFO. It also adds an "unsafe" peek to match
the existing "unsafe" put and get functions.
This commit is contained in:
Joshua DeWeese 2023-08-29 14:39:37 -04:00
parent 45752a3002
commit b6481654ba
2 changed files with 139 additions and 6 deletions

View File

@ -119,20 +119,75 @@ static inline int cib_get(cib_t *__restrict cib)
return -1;
}
/**
* @brief Get the index of an item in the buffer without removing anything.
*
* Offset 0 is the next item in the buffer that would be returned by
* `cip_get()`, offset 1 would be the following, and so on.
*
* Unsafe version, *must not* pass an offset that is larger than the number of
* items currently in the buffer!
*
* @param[in,out] cib corresponding *cib* to buffer.
* Must not be NULL.
* @param[in] offset offset from front of buffer
*
* @return index of item
* @retval -1 if no item at @p offset exists in the buffer
*/
static inline int cib_peek_at_unsafe(cib_t *__restrict cib, unsigned offset)
{
return (cib->read_count + offset) & cib->mask;
}
/**
* @brief Get the index of an item in the buffer without removing anything.
*
* Offset 0 is the next item in the buffer that would be returned by
* `cip_get()`, offset 1 would be the following, and so on.
*
* @param[in,out] cib corresponding *cib* to buffer.
* Must not be NULL.
* @param[in] offset offset from front of buffer
*
* @return index of item
* @retval -1 if no item at @p offset exists in the buffer
*/
static inline int cib_peek_at(cib_t *__restrict cib, unsigned offset)
{
if (offset < cib_avail(cib)) {
return cib_peek_at_unsafe(cib, offset);
}
return -1;
}
/**
* @brief Get the index of the next item in buffer without removing it.
*
* Unsafe version, *must not* be called if buffer is empty!
*
* @param[in,out] cib corresponding *cib* to buffer.
* Must not be NULL.
* @return index of next item
* @retval -1 if the buffer is empty
*/
static inline int cib_peek_unsafe(cib_t *__restrict cib)
{
return cib_peek_at_unsafe(cib, 0);
}
/**
* @brief Get the index of the next item in buffer without removing it.
*
* @param[in,out] cib corresponding *cib* to buffer.
* Must not be NULL.
* @return index of next item, -1 if the buffer is empty
* @return index of next item
* @retval -1 if the buffer is empty
*/
static inline int cib_peek(cib_t *__restrict cib)
{
if (cib_avail(cib)) {
return (int)(cib->read_count & cib->mask);
}
return -1;
return cib_peek_at(cib, 0);
}
/**

View File

@ -72,6 +72,83 @@ static void test_cib_peek__overflow(void)
TEST_ASSERT_EQUAL_INT(TEST_CIB_SIZE-1, cib_peek(&cib));
}
static void test_cib_peek_at(void)
{
/* Peeking an empty cib should give an error */
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 0));
/* Put 1 item in cib and check that we can peek it */
TEST_ASSERT_EQUAL_INT( 0, cib_put(&cib));
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
/* Peek past the end should give an error. */
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 1));
/* Put another item in cib. */
TEST_ASSERT_EQUAL_INT( 1, cib_put(&cib));
/* cib should now hold the indices { 0, 1 }. Test this. */
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 2));
/* Put another item in cib. */
TEST_ASSERT_EQUAL_INT( 2, cib_put(&cib));
/* cib should now hold the indices { 0, 1, 2 }. Test this. */
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 2));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 3));
/* Put another item in cib. */
TEST_ASSERT_EQUAL_INT( 3, cib_put(&cib));
/* cib should now hold the indices { 0, 1, 2, 3 }. Test this. */
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 2));
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 3));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 4));
/* Remove an item from cib. */
TEST_ASSERT_EQUAL_INT( 0, cib_get(&cib));
/* cib should now hold the indices { 1, 2, 3 }. Test this. */
TEST_ASSERT_EQUAL_INT( 1, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 1));
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 2));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 3));
/* Remove another item from cib. */
TEST_ASSERT_EQUAL_INT( 1, cib_get(&cib));
/* cib should now hold the indices { 2, 3 }. Test this. */
TEST_ASSERT_EQUAL_INT( 2, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 1));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 2));
/* Remove another item from cib. */
TEST_ASSERT_EQUAL_INT( 2, cib_get(&cib));
/* cib should now hold the indices { 3 }. Test this. */
TEST_ASSERT_EQUAL_INT( 3, cib_peek(&cib));
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 0));
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 1));
/* Remove last item from cib. */
TEST_ASSERT_EQUAL_INT( 3, cib_get(&cib));
/* Peeking an empty cib should give an error */
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 0));
}
static void test_cib_avail(void)
{
TEST_ASSERT_EQUAL_INT(0, cib_avail(&cib));
@ -111,6 +188,7 @@ Test *tests_core_cib_tests(void)
new_TestFixture(test_singleton_cib),
new_TestFixture(test_cib_peek),
new_TestFixture(test_cib_peek__overflow),
new_TestFixture(test_cib_peek_at),
};
EMB_UNIT_TESTCALLER(core_cib_tests, set_up, NULL, fixtures);