Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
libs/HeapRing.cpp@3:f151d08d335c, 2014-03-02 (annotated)
- Committer:
- Bigcheese
- Date:
- Sun Mar 02 06:33:08 2014 +0000
- Revision:
- 3:f151d08d335c
- Parent:
- 2:1df0b61d3b5a
Bunch of stuff. Need to locally merge in updated USB changes.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Michael J. Spencer |
2:1df0b61d3b5a | 1 | #include "HeapRing.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 2 | |
Michael J. Spencer |
2:1df0b61d3b5a | 3 | #include <cstdlib> |
Michael J. Spencer |
2:1df0b61d3b5a | 4 | |
Michael J. Spencer |
2:1df0b61d3b5a | 5 | #include "cmsis.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 6 | |
Michael J. Spencer |
2:1df0b61d3b5a | 7 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 8 | * constructors |
Michael J. Spencer |
2:1df0b61d3b5a | 9 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 10 | |
Michael J. Spencer |
2:1df0b61d3b5a | 11 | template<class kind> HeapRing<kind>::HeapRing() |
Michael J. Spencer |
2:1df0b61d3b5a | 12 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 13 | head_i = tail_i = length = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 14 | ring = NULL; |
Michael J. Spencer |
2:1df0b61d3b5a | 15 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 16 | |
Michael J. Spencer |
2:1df0b61d3b5a | 17 | template<class kind> HeapRing<kind>::HeapRing(unsigned int length) |
Michael J. Spencer |
2:1df0b61d3b5a | 18 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 19 | head_i = tail_i = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 20 | ring = new kind[length]; |
Michael J. Spencer |
2:1df0b61d3b5a | 21 | // TODO: handle allocation failure |
Michael J. Spencer |
2:1df0b61d3b5a | 22 | this->length = length; |
Michael J. Spencer |
2:1df0b61d3b5a | 23 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 24 | |
Michael J. Spencer |
2:1df0b61d3b5a | 25 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 26 | * destructor |
Michael J. Spencer |
2:1df0b61d3b5a | 27 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 28 | |
Michael J. Spencer |
2:1df0b61d3b5a | 29 | template<class kind> HeapRing<kind>::~HeapRing() |
Michael J. Spencer |
2:1df0b61d3b5a | 30 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 31 | head_i = tail_i = length = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 32 | if (ring) |
Michael J. Spencer |
2:1df0b61d3b5a | 33 | delete [] ring; |
Michael J. Spencer |
2:1df0b61d3b5a | 34 | ring = NULL; |
Michael J. Spencer |
2:1df0b61d3b5a | 35 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 36 | |
Michael J. Spencer |
2:1df0b61d3b5a | 37 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 38 | * index accessors (protected) |
Michael J. Spencer |
2:1df0b61d3b5a | 39 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 40 | |
Michael J. Spencer |
2:1df0b61d3b5a | 41 | template<class kind> unsigned int HeapRing<kind>::next(unsigned int item) |
Michael J. Spencer |
2:1df0b61d3b5a | 42 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 43 | if (length == 0) |
Michael J. Spencer |
2:1df0b61d3b5a | 44 | return 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 45 | |
Michael J. Spencer |
2:1df0b61d3b5a | 46 | if (++item >= length) |
Michael J. Spencer |
2:1df0b61d3b5a | 47 | return 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 48 | |
Michael J. Spencer |
2:1df0b61d3b5a | 49 | return item; |
Michael J. Spencer |
2:1df0b61d3b5a | 50 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 51 | |
Michael J. Spencer |
2:1df0b61d3b5a | 52 | template<class kind> unsigned int HeapRing<kind>::prev(unsigned int item) |
Michael J. Spencer |
2:1df0b61d3b5a | 53 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 54 | if (length == 0) |
Michael J. Spencer |
2:1df0b61d3b5a | 55 | return 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 56 | |
Michael J. Spencer |
2:1df0b61d3b5a | 57 | if (item == 0) |
Michael J. Spencer |
2:1df0b61d3b5a | 58 | return (length - 1); |
Michael J. Spencer |
2:1df0b61d3b5a | 59 | else |
Michael J. Spencer |
2:1df0b61d3b5a | 60 | return (item - 1); |
Michael J. Spencer |
2:1df0b61d3b5a | 61 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 62 | |
Michael J. Spencer |
2:1df0b61d3b5a | 63 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 64 | * reference accessors |
Michael J. Spencer |
2:1df0b61d3b5a | 65 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 66 | |
Michael J. Spencer |
2:1df0b61d3b5a | 67 | template<class kind> kind& HeapRing<kind>::head() |
Michael J. Spencer |
2:1df0b61d3b5a | 68 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 69 | return ring[head_i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 70 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 71 | |
Michael J. Spencer |
2:1df0b61d3b5a | 72 | template<class kind> kind& HeapRing<kind>::tail() |
Michael J. Spencer |
2:1df0b61d3b5a | 73 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 74 | return ring[tail_i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 75 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 76 | |
Michael J. Spencer |
2:1df0b61d3b5a | 77 | template<class kind> kind& HeapRing<kind>::item(unsigned int i) |
Michael J. Spencer |
2:1df0b61d3b5a | 78 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 79 | return ring[i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 80 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 81 | |
Michael J. Spencer |
2:1df0b61d3b5a | 82 | template<class kind> void HeapRing<kind>::push_front(kind& item) |
Michael J. Spencer |
2:1df0b61d3b5a | 83 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 84 | ring[head_i] = item; |
Michael J. Spencer |
2:1df0b61d3b5a | 85 | head_i = next(head_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 86 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 87 | |
Michael J. Spencer |
2:1df0b61d3b5a | 88 | template<class kind> kind& HeapRing<kind>::pop_back() |
Michael J. Spencer |
2:1df0b61d3b5a | 89 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 90 | kind& r = ring[tail_i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 91 | tail_i = next(tail_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 92 | return r; |
Michael J. Spencer |
2:1df0b61d3b5a | 93 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 94 | |
Michael J. Spencer |
2:1df0b61d3b5a | 95 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 96 | * pointer accessors |
Michael J. Spencer |
2:1df0b61d3b5a | 97 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 98 | |
Michael J. Spencer |
2:1df0b61d3b5a | 99 | template<class kind> kind* HeapRing<kind>::head_ref() |
Michael J. Spencer |
2:1df0b61d3b5a | 100 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 101 | return &ring[head_i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 102 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 103 | |
Michael J. Spencer |
2:1df0b61d3b5a | 104 | template<class kind> kind* HeapRing<kind>::tail_ref() |
Michael J. Spencer |
2:1df0b61d3b5a | 105 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 106 | return &ring[tail_i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 107 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 108 | |
Michael J. Spencer |
2:1df0b61d3b5a | 109 | template<class kind> kind* HeapRing<kind>::item_ref(unsigned int i) |
Michael J. Spencer |
2:1df0b61d3b5a | 110 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 111 | return &ring[i]; |
Michael J. Spencer |
2:1df0b61d3b5a | 112 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 113 | |
Michael J. Spencer |
2:1df0b61d3b5a | 114 | template<class kind> void HeapRing<kind>::produce_head() |
Michael J. Spencer |
2:1df0b61d3b5a | 115 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 116 | while (is_full()); |
Michael J. Spencer |
2:1df0b61d3b5a | 117 | head_i = next(head_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 118 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 119 | |
Michael J. Spencer |
2:1df0b61d3b5a | 120 | template<class kind> void HeapRing<kind>::consume_tail() |
Michael J. Spencer |
2:1df0b61d3b5a | 121 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 122 | if (!is_empty()) |
Michael J. Spencer |
2:1df0b61d3b5a | 123 | tail_i = next(tail_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 124 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 125 | |
Michael J. Spencer |
2:1df0b61d3b5a | 126 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 127 | * queue status accessors |
Michael J. Spencer |
2:1df0b61d3b5a | 128 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 129 | |
Michael J. Spencer |
2:1df0b61d3b5a | 130 | template<class kind> bool HeapRing<kind>::is_full() |
Michael J. Spencer |
2:1df0b61d3b5a | 131 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 132 | __disable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 133 | bool r = (next(head_i) == tail_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 134 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 135 | |
Michael J. Spencer |
2:1df0b61d3b5a | 136 | return r; |
Michael J. Spencer |
2:1df0b61d3b5a | 137 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 138 | |
Michael J. Spencer |
2:1df0b61d3b5a | 139 | template<class kind> bool HeapRing<kind>::is_empty() |
Michael J. Spencer |
2:1df0b61d3b5a | 140 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 141 | __disable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 142 | bool r = (head_i == tail_i); |
Michael J. Spencer |
2:1df0b61d3b5a | 143 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 144 | |
Michael J. Spencer |
2:1df0b61d3b5a | 145 | return r; |
Michael J. Spencer |
2:1df0b61d3b5a | 146 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 147 | |
Michael J. Spencer |
2:1df0b61d3b5a | 148 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 149 | * resize |
Michael J. Spencer |
2:1df0b61d3b5a | 150 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 151 | |
Michael J. Spencer |
2:1df0b61d3b5a | 152 | template<class kind> bool HeapRing<kind>::resize(unsigned int length) |
Michael J. Spencer |
2:1df0b61d3b5a | 153 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 154 | if (is_empty()) |
Michael J. Spencer |
2:1df0b61d3b5a | 155 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 156 | if (length == 0) |
Michael J. Spencer |
2:1df0b61d3b5a | 157 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 158 | __disable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 159 | |
Michael J. Spencer |
2:1df0b61d3b5a | 160 | if (is_empty()) // check again in case something was pushed |
Michael J. Spencer |
2:1df0b61d3b5a | 161 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 162 | head_i = tail_i = this->length = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 163 | |
Michael J. Spencer |
2:1df0b61d3b5a | 164 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 165 | |
Michael J. Spencer |
2:1df0b61d3b5a | 166 | if (ring) |
Michael J. Spencer |
2:1df0b61d3b5a | 167 | delete [] ring; |
Michael J. Spencer |
2:1df0b61d3b5a | 168 | ring = NULL; |
Michael J. Spencer |
2:1df0b61d3b5a | 169 | |
Michael J. Spencer |
2:1df0b61d3b5a | 170 | return true; |
Michael J. Spencer |
2:1df0b61d3b5a | 171 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 172 | |
Michael J. Spencer |
2:1df0b61d3b5a | 173 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 174 | |
Michael J. Spencer |
2:1df0b61d3b5a | 175 | return false; |
Michael J. Spencer |
2:1df0b61d3b5a | 176 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 177 | |
Michael J. Spencer |
2:1df0b61d3b5a | 178 | // Note: we don't use realloc so we can fall back to the existing ring if allocation fails |
Michael J. Spencer |
2:1df0b61d3b5a | 179 | kind* newring = new kind[length]; |
Michael J. Spencer |
2:1df0b61d3b5a | 180 | |
Michael J. Spencer |
2:1df0b61d3b5a | 181 | if (newring != NULL) |
Michael J. Spencer |
2:1df0b61d3b5a | 182 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 183 | kind* oldring = ring; |
Michael J. Spencer |
2:1df0b61d3b5a | 184 | |
Michael J. Spencer |
2:1df0b61d3b5a | 185 | __disable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 186 | |
Michael J. Spencer |
2:1df0b61d3b5a | 187 | if (is_empty()) // check again in case something was pushed while malloc did its thing |
Michael J. Spencer |
2:1df0b61d3b5a | 188 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 189 | ring = newring; |
Michael J. Spencer |
2:1df0b61d3b5a | 190 | this->length = length; |
Michael J. Spencer |
2:1df0b61d3b5a | 191 | head_i = tail_i = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 192 | |
Michael J. Spencer |
2:1df0b61d3b5a | 193 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 194 | |
Michael J. Spencer |
2:1df0b61d3b5a | 195 | if (oldring) |
Michael J. Spencer |
2:1df0b61d3b5a | 196 | delete [] oldring; |
Michael J. Spencer |
2:1df0b61d3b5a | 197 | |
Michael J. Spencer |
2:1df0b61d3b5a | 198 | return true; |
Michael J. Spencer |
2:1df0b61d3b5a | 199 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 200 | |
Michael J. Spencer |
2:1df0b61d3b5a | 201 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 202 | |
Michael J. Spencer |
2:1df0b61d3b5a | 203 | delete [] newring; |
Michael J. Spencer |
2:1df0b61d3b5a | 204 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 205 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 206 | |
Michael J. Spencer |
2:1df0b61d3b5a | 207 | return false; |
Michael J. Spencer |
2:1df0b61d3b5a | 208 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 209 | |
Michael J. Spencer |
2:1df0b61d3b5a | 210 | template<class kind> bool HeapRing<kind>::provide(kind* buffer, unsigned int length) |
Michael J. Spencer |
2:1df0b61d3b5a | 211 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 212 | __disable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 213 | |
Michael J. Spencer |
2:1df0b61d3b5a | 214 | if (is_empty()) |
Michael J. Spencer |
2:1df0b61d3b5a | 215 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 216 | kind* oldring = ring; |
Michael J. Spencer |
2:1df0b61d3b5a | 217 | |
Michael J. Spencer |
2:1df0b61d3b5a | 218 | if ((buffer != NULL) && (length > 0)) |
Michael J. Spencer |
2:1df0b61d3b5a | 219 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 220 | ring = buffer; |
Michael J. Spencer |
2:1df0b61d3b5a | 221 | this->length = length; |
Michael J. Spencer |
2:1df0b61d3b5a | 222 | head_i = tail_i = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 223 | |
Michael J. Spencer |
2:1df0b61d3b5a | 224 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 225 | |
Michael J. Spencer |
2:1df0b61d3b5a | 226 | if (oldring) |
Michael J. Spencer |
2:1df0b61d3b5a | 227 | delete [] oldring; |
Michael J. Spencer |
2:1df0b61d3b5a | 228 | return true; |
Michael J. Spencer |
2:1df0b61d3b5a | 229 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 230 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 231 | |
Michael J. Spencer |
2:1df0b61d3b5a | 232 | __enable_irq(); |
Michael J. Spencer |
2:1df0b61d3b5a | 233 | |
Michael J. Spencer |
2:1df0b61d3b5a | 234 | return false; |
Michael J. Spencer |
2:1df0b61d3b5a | 235 | } |