Skip to content

Commit b648165

Browse files
committed
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.
1 parent 45752a3 commit b648165

File tree

2 files changed

+138
-5
lines changed

2 files changed

+138
-5
lines changed

core/lib/include/cib.h

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,76 @@ static inline int cib_get(cib_t *__restrict cib)
120120
}
121121

122122
/**
123-
* @brief Get the index of the next item in buffer without removing it.
123+
* @brief Get the index of an item in the buffer without removing anything.
124+
*
125+
* Offset 0 is the next item in the buffer that would be returned by
126+
* `cip_get()`, offset 1 would be the following, and so on.
127+
*
128+
* Unsafe version, *must not* pass an offset that is larger than the number of
129+
* items currently in the buffer!
124130
*
125131
* @param[in,out] cib corresponding *cib* to buffer.
126132
* Must not be NULL.
127-
* @return index of next item, -1 if the buffer is empty
133+
* @param[in] offset offset from front of buffer
134+
*
135+
* @return index of item
136+
* @retval -1 if no item at @p offset exists in the buffer
128137
*/
129-
static inline int cib_peek(cib_t *__restrict cib)
138+
static inline int cib_peek_at_unsafe(cib_t *__restrict cib, unsigned offset)
130139
{
131-
if (cib_avail(cib)) {
132-
return (int)(cib->read_count & cib->mask);
140+
return (cib->read_count + offset) & cib->mask;
141+
}
142+
143+
/**
144+
* @brief Get the index of an item in the buffer without removing anything.
145+
*
146+
* Offset 0 is the next item in the buffer that would be returned by
147+
* `cip_get()`, offset 1 would be the following, and so on.
148+
*
149+
* @param[in,out] cib corresponding *cib* to buffer.
150+
* Must not be NULL.
151+
* @param[in] offset offset from front of buffer
152+
*
153+
* @return index of item
154+
* @retval -1 if no item at @p offset exists in the buffer
155+
*/
156+
static inline int cib_peek_at(cib_t *__restrict cib, unsigned offset)
157+
{
158+
if (offset < cib_avail(cib)) {
159+
return cib_peek_at_unsafe(cib, offset);
133160
}
134161

135162
return -1;
136163
}
137164

165+
/**
166+
* @brief Get the index of the next item in buffer without removing it.
167+
*
168+
* Unsafe version, *must not* be called if buffer is empty!
169+
*
170+
* @param[in,out] cib corresponding *cib* to buffer.
171+
* Must not be NULL.
172+
* @return index of next item
173+
* @retval -1 if the buffer is empty
174+
*/
175+
static inline int cib_peek_unsafe(cib_t *__restrict cib)
176+
{
177+
return cib_peek_at_unsafe(cib, 0);
178+
}
179+
180+
/**
181+
* @brief Get the index of the next item in buffer without removing it.
182+
*
183+
* @param[in,out] cib corresponding *cib* to buffer.
184+
* Must not be NULL.
185+
* @return index of next item
186+
* @retval -1 if the buffer is empty
187+
*/
188+
static inline int cib_peek(cib_t *__restrict cib)
189+
{
190+
return cib_peek_at(cib, 0);
191+
}
192+
138193
/**
139194
* @brief Get the index of the next item in buffer.
140195
*

tests/unittests/tests-core/tests-core-cib.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,83 @@ static void test_cib_peek__overflow(void)
7272
TEST_ASSERT_EQUAL_INT(TEST_CIB_SIZE-1, cib_peek(&cib));
7373
}
7474

75+
static void test_cib_peek_at(void)
76+
{
77+
/* Peeking an empty cib should give an error */
78+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 0));
79+
80+
/* Put 1 item in cib and check that we can peek it */
81+
TEST_ASSERT_EQUAL_INT( 0, cib_put(&cib));
82+
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
83+
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
84+
85+
/* Peek past the end should give an error. */
86+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 1));
87+
88+
/* Put another item in cib. */
89+
TEST_ASSERT_EQUAL_INT( 1, cib_put(&cib));
90+
91+
/* cib should now hold the indices { 0, 1 }. Test this. */
92+
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
93+
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
94+
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
95+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 2));
96+
97+
/* Put another item in cib. */
98+
TEST_ASSERT_EQUAL_INT( 2, cib_put(&cib));
99+
100+
/* cib should now hold the indices { 0, 1, 2 }. Test this. */
101+
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
102+
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
103+
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
104+
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 2));
105+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 3));
106+
107+
/* Put another item in cib. */
108+
TEST_ASSERT_EQUAL_INT( 3, cib_put(&cib));
109+
110+
/* cib should now hold the indices { 0, 1, 2, 3 }. Test this. */
111+
TEST_ASSERT_EQUAL_INT( 0, cib_peek(&cib));
112+
TEST_ASSERT_EQUAL_INT( 0, cib_peek_at(&cib, 0));
113+
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 1));
114+
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 2));
115+
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 3));
116+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 4));
117+
118+
/* Remove an item from cib. */
119+
TEST_ASSERT_EQUAL_INT( 0, cib_get(&cib));
120+
121+
/* cib should now hold the indices { 1, 2, 3 }. Test this. */
122+
TEST_ASSERT_EQUAL_INT( 1, cib_peek(&cib));
123+
TEST_ASSERT_EQUAL_INT( 1, cib_peek_at(&cib, 0));
124+
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 1));
125+
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 2));
126+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 3));
127+
128+
/* Remove another item from cib. */
129+
TEST_ASSERT_EQUAL_INT( 1, cib_get(&cib));
130+
131+
/* cib should now hold the indices { 2, 3 }. Test this. */
132+
TEST_ASSERT_EQUAL_INT( 2, cib_peek(&cib));
133+
TEST_ASSERT_EQUAL_INT( 2, cib_peek_at(&cib, 0));
134+
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 1));
135+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 2));
136+
137+
/* Remove another item from cib. */
138+
TEST_ASSERT_EQUAL_INT( 2, cib_get(&cib));
139+
140+
/* cib should now hold the indices { 3 }. Test this. */
141+
TEST_ASSERT_EQUAL_INT( 3, cib_peek(&cib));
142+
TEST_ASSERT_EQUAL_INT( 3, cib_peek_at(&cib, 0));
143+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 1));
144+
145+
/* Remove last item from cib. */
146+
TEST_ASSERT_EQUAL_INT( 3, cib_get(&cib));
147+
148+
/* Peeking an empty cib should give an error */
149+
TEST_ASSERT_EQUAL_INT(-1, cib_peek_at(&cib, 0));
150+
}
151+
75152
static void test_cib_avail(void)
76153
{
77154
TEST_ASSERT_EQUAL_INT(0, cib_avail(&cib));
@@ -111,6 +188,7 @@ Test *tests_core_cib_tests(void)
111188
new_TestFixture(test_singleton_cib),
112189
new_TestFixture(test_cib_peek),
113190
new_TestFixture(test_cib_peek__overflow),
191+
new_TestFixture(test_cib_peek_at),
114192
};
115193

116194
EMB_UNIT_TESTCALLER(core_cib_tests, set_up, NULL, fixtures);

0 commit comments

Comments
 (0)