1 /*
2 * Copyright (c) 2021 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Test log message
10 */
11
12 #include <zephyr/sys/mpsc_pbuf.h>
13
14 #include <zephyr/tc_util.h>
15 #include <stdbool.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/ztest.h>
18 #include <zephyr/random/random.h>
19
20 #define PUT_EXT_LEN \
21 ((sizeof(union mpsc_pbuf_generic) + sizeof(void *)) / sizeof(uint32_t))
22
23 #define LEN_BITS 9
24
25 struct test_data {
26 MPSC_PBUF_HDR;
27 uint32_t len : LEN_BITS;
28 uint32_t data : 32 - MPSC_PBUF_HDR_BITS - LEN_BITS;
29 };
30
31 struct test_data_ext {
32 struct test_data hdr;
33 void *data;
34 } __packed;
35
36 struct test_data_var {
37 struct test_data hdr;
38 uint32_t data[];
39 };
40
41 union test_item {
42 struct test_data data;
43 struct test_data_ext data_ext;
44 union mpsc_pbuf_generic item;
45 };
46
get_wlen(const union mpsc_pbuf_generic * item)47 static uint32_t get_wlen(const union mpsc_pbuf_generic *item)
48 {
49 union test_item *t_item = (union test_item *)item;
50
51 return t_item->data.len;
52 }
53
54 static uint32_t drop_cnt;
55 static uint32_t exp_drop_cnt;
56 static uintptr_t exp_dropped_data[10];
57 static uint32_t exp_dropped_len[10];
58
drop(const struct mpsc_pbuf_buffer * buffer,const union mpsc_pbuf_generic * item)59 static void drop(const struct mpsc_pbuf_buffer *buffer, const union mpsc_pbuf_generic *item)
60 {
61 struct test_data_var *packet = (struct test_data_var *)item;
62
63 zassert_true(drop_cnt < exp_drop_cnt);
64 zassert_equal(packet->hdr.len, exp_dropped_len[drop_cnt],
65 "(%d) Got:%08x, Expected: %08x",
66 drop_cnt, packet->hdr.len, exp_dropped_len[drop_cnt]);
67 zassert_equal(packet->hdr.data, exp_dropped_data[drop_cnt],
68 "(%d) Got:%08x, Expected: %08x",
69 drop_cnt, packet->hdr.data, exp_dropped_data[drop_cnt]);
70 for (int i = 0; i < exp_dropped_len[drop_cnt] - 1; i++) {
71 int err = memcmp(packet->data, &exp_dropped_data[drop_cnt],
72 sizeof(uint32_t));
73
74
75 zassert_equal(err, 0);
76 }
77
78 drop_cnt++;
79 }
80
81 static uint32_t buf32[512];
82
83 static struct mpsc_pbuf_buffer_config mpsc_buf_cfg = {
84 .buf = buf32,
85 .size = ARRAY_SIZE(buf32),
86 .notify_drop = drop,
87 .get_wlen = get_wlen
88 };
89
init(struct mpsc_pbuf_buffer * buffer,uint32_t wlen,bool overwrite)90 static void init(struct mpsc_pbuf_buffer *buffer, uint32_t wlen, bool overwrite)
91 {
92 drop_cnt = 0;
93 exp_drop_cnt = 0;
94 mpsc_buf_cfg.flags = overwrite ? MPSC_PBUF_MODE_OVERWRITE : 0;
95 mpsc_buf_cfg.size = wlen;
96 mpsc_pbuf_init(buffer, &mpsc_buf_cfg);
97
98 #if CONFIG_SOC_SERIES_NRF52X
99 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
100 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
101 DWT->CYCCNT = 0;
102 #endif
103 }
104
get_cyc(void)105 static inline uint32_t get_cyc(void)
106 {
107 #if CONFIG_SOC_SERIES_NRF52X
108 return DWT->CYCCNT;
109 #else
110 return k_cycle_get_32();
111 #endif
112 }
113
item_put_no_overwrite(bool pow2)114 void item_put_no_overwrite(bool pow2)
115 {
116 struct mpsc_pbuf_buffer buffer;
117
118 init(&buffer, 4 - !pow2, false);
119
120 int repeat = buffer.size*2;
121 union test_item test_1word = {.data = {.valid = 1, .len = 1 }};
122
123 for (int i = 0; i < repeat; i++) {
124 union test_item *t;
125
126 test_1word.data.data = i;
127 mpsc_pbuf_put_word(&buffer, test_1word.item);
128
129 t = (union test_item *)mpsc_pbuf_claim(&buffer);
130 zassert_true(t);
131 zassert_equal(t->data.data, i);
132 mpsc_pbuf_free(&buffer, &t->item);
133
134 }
135
136 zassert_is_null(mpsc_pbuf_claim(&buffer));
137 }
138
ZTEST(log_buffer,test_item_put_no_overwrite)139 ZTEST(log_buffer, test_item_put_no_overwrite)
140 {
141 item_put_no_overwrite(true);
142 item_put_no_overwrite(false);
143 }
144
item_put_overwrite(bool pow2)145 void item_put_overwrite(bool pow2)
146 {
147 struct mpsc_pbuf_buffer buffer;
148
149 init(&buffer, 4 - !pow2, true);
150
151 union test_item test_1word = {.data = {.valid = 1, .len = 1 }};
152
153 exp_dropped_data[0] = 0;
154 exp_dropped_len[0] = 1;
155 exp_drop_cnt = 1;
156
157 for (int i = 0; i < buffer.size + 1; i++) {
158 test_1word.data.data = i;
159 mpsc_pbuf_put_word(&buffer, test_1word.item);
160 }
161
162 zassert_equal(drop_cnt, exp_drop_cnt,
163 "Unexpected number of dropped messages: %d", drop_cnt);
164 }
165
ZTEST(log_buffer,test_item_put_overwrite)166 ZTEST(log_buffer, test_item_put_overwrite)
167 {
168 item_put_overwrite(true);
169 item_put_overwrite(false);
170 }
171
item_put_saturate(bool pow2)172 void item_put_saturate(bool pow2)
173 {
174 struct mpsc_pbuf_buffer buffer;
175
176 init(&buffer, 4 - !pow2, false);
177
178 int repeat = buffer.size;
179 union test_item test_1word = {.data = {.valid = 1, .len = 1 }};
180 union test_item *t;
181
182 zassert_false(mpsc_pbuf_is_pending(&buffer));
183
184 for (int i = 0; i < repeat / 2; i++) {
185 test_1word.data.data = i;
186 mpsc_pbuf_put_word(&buffer, test_1word.item);
187
188 zassert_true(mpsc_pbuf_is_pending(&buffer));
189
190 t = (union test_item *)mpsc_pbuf_claim(&buffer);
191 zassert_true(t);
192 zassert_equal(t->data.data, i);
193 mpsc_pbuf_free(&buffer, &t->item);
194 }
195
196 for (int i = 0; i < repeat + 1; i++) {
197 test_1word.data.data = i;
198 mpsc_pbuf_put_word(&buffer, test_1word.item);
199 }
200
201 for (int i = 0; i < repeat; i++) {
202 t = (union test_item *)mpsc_pbuf_claim(&buffer);
203 zassert_true(t);
204 zassert_equal(t->data.data, i);
205 mpsc_pbuf_free(&buffer, &t->item);
206 }
207
208 zassert_is_null(mpsc_pbuf_claim(&buffer));
209 }
210
ZTEST(log_buffer,test_item_put_saturate)211 ZTEST(log_buffer, test_item_put_saturate)
212 {
213 item_put_saturate(true);
214 item_put_saturate(false);
215 }
216
benchmark_item_put(bool pow2)217 void benchmark_item_put(bool pow2)
218 {
219 struct mpsc_pbuf_buffer buffer;
220
221 init(&buffer, ARRAY_SIZE(buf32) - !pow2, true);
222
223 int repeat = buffer.size - 1;
224 union test_item test_1word = {.data = {.valid = 1, .len = 1 }};
225 uint32_t t = get_cyc();
226
227 for (int i = 0; i < repeat; i++) {
228 test_1word.data.data = i;
229 mpsc_pbuf_put_word(&buffer, test_1word.item);
230 }
231
232 t = get_cyc() - t;
233 PRINT("%s buffer\n", pow2 ? "pow2" : "non-pow2");
234 PRINT("single word put time: %d cycles\n", t/repeat);
235
236 t = get_cyc();
237 for (int i = 0; i < repeat; i++) {
238 union test_item *ti;
239
240 ti = (union test_item *)mpsc_pbuf_claim(&buffer);
241 zassert_true(ti);
242 zassert_equal(ti->data.data, i);
243 mpsc_pbuf_free(&buffer, &ti->item);
244 }
245
246 t = get_cyc() - t;
247 PRINT("single word item claim,free: %d cycles\n", t/repeat);
248
249 zassert_is_null(mpsc_pbuf_claim(&buffer));
250 }
251
ZTEST(log_buffer,test_benchmark_item_put)252 ZTEST(log_buffer, test_benchmark_item_put)
253 {
254 benchmark_item_put(true);
255 benchmark_item_put(false);
256 }
257
item_put_ext_no_overwrite(bool pow2)258 void item_put_ext_no_overwrite(bool pow2)
259 {
260 struct mpsc_pbuf_buffer buffer;
261
262 init(&buffer, 8 - !pow2, false);
263
264 int repeat = buffer.size * 2;
265 union test_item test_ext_item = {
266 .data = {
267 .valid = 1,
268 .len = PUT_EXT_LEN
269 }
270 };
271 void *data;
272
273 for (uintptr_t i = 0; i < repeat; i++) {
274 union test_item *t;
275
276 data = (void *)i;
277 test_ext_item.data.data = i;
278 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, data);
279
280 t = (union test_item *)mpsc_pbuf_claim(&buffer);
281 zassert_true(t);
282 zassert_equal(t->data_ext.hdr.data, i);
283 zassert_equal(t->data_ext.data, (void *)i);
284 mpsc_pbuf_free(&buffer, &t->item);
285 }
286
287 zassert_is_null(mpsc_pbuf_claim(&buffer));
288 }
289
ZTEST(log_buffer,test_item_put_ext_no_overwrite)290 ZTEST(log_buffer, test_item_put_ext_no_overwrite)
291 {
292 item_put_ext_no_overwrite(true);
293 item_put_ext_no_overwrite(false);
294 }
295
item_put_word_ext_overwrite(bool pow2)296 void item_put_word_ext_overwrite(bool pow2)
297 {
298 struct mpsc_pbuf_buffer buffer;
299
300 init(&buffer, 8 - !pow2, true);
301
302 size_t w = (sizeof(uint32_t) + sizeof(void *)) / sizeof(uint32_t);
303 int repeat = 1 + buffer.size / w;
304 union test_item test_ext_item = {
305 .data = {
306 .valid = 1,
307 .len = PUT_EXT_LEN
308 }
309 };
310
311 exp_dropped_data[0] = 0;
312 exp_dropped_len[0] = w;
313 exp_drop_cnt = 1;
314
315 for (uintptr_t i = 0; i < repeat; i++) {
316 test_ext_item.data.data = i;
317 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, (void *)i);
318 }
319
320 zassert_equal(drop_cnt, exp_drop_cnt,
321 "Unexpected number of dropped messages: %d (exp: %d)",
322 drop_cnt, exp_drop_cnt);
323 }
324
ZTEST(log_buffer,test_item_put_word_ext_overwrite)325 ZTEST(log_buffer, test_item_put_word_ext_overwrite)
326 {
327 item_put_word_ext_overwrite(true);
328 item_put_word_ext_overwrite(false);
329 }
330
item_put_ext_saturate(bool pow2)331 void item_put_ext_saturate(bool pow2)
332 {
333 struct mpsc_pbuf_buffer buffer;
334
335 init(&buffer, 8 - !pow2, false);
336
337 int repeat = buffer.size / PUT_EXT_LEN;
338 union test_item test_ext_item = {
339 .data = {
340 .valid = 1,
341 .len = PUT_EXT_LEN
342 }
343 };
344 void *data;
345 union test_item *t;
346
347 for (uintptr_t i = 0; i < repeat/2; i++) {
348 test_ext_item.data.data = i;
349 data = (void *)i;
350 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, data);
351
352 t = (union test_item *)mpsc_pbuf_claim(&buffer);
353 zassert_true(t);
354 zassert_equal(t->data.data, i);
355 mpsc_pbuf_free(&buffer, &t->item);
356 }
357
358 for (uintptr_t i = 0; i < repeat; i++) {
359 test_ext_item.data.data = i;
360 data = (void *)i;
361 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, data);
362 }
363
364 for (uintptr_t i = 0; i < repeat; i++) {
365 t = (union test_item *)mpsc_pbuf_claim(&buffer);
366 zassert_true(t);
367 zassert_equal(t->data_ext.data, (void *)i);
368 zassert_equal(t->data_ext.hdr.data, i);
369 mpsc_pbuf_free(&buffer, &t->item);
370 }
371
372 zassert_is_null(mpsc_pbuf_claim(&buffer));
373 }
374
ZTEST(log_buffer,test_item_put_ext_saturate)375 ZTEST(log_buffer, test_item_put_ext_saturate)
376 {
377 item_put_ext_saturate(true);
378 item_put_ext_saturate(false);
379 }
380
benchmark_item_put_ext(bool pow2)381 void benchmark_item_put_ext(bool pow2)
382 {
383 struct mpsc_pbuf_buffer buffer;
384
385 init(&buffer, ARRAY_SIZE(buf32) - !pow2, false);
386
387 int repeat = (buffer.size - 1) / PUT_EXT_LEN;
388 union test_item test_ext_item = {
389 .data = {
390 .valid = 1,
391 .len = PUT_EXT_LEN
392 }
393 };
394 void *data = NULL;
395 uint32_t t = get_cyc();
396
397 for (int i = 0; i < repeat; i++) {
398 test_ext_item.data.data = i;
399 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, data);
400 }
401
402 t = get_cyc() - t;
403 PRINT("%spow2 buffer\n", pow2 ? "" : "non-");
404 PRINT("put_ext time: %d cycles\n", t/repeat);
405
406 t = get_cyc();
407 for (int i = 0; i < repeat; i++) {
408 union test_item *ti;
409
410 ti = (union test_item *)mpsc_pbuf_claim(&buffer);
411 zassert_true(ti);
412 zassert_equal(ti->data.data, i);
413 mpsc_pbuf_free(&buffer, &ti->item);
414 }
415
416 t = get_cyc() - t;
417 PRINT("ext item claim,free: %d cycles\n", t/repeat);
418
419 zassert_is_null(mpsc_pbuf_claim(&buffer));
420 }
421
ZTEST(log_buffer,test_benchmark_item_put_ext)422 ZTEST(log_buffer, test_benchmark_item_put_ext)
423 {
424 benchmark_item_put_ext(true);
425 benchmark_item_put_ext(false);
426 }
427
benchmark_item_put_data(bool pow2)428 void benchmark_item_put_data(bool pow2)
429 {
430 struct mpsc_pbuf_buffer buffer;
431
432 init(&buffer, ARRAY_SIZE(buf32) - !pow2, false);
433
434 int repeat = (buffer.size - 1) / PUT_EXT_LEN;
435 union test_item test_ext_item = {
436 .data_ext = {
437 .hdr = {
438 .valid = 1,
439 .len = PUT_EXT_LEN
440 },
441 .data = NULL
442 }
443 };
444 uint32_t cyc = get_cyc();
445
446 for (uintptr_t i = 0; i < repeat; i++) {
447 test_ext_item.data_ext.hdr.data = i;
448 test_ext_item.data_ext.data = (void *)i;
449 mpsc_pbuf_put_data(&buffer, (uint32_t *)&test_ext_item,
450 PUT_EXT_LEN);
451 }
452
453 cyc = get_cyc() - cyc;
454 PRINT("%spow2 buffer\n", pow2 ? "" : "non-");
455 PRINT("put_ext time: %d cycles\n", cyc/repeat);
456
457 cyc = get_cyc();
458 for (int i = 0; i < repeat; i++) {
459 union test_item *ti;
460
461 ti = (union test_item *)mpsc_pbuf_claim(&buffer);
462 zassert_true(ti);
463 zassert_equal(ti->data.data, i);
464 mpsc_pbuf_free(&buffer, &ti->item);
465 }
466
467 cyc = get_cyc() - cyc;
468 PRINT("ext item claim,free: %d cycles\n", cyc/repeat);
469
470 zassert_is_null(mpsc_pbuf_claim(&buffer));
471 }
472
ZTEST(log_buffer,test_benchmark_item_put_data)473 ZTEST(log_buffer, test_benchmark_item_put_data)
474 {
475 benchmark_item_put_data(true);
476 benchmark_item_put_data(false);
477 }
478
item_put_data_overwrite(bool pow2)479 void item_put_data_overwrite(bool pow2)
480 {
481 struct mpsc_pbuf_buffer buffer;
482
483 init(&buffer, 8 - !pow2, true);
484
485 size_t w = (sizeof(uint32_t) + sizeof(void *)) / sizeof(uint32_t);
486 int repeat = 1 + buffer.size / w;
487 static const int len = sizeof(struct test_data_ext) / sizeof(uint32_t);
488 struct test_data_ext item = {
489 .hdr = {
490 .valid = 1,
491 .len = len
492 }
493 };
494
495 exp_dropped_data[0] = 0;
496 exp_dropped_len[0] = w;
497 exp_drop_cnt = 1;
498
499 for (uintptr_t i = 0; i < repeat; i++) {
500 void *vitem;
501 item.data = (void *)i;
502 item.hdr.data = i;
503 vitem = (uint32_t *)&item;
504 zassert_true(IS_PTR_ALIGNED(vitem, uint32_t), "unaligned ptr");
505 mpsc_pbuf_put_data(&buffer, (uint32_t *)vitem, len);
506 }
507
508 zassert_equal(drop_cnt, exp_drop_cnt,
509 "Unexpected number of dropped messages: %d", drop_cnt);
510 }
511
ZTEST(log_buffer,test_put_data_overwrite)512 ZTEST(log_buffer, test_put_data_overwrite)
513 {
514 item_put_data_overwrite(true);
515 item_put_data_overwrite(false);
516 }
517
item_alloc_commit(bool pow2)518 void item_alloc_commit(bool pow2)
519 {
520 struct mpsc_pbuf_buffer buffer;
521
522 init(&buffer, 16 - !pow2, false);
523
524 struct test_data_var *packet;
525 uint32_t len = 5;
526 int repeat = 1024;
527
528 for (int i = 0; i < repeat; i++) {
529 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len,
530 K_NO_WAIT);
531 packet->hdr.len = len;
532 for (int j = 0; j < len - 1; j++) {
533 packet->data[j] = i + j;
534 }
535
536 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)packet);
537
538 packet = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
539 zassert_true(packet);
540 zassert_equal(packet->hdr.len, len);
541
542 for (int j = 0; j < len - 1; j++) {
543 zassert_equal(packet->data[j], i + j);
544 }
545
546 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)packet);
547 }
548 }
549
ZTEST(log_buffer,test_item_alloc_commit)550 ZTEST(log_buffer, test_item_alloc_commit)
551 {
552 item_alloc_commit(true);
553 item_alloc_commit(false);
554 }
555
item_max_alloc(bool overwrite)556 void item_max_alloc(bool overwrite)
557 {
558 struct mpsc_pbuf_buffer buffer;
559 struct test_data_var *packet;
560
561 init(&buffer, 8, overwrite);
562
563 /* First try to allocate the biggest possible packet. */
564 for (int i = 0; i < 2; i++) {
565 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer,
566 buffer.size,
567 K_NO_WAIT);
568 zassert_true(packet != NULL);
569 packet->hdr.len = buffer.size;
570 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)packet);
571
572 packet = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
573 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)packet);
574 }
575
576 /* Too big packet cannot be allocated. */
577 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer,
578 buffer.size + 1,
579 K_NO_WAIT);
580 zassert_true(packet == NULL);
581 }
582
ZTEST(log_buffer,test_item_max_alloc)583 ZTEST(log_buffer, test_item_max_alloc)
584 {
585 item_max_alloc(true);
586 item_max_alloc(false);
587 }
588
saturate_buffer_uneven(struct mpsc_pbuf_buffer * buffer,uint32_t len)589 static uint32_t saturate_buffer_uneven(struct mpsc_pbuf_buffer *buffer,
590 uint32_t len)
591 {
592 struct test_data_var *packet;
593 uint32_t uneven = 3;
594 uint32_t cnt = 0;
595 int repeat =
596 uneven + ((buffer->size - (uneven * len)) / len);
597
598 /* Put some data to include wrapping */
599 for (int i = 0; i < uneven; i++) {
600 packet = (struct test_data_var *)mpsc_pbuf_alloc(buffer, len,
601 K_NO_WAIT);
602 packet->hdr.len = len;
603 mpsc_pbuf_commit(buffer, (union mpsc_pbuf_generic *)packet);
604
605 packet = (struct test_data_var *)mpsc_pbuf_claim(buffer);
606 zassert_true(packet);
607 mpsc_pbuf_free(buffer, (union mpsc_pbuf_generic *)packet);
608 }
609
610 for (int i = 0; i < repeat; i++) {
611 packet = (struct test_data_var *)mpsc_pbuf_alloc(buffer, len,
612 K_NO_WAIT);
613 zassert_true(packet);
614 packet->hdr.len = len;
615 packet->hdr.data = i;
616 for (int j = 0; j < len - 1; j++) {
617 packet->data[j] = i + j;
618 }
619
620 mpsc_pbuf_commit(buffer, (union mpsc_pbuf_generic *)packet);
621 cnt++;
622 }
623
624 return cnt;
625 }
626
item_alloc_commit_saturate(bool pow2)627 void item_alloc_commit_saturate(bool pow2)
628 {
629 struct mpsc_pbuf_buffer buffer;
630
631 init(&buffer, 32 - !pow2, false);
632
633 saturate_buffer_uneven(&buffer, 5);
634
635 struct test_data_var *packet;
636 uint32_t len = 5;
637
638 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len,
639 K_NO_WAIT);
640 zassert_is_null(packet);
641
642 /* Get one packet from the buffer. */
643 packet = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
644 zassert_true(packet);
645 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)packet);
646
647 /* and try to allocate one more time, this time with success. */
648 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len,
649 K_NO_WAIT);
650 zassert_true(packet);
651 }
652
ZTEST(log_buffer,test_item_alloc_commit_saturate)653 ZTEST(log_buffer, test_item_alloc_commit_saturate)
654 {
655 item_alloc_commit_saturate(true);
656 item_alloc_commit_saturate(false);
657 }
658
item_alloc_preemption(bool pow2)659 void item_alloc_preemption(bool pow2)
660 {
661 struct mpsc_pbuf_buffer buffer;
662
663 init(&buffer, ARRAY_SIZE(buf32) - !pow2, false);
664
665 struct test_data_var *p0;
666 struct test_data_var *p1;
667 struct test_data_var *p;
668
669 p0 = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, 10, K_NO_WAIT);
670 zassert_true(p0);
671 p0->hdr.len = 10;
672
673 /* Check that no packet is yet available */
674 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
675 zassert_is_null(p);
676
677 p1 = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, 20, K_NO_WAIT);
678 zassert_true(p1);
679 p1->hdr.len = 20;
680
681 /* Commit p1, p0 is still not committed, there should be no packets
682 * available for reading.
683 */
684 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p1);
685
686 /* Check that no packet is yet available */
687 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
688 zassert_is_null(p);
689
690 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p0);
691
692 /* Validate that p0 is the first one. */
693 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
694 zassert_true(p);
695 zassert_equal(p->hdr.len, 10);
696 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p);
697
698 /* Validate that p1 is the next one. */
699 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
700 zassert_true(p);
701 zassert_equal(p->hdr.len, 20);
702 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p);
703
704 /* No more packets. */
705 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
706 zassert_is_null(p);
707 }
708
ZTEST(log_buffer,test_item_alloc_preemption)709 ZTEST(log_buffer, test_item_alloc_preemption)
710 {
711 item_alloc_preemption(true);
712 item_alloc_preemption(false);
713 }
714
overwrite(bool pow2)715 void overwrite(bool pow2)
716 {
717 struct test_data_var *p;
718 uint32_t fill_len = 5;
719 uint32_t len0, len1;
720 struct mpsc_pbuf_buffer buffer;
721
722 init(&buffer, 32 - !pow2, true);
723 uint32_t packet_cnt = saturate_buffer_uneven(&buffer, fill_len);
724
725 zassert_equal(drop_cnt, exp_drop_cnt, NULL);
726
727 exp_dropped_data[0] = 0;
728 exp_dropped_len[0] = fill_len;
729 exp_drop_cnt++;
730 exp_dropped_data[1] = 1;
731 exp_dropped_len[1] = fill_len;
732 exp_drop_cnt++;
733
734 len0 = 6;
735 p = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len0, K_NO_WAIT);
736
737 p->hdr.len = len0;
738 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p);
739 zassert_equal(drop_cnt, exp_drop_cnt);
740
741 /* Request allocation which will require dropping 2 packets. */
742 len1 = 9;
743 exp_dropped_data[1] = 1;
744 exp_dropped_len[1] = fill_len;
745 exp_dropped_data[2] = 2;
746 exp_dropped_len[2] = fill_len;
747 exp_drop_cnt = 3;
748
749 p = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len1, K_NO_WAIT);
750
751 p->hdr.len = len1;
752 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p);
753 zassert_equal(drop_cnt, exp_drop_cnt);
754
755 for (int i = 0; i < (packet_cnt - drop_cnt); i++) {
756 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
757 zassert_true(p);
758 zassert_equal(p->hdr.len, fill_len);
759 zassert_equal(p->hdr.data, i + drop_cnt);
760 for (int j = 0; j < fill_len - 1; j++) {
761 zassert_equal(p->data[j], p->hdr.data + j);
762 }
763
764 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p);
765 }
766
767 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
768 zassert_true(p);
769 zassert_equal(p->hdr.len, len0);
770 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p);
771
772 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
773 zassert_true(p);
774 zassert_equal(p->hdr.len, len1);
775 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p);
776
777 p = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
778 zassert_is_null(p);
779 }
780
ZTEST(log_buffer,test_overwrite)781 ZTEST(log_buffer, test_overwrite)
782 {
783 overwrite(true);
784 overwrite(false);
785 }
786
overwrite_while_claimed(bool pow2)787 void overwrite_while_claimed(bool pow2)
788 {
789 struct test_data_var *p0;
790 struct test_data_var *p1;
791 struct mpsc_pbuf_buffer buffer;
792
793 init(&buffer, 32 - !pow2, true);
794
795 uint32_t fill_len = 5;
796 uint32_t len = 6;
797 uint32_t packet_cnt = saturate_buffer_uneven(&buffer, fill_len);
798
799 /* Start by claiming a packet. Buffer is now full. Allocation shall
800 * skip claimed packed and drop the next one.
801 */
802 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
803 zassert_true(p0);
804 zassert_equal(p0->hdr.len, fill_len);
805
806 exp_dropped_data[0] = p0->hdr.data + 1; /* next packet is dropped */
807 exp_dropped_len[0] = fill_len;
808 exp_dropped_data[1] = p0->hdr.data + 2; /* next packet is dropped */
809 exp_dropped_len[1] = fill_len;
810 exp_drop_cnt = 2;
811 p1 = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, 6, K_NO_WAIT);
812 zassert_equal(drop_cnt, exp_drop_cnt);
813 p1->hdr.len = len;
814 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p1);
815
816 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p0);
817
818 for (int i = 0; i < packet_cnt - drop_cnt - 1; i++) {
819 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
820 zassert_true(p0);
821 zassert_equal(p0->hdr.len, fill_len);
822 zassert_equal(p0->hdr.data, i + drop_cnt + 1);
823 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p0);
824 }
825
826 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
827 zassert_true(p0);
828 zassert_equal(p0->hdr.len, len);
829
830 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
831 zassert_is_null(p0);
832 }
833
ZTEST(log_buffer,test_overwrite_while_claimed)834 ZTEST(log_buffer, test_overwrite_while_claimed)
835 {
836 overwrite_while_claimed(true);
837 overwrite_while_claimed(false);
838 }
839
overwrite_while_claimed2(bool pow2)840 void overwrite_while_claimed2(bool pow2)
841 {
842 struct test_data_var *p0;
843 struct test_data_var *p1;
844 struct mpsc_pbuf_buffer buffer;
845
846 init(&buffer, 32 - !pow2, true);
847
848 uint32_t fill_len = 1;
849 uint32_t len = 3;
850 uint32_t packet_cnt = saturate_buffer_uneven(&buffer, fill_len);
851
852 /* Start by claiming a packet. Buffer is now full. Allocation shall
853 * skip claimed packed and drop the next one.
854 */
855 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
856 zassert_true(p0);
857 zassert_equal(p0->hdr.len, fill_len);
858
859 exp_dropped_data[0] = p0->hdr.data + 1; /* next packet is dropped */
860 exp_dropped_len[0] = fill_len;
861 exp_dropped_data[1] = p0->hdr.data + 2; /* next packet is dropped */
862 exp_dropped_len[1] = fill_len;
863 exp_dropped_data[2] = p0->hdr.data + 3; /* next packet is dropped */
864 exp_dropped_len[2] = fill_len;
865 exp_drop_cnt = 3;
866 p1 = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len, K_NO_WAIT);
867
868 zassert_equal(drop_cnt, exp_drop_cnt);
869 p1->hdr.len = len;
870 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)p1);
871
872 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p0);
873
874 for (int i = 0; i < packet_cnt - drop_cnt - 1; i++) {
875 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
876 zassert_true(p0);
877 zassert_equal(p0->hdr.len, fill_len);
878 zassert_equal(p0->hdr.data, i + drop_cnt + 1);
879 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)p0);
880 }
881
882 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
883 zassert_true(p0);
884 zassert_equal(p0->hdr.len, len);
885
886 p0 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
887 zassert_is_null(p0);
888 }
889
ZTEST(log_buffer,test_overwrite_while_claimed2)890 ZTEST(log_buffer, test_overwrite_while_claimed2)
891 {
892 overwrite_while_claimed2(true);
893 overwrite_while_claimed2(false);
894 }
895
896 static uintptr_t current_rd_idx;
897
validate_packet(struct test_data_var * packet)898 static void validate_packet(struct test_data_var *packet)
899 {
900 zassert_equal((uintptr_t)packet->hdr.data, current_rd_idx,
901 "Got %d, expected: %d",
902 (uintptr_t)packet->hdr.data, current_rd_idx);
903 current_rd_idx++;
904 }
905
consistent_drop(const struct mpsc_pbuf_buffer * buffer,const union mpsc_pbuf_generic * item)906 static void consistent_drop(const struct mpsc_pbuf_buffer *buffer,
907 const union mpsc_pbuf_generic *item)
908 {
909 validate_packet((struct test_data_var *)item);
910 }
911
rand_get(uint32_t min,uint32_t max)912 uint32_t rand_get(uint32_t min, uint32_t max)
913 {
914 return min + (sys_rand32_get() % max);
915 }
916
ZTEST(log_buffer,test_overwrite_consistency)917 ZTEST(log_buffer, test_overwrite_consistency)
918 {
919 struct mpsc_pbuf_buffer buffer;
920 static struct mpsc_pbuf_buffer_config cfg = {
921 .buf = buf32,
922 .size = ARRAY_SIZE(buf32),
923 .notify_drop = consistent_drop,
924 .get_wlen = get_wlen,
925 .flags = MPSC_PBUF_MODE_OVERWRITE
926 };
927
928 mpsc_pbuf_init(&buffer, &cfg);
929 int repeat = 50000;
930 int id = 0;
931
932 while (id < repeat) {
933 struct test_data_var *tdv = NULL;
934 bool alloc_during_claim = (rand_get(1, 5) <= 2);
935
936 /* Occasionally claim buffer to simulate that claiming is
937 * interrupted by allocation.
938 */
939 if (alloc_during_claim) {
940 tdv = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
941 if (tdv) {
942 validate_packet(tdv);
943 }
944 }
945
946 uint32_t wr_cnt = rand_get(1, 15);
947
948 for (int i = 0; i < wr_cnt; i++) {
949 uint32_t wlen = rand_get(1, 15);
950 struct test_data_var *tdv2;
951
952 tdv2 = (struct test_data_var *)mpsc_pbuf_alloc(&buffer,
953 wlen,
954 K_NO_WAIT);
955 tdv2->hdr.len = wlen;
956 tdv2->hdr.data = id++;
957 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)tdv2);
958 }
959
960 /* Put back item claimed before committing new items. */
961 if (tdv) {
962 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)tdv);
963 }
964
965 uint32_t rd_cnt = rand_get(1, 30);
966
967 for (int i = 0; i < rd_cnt; i++) {
968 struct test_data_var *tdv2;
969
970 tdv2 = (struct test_data_var *)mpsc_pbuf_claim(&buffer);
971 if (!tdv2) {
972 continue;
973 }
974
975 validate_packet(tdv2);
976 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)tdv2);
977 }
978 }
979 }
980
981 K_THREAD_STACK_DEFINE(t1_stack, 1024);
982 K_THREAD_STACK_DEFINE(t2_stack, 1024);
983
984 static k_thread_stack_t *stacks[2] = {t1_stack, t2_stack};
985 static struct k_thread threads[2];
986 static k_tid_t tids[2];
987
t_entry(void * p0,void * p1,void * p2)988 void t_entry(void *p0, void *p1, void *p2)
989 {
990 struct mpsc_pbuf_buffer *buffer = p0;
991 uintptr_t wait_ms = (uintptr_t)p1;
992 struct test_data_ext *t;
993 void *vt;
994
995 t = (struct test_data_ext *)mpsc_pbuf_alloc(buffer,
996 sizeof(*t) / sizeof(uint32_t),
997 K_MSEC(1));
998 zassert_is_null(t);
999
1000 t = (struct test_data_ext *)mpsc_pbuf_alloc(buffer,
1001 sizeof(*t) / sizeof(uint32_t),
1002 K_MSEC(wait_ms));
1003 t->hdr.len = PUT_EXT_LEN;
1004 t->data = k_current_get();
1005
1006 vt = t;
1007 zassert_true(IS_PTR_ALIGNED(vt, union mpsc_pbuf_generic), "unaligned ptr");
1008 mpsc_pbuf_commit(buffer, (union mpsc_pbuf_generic *)vt);
1009 while (1) {
1010 k_sleep(K_MSEC(10));
1011 }
1012 }
1013
start_threads(struct mpsc_pbuf_buffer * buffer)1014 void start_threads(struct mpsc_pbuf_buffer *buffer)
1015 {
1016 int prio = 2;
1017 uintptr_t wait_ms = 1000;
1018
1019 for (int i = 0; i < ARRAY_SIZE(threads); i++) {
1020 tids[i] = k_thread_create(&threads[i], stacks[i], 1024, t_entry,
1021 buffer, (void *)wait_ms, NULL,
1022 prio--,
1023 0, K_NO_WAIT);
1024 }
1025
1026 k_sleep(K_MSEC(10));
1027
1028 for (int i = 0; i < ARRAY_SIZE(threads); i++) {
1029 k_ticks_t t = k_thread_timeout_remaining_ticks(tids[i]);
1030 k_ticks_t exp_wait = k_ms_to_ticks_ceil32(wait_ms);
1031
1032 /* Threads shall be blocked, waiting for available space. */
1033 zassert_within(t, exp_wait, k_ms_to_ticks_ceil32(20));
1034 }
1035 }
1036
1037 /* Test creates two threads which pends on the buffer until there is a space
1038 * available. When enough buffers is released threads are woken up and they
1039 * allocate packets.
1040 */
ZTEST(log_buffer,test_pending_alloc)1041 ZTEST(log_buffer, test_pending_alloc)
1042 {
1043 int prio = k_thread_priority_get(k_current_get());
1044 struct mpsc_pbuf_buffer buffer;
1045 void *vt;
1046
1047 k_thread_priority_set(k_current_get(), 3);
1048
1049 init(&buffer, ARRAY_SIZE(buf32) - 1, true);
1050
1051 uint32_t fill_len = 1;
1052 uint32_t packet_cnt = saturate_buffer_uneven(&buffer, fill_len);
1053
1054 start_threads(&buffer);
1055
1056 k_sleep(K_MSEC(1));
1057
1058 for (int i = 0; i < packet_cnt; i++) {
1059 union test_item *t = (union test_item *)mpsc_pbuf_claim(&buffer);
1060
1061 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)t);
1062 }
1063
1064
1065 for (int i = 0; i < 2; i++) {
1066 struct test_data_ext *t =
1067 (struct test_data_ext *)mpsc_pbuf_claim(&buffer);
1068
1069 zassert_true(t);
1070 zassert_equal(t->data, tids[ARRAY_SIZE(tids) - 1 - i]);
1071 vt = t;
1072 zassert_true(IS_PTR_ALIGNED(vt, union mpsc_pbuf_generic), "unaligned ptr");
1073 mpsc_pbuf_free(&buffer, (union mpsc_pbuf_generic *)vt);
1074 }
1075
1076 zassert_equal(mpsc_pbuf_claim(&buffer), NULL, "No more packets.");
1077 k_thread_priority_set(k_current_get(), prio);
1078 }
1079
check_packet(struct mpsc_pbuf_buffer * buffer,char exp_c)1080 static void check_packet(struct mpsc_pbuf_buffer *buffer, char exp_c)
1081 {
1082 union test_item claimed_item;
1083 const union mpsc_pbuf_generic *claimed;
1084
1085 claimed = mpsc_pbuf_claim(buffer);
1086 zassert_true(claimed, NULL);
1087 claimed_item.item = *claimed;
1088 zassert_equal(claimed_item.data.data, exp_c, NULL);
1089
1090 mpsc_pbuf_free(buffer, claimed);
1091 }
1092
ZTEST(log_buffer,test_put_while_claim)1093 ZTEST(log_buffer, test_put_while_claim)
1094 {
1095 struct mpsc_pbuf_buffer buffer;
1096 uint32_t buffer_storage[4];
1097 const union mpsc_pbuf_generic *claimed;
1098 struct mpsc_pbuf_buffer_config buffer_config = {
1099 .buf = buffer_storage,
1100 .size = 4,
1101 .notify_drop = drop,
1102 .get_wlen = get_wlen,
1103 .flags = MPSC_PBUF_SIZE_POW2 | MPSC_PBUF_MODE_OVERWRITE
1104 };
1105 union test_item claimed_item;
1106 union test_item item = {
1107 .data = {
1108 .valid = 1,
1109 .busy = 0,
1110 .len = 1,
1111 .data = (uint32_t)'a'
1112 }
1113 };
1114
1115 exp_drop_cnt = 0;
1116 drop_cnt = 0;
1117 mpsc_pbuf_init(&buffer, &buffer_config);
1118 /* Expect buffer = {} */
1119
1120 for (int i = 0; i < buffer.size; ++i) {
1121 mpsc_pbuf_put_word(&buffer, item.item);
1122 item.data.data++;
1123 }
1124
1125 /* Expect buffer = {a, b, c, d}. Adding new word will drop 'a'. */
1126 exp_dropped_data[exp_drop_cnt] = (uint32_t)'a';
1127 exp_dropped_len[exp_drop_cnt] = 1;
1128 exp_drop_cnt++;
1129
1130 item.data.data = 'e';
1131 mpsc_pbuf_put_word(&buffer, item.item);
1132 zassert_equal(drop_cnt, exp_drop_cnt, NULL);
1133 /* Expect buffer = {e, b, c, d} */
1134
1135 claimed = mpsc_pbuf_claim(&buffer);
1136 zassert_true(claimed, NULL);
1137 claimed_item.item = *claimed;
1138 zassert_equal(claimed_item.data.data, (uint32_t)'b', NULL);
1139
1140 /* Expect buffer = {e, B, c, d}. Adding new will drop 'c'. */
1141 exp_dropped_data[exp_drop_cnt] = (int)'c';
1142 exp_dropped_len[exp_drop_cnt] = 1;
1143 exp_drop_cnt++;
1144
1145 item.data.data = 'f';
1146 mpsc_pbuf_put_word(&buffer, item.item);
1147 zassert_equal(drop_cnt, exp_drop_cnt, NULL);
1148 /* Expect buffer = {e, B, f, d}, Adding new will drop 'd'. */
1149
1150 exp_dropped_data[exp_drop_cnt] = (int)'d';
1151 exp_dropped_len[exp_drop_cnt] = 1;
1152 exp_drop_cnt++;
1153 item.data.data = 'g';
1154 mpsc_pbuf_put_word(&buffer, item.item);
1155 zassert_equal(drop_cnt, exp_drop_cnt, NULL);
1156 /* Expect buffer = {e, B, f, g} */
1157
1158 mpsc_pbuf_free(&buffer, claimed);
1159 /* Expect buffer = {e -, f, g} */
1160
1161 check_packet(&buffer, 'e');
1162 /* Expect buffer = {-, -, f, g} */
1163
1164 check_packet(&buffer, 'f');
1165 /* Expect buffer = {-, -, -, g} */
1166
1167 check_packet(&buffer, 'g');
1168 /* Expect buffer = {-, -, -, -} */
1169
1170 claimed = mpsc_pbuf_claim(&buffer);
1171 zassert_equal(claimed, NULL, NULL);
1172 }
1173
check_usage(struct mpsc_pbuf_buffer * buffer,uint32_t now,int exp_err,uint32_t max,uint32_t line)1174 static void check_usage(struct mpsc_pbuf_buffer *buffer,
1175 uint32_t now, int exp_err, uint32_t max, uint32_t line)
1176 {
1177 uint32_t size;
1178 uint32_t usage;
1179 int err;
1180
1181 mpsc_pbuf_get_utilization(buffer, &size, &usage);
1182 zassert_equal(size / sizeof(int), buffer->size - 1, "%d: got:%d, exp:%d",
1183 line, size / sizeof(int), buffer->size - 1);
1184 zassert_equal(usage, now, "%d: got:%d, exp:%d", line, usage, now);
1185
1186 err = mpsc_pbuf_get_max_utilization(buffer, &usage);
1187 zassert_equal(err, exp_err);
1188 if (err == 0) {
1189 zassert_equal(usage, max, "%d: got:%d, exp:%d", line, usage, max);
1190 }
1191 }
1192
1193 #define CHECK_USAGE(buffer, now, max) \
1194 check_usage(buffer, (now) * sizeof(int), 0, (max) * sizeof(int), __LINE__)
1195
ignore_drop(const struct mpsc_pbuf_buffer * buffer,const union mpsc_pbuf_generic * item)1196 static void ignore_drop(const struct mpsc_pbuf_buffer *buffer,
1197 const union mpsc_pbuf_generic *item)
1198 {
1199 ARG_UNUSED(buffer);
1200 ARG_UNUSED(item);
1201 }
1202
ZTEST(log_buffer,test_utilization)1203 ZTEST(log_buffer, test_utilization)
1204 {
1205 struct mpsc_pbuf_buffer buffer;
1206 struct mpsc_pbuf_buffer_config config = {
1207 .buf = buf32,
1208 .size = ARRAY_SIZE(buf32),
1209 .notify_drop = ignore_drop,
1210 .get_wlen = get_wlen,
1211 .flags = 0 /* Utilization not supported. */
1212 };
1213
1214 mpsc_pbuf_init(&buffer, &config);
1215
1216 check_usage(&buffer, 0, -ENOTSUP, 0, __LINE__);
1217
1218 /* Initialize with max utilization support. */
1219 config.flags = MPSC_PBUF_MAX_UTILIZATION;
1220 mpsc_pbuf_init(&buffer, &config);
1221
1222 CHECK_USAGE(&buffer, 0, 0);
1223
1224 union test_item test_1word = {.data = {.valid = 1, .len = 1 }};
1225 union test_item test_ext_item = {
1226 .data = {
1227 .valid = 1,
1228 .len = PUT_EXT_LEN
1229 }
1230 };
1231 union test_item *t;
1232
1233 mpsc_pbuf_put_word(&buffer, test_1word.item);
1234
1235 CHECK_USAGE(&buffer, 1, 1);
1236
1237 mpsc_pbuf_put_word_ext(&buffer, test_ext_item.item, NULL);
1238
1239 CHECK_USAGE(&buffer, 1 + PUT_EXT_LEN, 1 + PUT_EXT_LEN);
1240
1241 t = (union test_item *)mpsc_pbuf_claim(&buffer);
1242
1243 zassert_true(t != NULL);
1244 CHECK_USAGE(&buffer, 1 + PUT_EXT_LEN, 1 + PUT_EXT_LEN);
1245 mpsc_pbuf_free(&buffer, &t->item);
1246
1247 t = (union test_item *)mpsc_pbuf_claim(&buffer);
1248 zassert_true(t != NULL);
1249
1250 CHECK_USAGE(&buffer, PUT_EXT_LEN, 1 + PUT_EXT_LEN);
1251
1252 mpsc_pbuf_free(&buffer, &t->item);
1253
1254 CHECK_USAGE(&buffer, 0, 1 + PUT_EXT_LEN);
1255
1256 union test_item test_ext_item2 = {
1257 .data_ext = {
1258 .hdr = {
1259 .valid = 1,
1260 .len = PUT_EXT_LEN
1261 },
1262 .data = NULL
1263 }
1264 };
1265
1266 mpsc_pbuf_put_data(&buffer, (uint32_t *)&test_ext_item2, PUT_EXT_LEN);
1267
1268 CHECK_USAGE(&buffer, PUT_EXT_LEN, 1 + PUT_EXT_LEN);
1269
1270 t = (union test_item *)mpsc_pbuf_claim(&buffer);
1271 zassert_true(t != NULL);
1272 mpsc_pbuf_free(&buffer, &t->item);
1273
1274 CHECK_USAGE(&buffer, 0, 1 + PUT_EXT_LEN);
1275
1276 memset(&buffer, 0, sizeof(buffer));
1277 /* Initialize to reset indexes. */
1278 mpsc_pbuf_init(&buffer, &config);
1279
1280 struct test_data_var *packet;
1281 uint32_t len = 5;
1282 uint32_t i;
1283
1284 for (i = 0; i < (buffer.size - 1) / len; i++) {
1285 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len, K_NO_WAIT);
1286 packet->hdr.len = len;
1287
1288 mpsc_pbuf_commit(&buffer, (union mpsc_pbuf_generic *)packet);
1289 CHECK_USAGE(&buffer, len * (i + 1), len * (i + 1));
1290 }
1291
1292 packet = (struct test_data_var *)mpsc_pbuf_alloc(&buffer, len, K_NO_WAIT);
1293
1294 zassert_true(packet == NULL);
1295 }
1296
1297 /*test case main entry*/
1298 ZTEST_SUITE(log_buffer, NULL, NULL, NULL, NULL, NULL);
1299