diff options
Diffstat (limited to 'ringbuff.c')
| -rw-r--r-- | ringbuff.c | 108 |
1 files changed, 89 insertions, 19 deletions
| @@ -1,13 +1,15 @@ | |||
| 1 | #include <assert.h> | ||
| 2 | #include <stdbool.h> | ||
| 1 | #include <stdio.h> | 3 | #include <stdio.h> |
| 2 | #include <stdlib.h> | 4 | #include <stdlib.h> |
| 3 | #include <stdbool.h> | 5 | |
| 4 | #include "util.h" | 6 | #include "util.h" |
| 5 | 7 | ||
| 6 | typedef int T; | 8 | typedef int T; |
| 7 | 9 | ||
| 8 | struct ring_buffer { | 10 | struct ring_buffer { |
| 9 | int head, tail; | 11 | size_t head, tail; |
| 10 | T array[8]; /* fit for your needs... */ | 12 | T array[8]; /* fit for your needs... */ |
| 11 | }; | 13 | }; |
| 12 | 14 | ||
| 13 | void | 15 | void |
| @@ -17,34 +19,84 @@ ring_init(struct ring_buffer *rb) | |||
| 17 | } | 19 | } |
| 18 | 20 | ||
| 19 | bool | 21 | bool |
| 20 | ring_put(struct ring_buffer *rb, T data) | 22 | ring_push_front(struct ring_buffer *rb, T data) |
| 23 | { | ||
| 24 | const size_t prev = (rb->tail + NELEM(rb->array) - 1) % NELEM(rb->array); | ||
| 25 | |||
| 26 | if ( prev == rb->head ) | ||
| 27 | return false; | ||
| 28 | |||
| 29 | rb->array[prev] = data; | ||
| 30 | rb->tail = prev; | ||
| 31 | |||
| 32 | return true; | ||
| 33 | } | ||
| 34 | |||
| 35 | bool | ||
| 36 | ring_push_back(struct ring_buffer *rb, T data) | ||
| 21 | { | 37 | { |
| 22 | const int next = (rb->head + 1) % NELEM(rb->array); | 38 | const size_t next = (rb->head + 1) % NELEM(rb->array); |
| 23 | 39 | ||
| 24 | if ( next == rb->tail ) | 40 | if ( next == rb->tail ) |
| 25 | return false; | 41 | return false; |
| 26 | 42 | ||
| 27 | rb->array[rb->head] = data; | 43 | rb->array[rb->head] = data; |
| 28 | rb->head = next; | 44 | rb->head = next; |
| 29 | 45 | ||
| 30 | return true; | 46 | return true; |
| 31 | } | 47 | } |
| 32 | 48 | ||
| 33 | bool | 49 | bool |
| 34 | ring_get(struct ring_buffer *rb, T *data) | 50 | ring_pop_front(struct ring_buffer *rb, T *data) |
| 35 | { | 51 | { |
| 36 | if ( rb->head == rb->tail ) | 52 | if ( rb->head == rb->tail ) |
| 37 | return false; | 53 | return false; |
| 38 | 54 | ||
| 39 | const int next = (rb->tail + 1) % NELEM(rb->array); | 55 | const size_t next = (rb->tail + 1) % NELEM(rb->array); |
| 40 | 56 | ||
| 41 | *data = rb->array[rb->tail]; | 57 | *data = rb->array[rb->tail]; |
| 42 | rb->tail = next; | 58 | rb->tail = next; |
| 43 | 59 | ||
| 44 | return true; | 60 | return true; |
| 45 | } | 61 | } |
| 46 | 62 | ||
| 47 | void f() { ERROR(""); } | 63 | bool |
| 64 | ring_pop_back(struct ring_buffer *rb, T *data) | ||
| 65 | { | ||
| 66 | if ( rb->head == rb->tail ) | ||
| 67 | return false; | ||
| 68 | |||
| 69 | const size_t prev = (rb->head + NELEM(rb->array) - 1) % NELEM(rb->array); | ||
| 70 | |||
| 71 | *data = rb->array[prev]; | ||
| 72 | rb->head = prev; | ||
| 73 | |||
| 74 | return true; | ||
| 75 | } | ||
| 76 | |||
| 77 | bool | ||
| 78 | ring_put(struct ring_buffer *rb, T data) | ||
| 79 | { | ||
| 80 | return ring_push_back(rb, data); | ||
| 81 | } | ||
| 82 | |||
| 83 | bool | ||
| 84 | ring_get(struct ring_buffer *rb, T *data) | ||
| 85 | { | ||
| 86 | return ring_pop_front(rb, data); | ||
| 87 | } | ||
| 88 | |||
| 89 | void | ||
| 90 | f() | ||
| 91 | { | ||
| 92 | ERROR(""); | ||
| 93 | } | ||
| 94 | |||
| 95 | void | ||
| 96 | debug_print(const char *msg, struct ring_buffer *rb) | ||
| 97 | { | ||
| 98 | printf("%s: head: %zu, tail: %zu\n", msg, rb->head, rb->tail); | ||
| 99 | } | ||
| 48 | 100 | ||
| 49 | int | 101 | int |
| 50 | main(void) | 102 | main(void) |
| @@ -56,17 +108,35 @@ main(void) | |||
| 56 | struct ring_buffer rb = { .head = 0, .tail = 0 }; | 108 | struct ring_buffer rb = { .head = 0, .tail = 0 }; |
| 57 | #endif | 109 | #endif |
| 58 | 110 | ||
| 59 | for ( int i = 0; i != 30; ++i ) { | 111 | assert(ring_push_back(&rb, 1) == true); // 1 |
| 60 | if ( !ring_put(&rb, i) ) | 112 | assert(ring_push_back(&rb, 2) == true); // 1, 2 |
| 61 | break; | 113 | assert(ring_push_back(&rb, 3) == true); // 1, 2, 3 |
| 62 | } | 114 | assert(ring_push_back(&rb, 4) == true); // 1, 2, 3, 4 |
| 115 | |||
| 116 | debug_print("Stand", &rb); | ||
| 117 | |||
| 118 | assert(ring_push_front(&rb, 0) == true); // 0, 1, 2, 3, 4 | ||
| 119 | assert(ring_push_front(&rb, -1) == true); // -1, 0, 1, 2, 3, 4 | ||
| 120 | |||
| 121 | debug_print("Stand", &rb); | ||
| 63 | 122 | ||
| 64 | int j; | 123 | T temp; |
| 65 | while ( ring_get(&rb, &j) ) { | 124 | assert(ring_pop_back(&rb, &temp) == true); // -1, 0, 1, 2, 3 |
| 66 | printf("%d\n", j); | 125 | assert(ring_pop_front(&rb, &temp) == true); // 0, 1, 2, 3 |
| 126 | |||
| 127 | debug_print("Stand", &rb); | ||
| 128 | |||
| 129 | assert(ring_push_back(&rb, 4) == true); // 0, 1, 2, 3, 4 | ||
| 130 | assert(ring_push_back(&rb, 5) == true); // 0, 1, 2, 3, 4, 5 | ||
| 131 | assert(ring_push_back(&rb, 6) == true); // 0, 1, 2, 3, 4, 5, 6 | ||
| 132 | assert(ring_push_back(&rb, 7) == false); // 0, 1, 2, 3, 4, 5, 6 | ||
| 133 | assert(ring_push_front(&rb, 7) == false); // 0, 1, 2, 3, 4, 5, 6 | ||
| 134 | |||
| 135 | while ( ring_pop_back(&rb, &temp) ) { | ||
| 136 | printf("temp: %d\n", temp); | ||
| 67 | } | 137 | } |
| 68 | 138 | ||
| 139 | debug_print("Stand", &rb); | ||
| 140 | |||
| 69 | return EXIT_SUCCESS; | 141 | return EXIT_SUCCESS; |
| 70 | } | 142 | } |
| 71 | |||
| 72 | |||
