Skip to content

Commit 715ae32

Browse files
nordic-krchcarlescufi
authored andcommitted
lib: os: spsc_pbuf: Add option to get maximum utilization
Add option to track maximum utilization of the packet buffer. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent fa055f7 commit 715ae32

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

include/zephyr/sys/spsc_pbuf.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ extern "C" {
2424
/** @brief Flag indicating that cache shall be handled. */
2525
#define SPSC_PBUF_CACHE BIT(0)
2626

27+
/** @brief Size of the field which stores maximum utilization. */
28+
#define SPSC_PBUF_UTILIZATION_BITS 24
29+
30+
/** @brief Offset of the field which stores maximum utilization. */
31+
#define SPSC_PBUF_UTILIZATION_OFFSET 8
32+
2733
/**@} */
2834

2935
#ifndef CONFIG_SPSC_PBUF_CACHE_LINE
@@ -223,6 +229,18 @@ uint16_t spsc_pbuf_claim(struct spsc_pbuf *pb, char **buf);
223229
*/
224230
void spsc_pbuf_free(struct spsc_pbuf *pb, uint16_t len);
225231

232+
/**
233+
* @brief Get maximum utilization of the packet buffer.
234+
*
235+
* Function can be used to tune the buffer size. Feature is enabled by
236+
* CONFIG_SPSC_PBUF_UTILIZATION. Utilization is updated by the consumer.
237+
*
238+
* @param pb A packet buffer.
239+
*
240+
* @retval -ENOTSUP Feature not enabled.
241+
* @retval non-negative Maximum utilization.
242+
*/
243+
int spsc_pbuf_get_utilization(struct spsc_pbuf *pb);
226244
/**
227245
* @}
228246
*/

lib/os/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ config SPSC_PBUF_CACHE_LINE
8989

9090
endif # SPSC_PBUF_CACHE_FLAG || SPSC_PBUF_CACHE_ALWAYS
9191

92+
config SPSC_PBUF_UTILIZATION
93+
bool "Track maximum utilization"
94+
help
95+
When enabled, maximum utilization is tracked which can be used to
96+
determine the size of the packet buffer.
97+
9298
endif # SPSC_PBUF
9399

94100
config SHARED_MULTI_HEAP

lib/os/spsc_pbuf.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
#define LEN_SZ sizeof(uint32_t)
1515
#define PADDING_MARK 0xFF
1616

17+
#define GET_UTILIZATION(flags) \
18+
(((flags) >> SPSC_PBUF_UTILIZATION_OFFSET) & BIT_MASK(SPSC_PBUF_UTILIZATION_BITS))
19+
20+
#define SET_UTILIZATION(flags, val) \
21+
((flags & ~(BIT_MASK(SPSC_PBUF_UTILIZATION_BITS) << \
22+
SPSC_PBUF_UTILIZATION_OFFSET)) | \
23+
((val) << SPSC_PBUF_UTILIZATION_OFFSET))
24+
1725
/*
1826
* In order to allow allocation of continuous buffers (in zero copy manner) buffer
1927
* is handling wrapping. When it is detected that request space cannot be allocated
@@ -254,6 +262,17 @@ uint16_t spsc_pbuf_claim(struct spsc_pbuf *pb, char **buf)
254262

255263
uint32_t bytes_stored = idx_occupied(pblen, wr_idx, rd_idx);
256264

265+
/* Utilization is calculated at claiming to handle cache case when flags
266+
* and rd_idx is in the same cache line thus it should be modified only
267+
* by the consumer.
268+
*/
269+
if (IS_ENABLED(CONFIG_SPSC_PBUF_UTILIZATION) && (bytes_stored > GET_UTILIZATION(flags))) {
270+
__ASSERT_NO_MSG(bytes_stored <= BIT_MASK(SPSC_PBUF_UTILIZATION_BITS));
271+
pb->common.flags = SET_UTILIZATION(flags, bytes_stored);
272+
__sync_synchronize();
273+
cache_wb(&pb->common.flags, sizeof(pb->common.flags), flags);
274+
}
275+
257276
/* Read message len. */
258277
uint16_t len;
259278

@@ -326,3 +345,15 @@ int spsc_pbuf_read(struct spsc_pbuf *pb, char *buf, uint16_t len)
326345

327346
return plen;
328347
}
348+
349+
int spsc_pbuf_get_utilization(struct spsc_pbuf *pb)
350+
{
351+
if (!IS_ENABLED(CONFIG_SPSC_PBUF_UTILIZATION)) {
352+
return -ENOTSUP;
353+
}
354+
355+
cache_inv(&pb->common.flags, sizeof(pb->common.flags), pb->common.flags);
356+
__sync_synchronize();
357+
358+
return GET_UTILIZATION(pb->common.flags);
359+
}

0 commit comments

Comments
 (0)