11b868441SAndrew Jeffery #include <stdbool.h>
2*4dfefa97SAndrew Jeffery #include <stdlib.h>
31b868441SAndrew Jeffery 
41b868441SAndrew Jeffery #include "console-server.h"
5c9775ce7SJeremy Kerr 
6c9775ce7SJeremy Kerr struct rb_test_ctx {
7c9775ce7SJeremy Kerr 	struct ringbuffer_consumer *rbc;
8c9775ce7SJeremy Kerr 	bool ignore_poll;
9c9775ce7SJeremy Kerr 	bool force_only;
10c9775ce7SJeremy Kerr 	int count;
11c9775ce7SJeremy Kerr 	uint8_t *data;
125c359cc6SAndrew Jeffery 	size_t len;
13c9775ce7SJeremy Kerr };
14c9775ce7SJeremy Kerr 
ringbuffer_test_context_init(struct rb_test_ctx * ctx)15c9775ce7SJeremy Kerr void ringbuffer_test_context_init(struct rb_test_ctx *ctx)
16c9775ce7SJeremy Kerr {
17c9775ce7SJeremy Kerr 	ctx->count = 0;
18c9775ce7SJeremy Kerr 	ctx->data = NULL;
19c9775ce7SJeremy Kerr 	ctx->len = 0;
20c9775ce7SJeremy Kerr 	ctx->ignore_poll = false;
21c9775ce7SJeremy Kerr 	ctx->force_only = false;
22c9775ce7SJeremy Kerr }
23c9775ce7SJeremy Kerr 
ringbuffer_test_context_fini(struct rb_test_ctx * ctx)24c9775ce7SJeremy Kerr void ringbuffer_test_context_fini(struct rb_test_ctx *ctx)
25c9775ce7SJeremy Kerr {
26c9775ce7SJeremy Kerr 	free(ctx->data);
27c9775ce7SJeremy Kerr }
28c9775ce7SJeremy Kerr 
ringbuffer_poll_nop(void * data,size_t force_len)29a72711afSAndrew Jeffery enum ringbuffer_poll_ret ringbuffer_poll_nop(void *data __attribute__((unused)),
30a72711afSAndrew Jeffery 					     size_t force_len
31a72711afSAndrew Jeffery 					     __attribute__((unused)))
32c9775ce7SJeremy Kerr {
33c9775ce7SJeremy Kerr 	return RINGBUFFER_POLL_OK;
34c9775ce7SJeremy Kerr }
35c9775ce7SJeremy Kerr 
ringbuffer_poll_append_all(void * data,size_t force_len)36c9775ce7SJeremy Kerr enum ringbuffer_poll_ret ringbuffer_poll_append_all(void *data,
37c9775ce7SJeremy Kerr 						    size_t force_len)
38c9775ce7SJeremy Kerr {
39c9775ce7SJeremy Kerr 	struct rb_test_ctx *ctx = data;
40b70f8713SAndrew Jeffery 	size_t len;
41b70f8713SAndrew Jeffery 	size_t total_len;
42c9775ce7SJeremy Kerr 	uint8_t *buf;
43c9775ce7SJeremy Kerr 
442834c5b1SAndrew Jeffery 	if (ctx->ignore_poll) {
45c9775ce7SJeremy Kerr 		return RINGBUFFER_POLL_OK;
462834c5b1SAndrew Jeffery 	}
47c9775ce7SJeremy Kerr 
482834c5b1SAndrew Jeffery 	if (ctx->force_only && !force_len) {
49c9775ce7SJeremy Kerr 		return RINGBUFFER_POLL_OK;
502834c5b1SAndrew Jeffery 	}
51c9775ce7SJeremy Kerr 
52c9775ce7SJeremy Kerr 	ctx->count++;
53c9775ce7SJeremy Kerr 
54c9775ce7SJeremy Kerr 	total_len = 0;
55c9775ce7SJeremy Kerr 	for (;;) {
56c9775ce7SJeremy Kerr 		len = ringbuffer_dequeue_peek(ctx->rbc, total_len, &buf);
572834c5b1SAndrew Jeffery 		if (!len) {
58c9775ce7SJeremy Kerr 			break;
592834c5b1SAndrew Jeffery 		}
60c9775ce7SJeremy Kerr 
612834c5b1SAndrew Jeffery 		if (ctx->force_only && total_len + len > force_len) {
62c9775ce7SJeremy Kerr 			len = force_len - total_len;
632834c5b1SAndrew Jeffery 		}
64c9775ce7SJeremy Kerr 
65c9775ce7SJeremy Kerr 		ctx->data = realloc(ctx->data, ctx->len + len);
66c9775ce7SJeremy Kerr 		memcpy(ctx->data + ctx->len, buf, len);
67c9775ce7SJeremy Kerr 		ctx->len += len;
68c9775ce7SJeremy Kerr 		total_len += len;
69c9775ce7SJeremy Kerr 
702834c5b1SAndrew Jeffery 		if (ctx->force_only && total_len >= force_len) {
71c9775ce7SJeremy Kerr 			break;
72c9775ce7SJeremy Kerr 		}
732834c5b1SAndrew Jeffery 	}
74c9775ce7SJeremy Kerr 	ringbuffer_dequeue_commit(ctx->rbc, total_len);
75c9775ce7SJeremy Kerr 
76c9775ce7SJeremy Kerr 	return RINGBUFFER_POLL_OK;
77c9775ce7SJeremy Kerr }
78c9775ce7SJeremy Kerr 
ringbuffer_dump(struct ringbuffer * rb)79c9775ce7SJeremy Kerr void ringbuffer_dump(struct ringbuffer *rb)
80c9775ce7SJeremy Kerr {
81c9775ce7SJeremy Kerr 	struct ringbuffer_consumer *rbc;
828f548f6cSAndrew Jeffery 	size_t i;
838f548f6cSAndrew Jeffery 	int j;
84c9775ce7SJeremy Kerr 
85c9775ce7SJeremy Kerr 	printf("---- ringbuffer (%d consumer%s)\n", rb->n_consumers,
86c9775ce7SJeremy Kerr 	       rb->n_consumers == 1 ? "" : "s");
87c9775ce7SJeremy Kerr 
88c9775ce7SJeremy Kerr 	for (i = 0; i < rb->size; i++) {
89c9775ce7SJeremy Kerr 		bool has_consumer = false;
90c9775ce7SJeremy Kerr 		const char *prefix = "";
91c9775ce7SJeremy Kerr 
922834c5b1SAndrew Jeffery 		if (rb->tail == i) {
93c9775ce7SJeremy Kerr 			prefix = "tail=>";
942834c5b1SAndrew Jeffery 		}
95c9775ce7SJeremy Kerr 
96c9775ce7SJeremy Kerr 		printf("%6s %02x", prefix, rb->buf[i]);
97c9775ce7SJeremy Kerr 		for (j = 0; j < rb->n_consumers; j++) {
98c9775ce7SJeremy Kerr 			rbc = rb->consumers[j];
992834c5b1SAndrew Jeffery 			if (rbc->pos != i) {
100c9775ce7SJeremy Kerr 				continue;
1012834c5b1SAndrew Jeffery 			}
1022834c5b1SAndrew Jeffery 			if (!has_consumer) {
103c9775ce7SJeremy Kerr 				printf(" <=");
1042834c5b1SAndrew Jeffery 			}
105c9775ce7SJeremy Kerr 			printf("c[%d],len=%zd ", j, ringbuffer_len(rbc));
106c9775ce7SJeremy Kerr 			has_consumer = true;
107c9775ce7SJeremy Kerr 		}
108c9775ce7SJeremy Kerr 		printf("\n");
109c9775ce7SJeremy Kerr 	}
110c9775ce7SJeremy Kerr }
111