Charles Andre
/
multithread
multithreading example
circ_buff.hpp@113:233a2fac1911, 2019-12-03 (annotated)
- Committer:
- candre97
- Date:
- Tue Dec 03 22:39:22 2019 +0000
- Revision:
- 113:233a2fac1911
- Parent:
- 109:1d95a4596fb5
yutong, look here
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
candre97 | 109:1d95a4596fb5 | 1 | #pragma once |
candre97 | 109:1d95a4596fb5 | 2 | #include <cstddef> |
candre97 | 109:1d95a4596fb5 | 3 | #include <stdio.h> |
candre97 | 109:1d95a4596fb5 | 4 | #include <string> |
candre97 | 109:1d95a4596fb5 | 5 | #include <cstring> |
candre97 | 109:1d95a4596fb5 | 6 | |
candre97 | 109:1d95a4596fb5 | 7 | #define DEFAULT_BUF_SIZE 512 |
candre97 | 109:1d95a4596fb5 | 8 | #define DEFAULT_AE_THRES 100 |
candre97 | 109:1d95a4596fb5 | 9 | #define DEFAULT_AF_THRES 412 |
candre97 | 109:1d95a4596fb5 | 10 | |
candre97 | 109:1d95a4596fb5 | 11 | template <class T> |
candre97 | 109:1d95a4596fb5 | 12 | class CircularBuff{ |
candre97 | 109:1d95a4596fb5 | 13 | private: |
candre97 | 109:1d95a4596fb5 | 14 | int buffer_size; |
candre97 | 109:1d95a4596fb5 | 15 | T* buffer; |
candre97 | 109:1d95a4596fb5 | 16 | int read_index; |
candre97 | 109:1d95a4596fb5 | 17 | int write_index; |
candre97 | 109:1d95a4596fb5 | 18 | int window; |
candre97 | 109:1d95a4596fb5 | 19 | int ae_thres; |
candre97 | 109:1d95a4596fb5 | 20 | int af_thres; |
candre97 | 109:1d95a4596fb5 | 21 | public: |
candre97 | 109:1d95a4596fb5 | 22 | CircularBuff(); |
candre97 | 109:1d95a4596fb5 | 23 | CircularBuff(int buffsize); |
candre97 | 109:1d95a4596fb5 | 24 | CircularBuff(int buffsize, int window_size); |
candre97 | 109:1d95a4596fb5 | 25 | CircularBuff(int buffsize, int ae_threshold, int af_threshold); |
candre97 | 109:1d95a4596fb5 | 26 | ~CircularBuff(); |
candre97 | 109:1d95a4596fb5 | 27 | bool is_full(); |
candre97 | 109:1d95a4596fb5 | 28 | bool is_empty(); |
candre97 | 109:1d95a4596fb5 | 29 | bool push(T input); |
candre97 | 109:1d95a4596fb5 | 30 | bool push_buff(uint8_t* input_buf, int buf_size); |
candre97 | 109:1d95a4596fb5 | 31 | bool window_possible(); |
candre97 | 109:1d95a4596fb5 | 32 | T* pop(); |
candre97 | 109:1d95a4596fb5 | 33 | int size(); |
candre97 | 109:1d95a4596fb5 | 34 | int capacity(); |
candre97 | 109:1d95a4596fb5 | 35 | void print(); |
candre97 | 109:1d95a4596fb5 | 36 | void clear(); |
candre97 | 109:1d95a4596fb5 | 37 | void set_AE_thres(int thres); |
candre97 | 109:1d95a4596fb5 | 38 | T* read_window(); |
candre97 | 109:1d95a4596fb5 | 39 | int get_AE_thres(); |
candre97 | 109:1d95a4596fb5 | 40 | bool almost_empty(); |
candre97 | 109:1d95a4596fb5 | 41 | void set_AF_thres(int thres); |
candre97 | 109:1d95a4596fb5 | 42 | int get_AF_thres(); |
candre97 | 109:1d95a4596fb5 | 43 | bool almost_full(); |
candre97 | 109:1d95a4596fb5 | 44 | }; |
candre97 | 109:1d95a4596fb5 | 45 | |
candre97 | 109:1d95a4596fb5 | 46 | template <class T> |
candre97 | 109:1d95a4596fb5 | 47 | CircularBuff<T>::CircularBuff(){ |
candre97 | 109:1d95a4596fb5 | 48 | buffer_size = DEFAULT_BUF_SIZE+1; |
candre97 | 109:1d95a4596fb5 | 49 | ae_thres = DEFAULT_AE_THRES; |
candre97 | 109:1d95a4596fb5 | 50 | af_thres = DEFAULT_AF_THRES; |
candre97 | 109:1d95a4596fb5 | 51 | buffer = new T[buffer_size]; |
candre97 | 109:1d95a4596fb5 | 52 | read_index = 0; |
candre97 | 109:1d95a4596fb5 | 53 | write_index = 0; |
candre97 | 109:1d95a4596fb5 | 54 | } |
candre97 | 109:1d95a4596fb5 | 55 | |
candre97 | 109:1d95a4596fb5 | 56 | template <class T> |
candre97 | 109:1d95a4596fb5 | 57 | CircularBuff<T>::CircularBuff(int buffsize){ |
candre97 | 109:1d95a4596fb5 | 58 | buffer_size = buffsize+1; |
candre97 | 109:1d95a4596fb5 | 59 | ae_thres = buffer_size/5; |
candre97 | 109:1d95a4596fb5 | 60 | af_thres = buffer_size*4/5; |
candre97 | 109:1d95a4596fb5 | 61 | buffer = new T[buffer_size]; |
candre97 | 109:1d95a4596fb5 | 62 | read_index = 0; |
candre97 | 109:1d95a4596fb5 | 63 | write_index = 0; |
candre97 | 109:1d95a4596fb5 | 64 | } |
candre97 | 109:1d95a4596fb5 | 65 | template <class T> |
candre97 | 109:1d95a4596fb5 | 66 | CircularBuff<T>::CircularBuff(int buffsize, int window_size){ |
candre97 | 109:1d95a4596fb5 | 67 | buffer_size = buffsize+1; |
candre97 | 109:1d95a4596fb5 | 68 | window = window_size; |
candre97 | 109:1d95a4596fb5 | 69 | buffer = new T[buffer_size]; |
candre97 | 109:1d95a4596fb5 | 70 | read_index = 0; |
candre97 | 109:1d95a4596fb5 | 71 | write_index = 0; |
candre97 | 109:1d95a4596fb5 | 72 | } |
candre97 | 109:1d95a4596fb5 | 73 | |
candre97 | 109:1d95a4596fb5 | 74 | template <class T> |
candre97 | 109:1d95a4596fb5 | 75 | CircularBuff<T>::CircularBuff(int buffsize, int ae_threshold, int af_threshold){ |
candre97 | 109:1d95a4596fb5 | 76 | buffer_size = buffsize+1; |
candre97 | 109:1d95a4596fb5 | 77 | ae_thres = ae_threshold; |
candre97 | 109:1d95a4596fb5 | 78 | af_thres = af_threshold; |
candre97 | 109:1d95a4596fb5 | 79 | buffer = new T[buffer_size]; |
candre97 | 109:1d95a4596fb5 | 80 | read_index = 0; |
candre97 | 109:1d95a4596fb5 | 81 | write_index = 0; |
candre97 | 109:1d95a4596fb5 | 82 | } |
candre97 | 109:1d95a4596fb5 | 83 | |
candre97 | 109:1d95a4596fb5 | 84 | |
candre97 | 109:1d95a4596fb5 | 85 | template <class T> |
candre97 | 109:1d95a4596fb5 | 86 | CircularBuff<T>::~CircularBuff(){ |
candre97 | 109:1d95a4596fb5 | 87 | delete [] buffer; |
candre97 | 109:1d95a4596fb5 | 88 | buffer = NULL; |
candre97 | 109:1d95a4596fb5 | 89 | } |
candre97 | 109:1d95a4596fb5 | 90 | |
candre97 | 109:1d95a4596fb5 | 91 | template <class T> |
candre97 | 109:1d95a4596fb5 | 92 | bool CircularBuff<T>::is_full(){ |
candre97 | 109:1d95a4596fb5 | 93 | if (size() == (buffer_size - 1)){ |
candre97 | 109:1d95a4596fb5 | 94 | return true; |
candre97 | 109:1d95a4596fb5 | 95 | } |
candre97 | 109:1d95a4596fb5 | 96 | else{ |
candre97 | 109:1d95a4596fb5 | 97 | return false; |
candre97 | 109:1d95a4596fb5 | 98 | } |
candre97 | 109:1d95a4596fb5 | 99 | } |
candre97 | 109:1d95a4596fb5 | 100 | |
candre97 | 109:1d95a4596fb5 | 101 | template <class T> |
candre97 | 109:1d95a4596fb5 | 102 | bool CircularBuff<T>::is_empty(){ |
candre97 | 109:1d95a4596fb5 | 103 | if (size() == 0){ |
candre97 | 109:1d95a4596fb5 | 104 | return true; |
candre97 | 109:1d95a4596fb5 | 105 | } |
candre97 | 109:1d95a4596fb5 | 106 | else{ |
candre97 | 109:1d95a4596fb5 | 107 | return false; |
candre97 | 109:1d95a4596fb5 | 108 | } |
candre97 | 109:1d95a4596fb5 | 109 | } |
candre97 | 109:1d95a4596fb5 | 110 | |
candre97 | 109:1d95a4596fb5 | 111 | //false if failed, true if success |
candre97 | 109:1d95a4596fb5 | 112 | template <class T> |
candre97 | 109:1d95a4596fb5 | 113 | bool CircularBuff<T>::push(T input){ |
candre97 | 109:1d95a4596fb5 | 114 | if (!is_full()){ |
candre97 | 109:1d95a4596fb5 | 115 | buffer[write_index] = input; |
candre97 | 109:1d95a4596fb5 | 116 | write_index = (write_index + 1) % buffer_size; |
candre97 | 109:1d95a4596fb5 | 117 | return true; |
candre97 | 109:1d95a4596fb5 | 118 | } |
candre97 | 109:1d95a4596fb5 | 119 | else{ |
candre97 | 109:1d95a4596fb5 | 120 | return false; |
candre97 | 109:1d95a4596fb5 | 121 | } |
candre97 | 109:1d95a4596fb5 | 122 | } |
candre97 | 109:1d95a4596fb5 | 123 | |
candre97 | 109:1d95a4596fb5 | 124 | //false if failed, true if success |
candre97 | 109:1d95a4596fb5 | 125 | //TODO: needs to be optimized |
candre97 | 109:1d95a4596fb5 | 126 | template <class T> |
candre97 | 109:1d95a4596fb5 | 127 | bool CircularBuff<T>::push_buff(uint8_t* input_buf, int input_buf_size){ |
candre97 | 109:1d95a4596fb5 | 128 | int casted_input_buf_size = input_buf_size/sizeof(T); |
candre97 | 109:1d95a4596fb5 | 129 | |
candre97 | 109:1d95a4596fb5 | 130 | if (((size() + casted_input_buf_size) < capacity()) && ((input_buf_size % sizeof(T)) == 0)){ |
candre97 | 109:1d95a4596fb5 | 131 | T* casted_input_buf = (T*) input_buf; |
candre97 | 109:1d95a4596fb5 | 132 | |
candre97 | 109:1d95a4596fb5 | 133 | // printf("Buffer contents: [\n"); |
candre97 | 109:1d95a4596fb5 | 134 | // for(int i = 0; i < casted_input_buf_size; i++){ |
candre97 | 109:1d95a4596fb5 | 135 | // //printf("%s,", std::to_string(buffer[i]).c_str()); |
candre97 | 109:1d95a4596fb5 | 136 | // printf("%08x,", casted_input_buf[i]); |
candre97 | 109:1d95a4596fb5 | 137 | // } |
candre97 | 109:1d95a4596fb5 | 138 | // printf("\b\n]\n"); |
candre97 | 109:1d95a4596fb5 | 139 | int pre_wrap_size = 0; |
candre97 | 109:1d95a4596fb5 | 140 | int post_wrap_size = 0; |
candre97 | 109:1d95a4596fb5 | 141 | |
candre97 | 109:1d95a4596fb5 | 142 | if(write_index + casted_input_buf_size > buffer_size){ |
candre97 | 109:1d95a4596fb5 | 143 | pre_wrap_size = buffer_size - write_index; |
candre97 | 109:1d95a4596fb5 | 144 | post_wrap_size = casted_input_buf_size - pre_wrap_size; |
candre97 | 109:1d95a4596fb5 | 145 | } |
candre97 | 109:1d95a4596fb5 | 146 | else{ |
candre97 | 109:1d95a4596fb5 | 147 | pre_wrap_size = casted_input_buf_size; |
candre97 | 109:1d95a4596fb5 | 148 | } |
candre97 | 109:1d95a4596fb5 | 149 | std::memmove(buffer + write_index, casted_input_buf, pre_wrap_size * sizeof(T)); |
candre97 | 109:1d95a4596fb5 | 150 | std::memmove(buffer, casted_input_buf + pre_wrap_size, post_wrap_size * sizeof(T)); |
candre97 | 109:1d95a4596fb5 | 151 | |
candre97 | 109:1d95a4596fb5 | 152 | write_index = (write_index + casted_input_buf_size) % buffer_size; |
candre97 | 109:1d95a4596fb5 | 153 | return true; |
candre97 | 109:1d95a4596fb5 | 154 | } |
candre97 | 109:1d95a4596fb5 | 155 | else{ |
candre97 | 109:1d95a4596fb5 | 156 | if (input_buf_size % sizeof(T) != 0){ |
candre97 | 109:1d95a4596fb5 | 157 | printf("Buffer cannot be casted to CircularBuff's data type; make sure bytes are alined\n"); |
candre97 | 109:1d95a4596fb5 | 158 | } |
candre97 | 109:1d95a4596fb5 | 159 | else{ |
candre97 | 109:1d95a4596fb5 | 160 | printf("Input buffer too large\n"); |
candre97 | 109:1d95a4596fb5 | 161 | } |
candre97 | 109:1d95a4596fb5 | 162 | return false; |
candre97 | 109:1d95a4596fb5 | 163 | } |
candre97 | 109:1d95a4596fb5 | 164 | } |
candre97 | 109:1d95a4596fb5 | 165 | |
candre97 | 109:1d95a4596fb5 | 166 | //false if failed, true if success |
candre97 | 109:1d95a4596fb5 | 167 | template <class T> |
candre97 | 109:1d95a4596fb5 | 168 | bool CircularBuff<T>::window_possible(){ |
candre97 | 109:1d95a4596fb5 | 169 | if (!is_full()){ |
candre97 | 109:1d95a4596fb5 | 170 | if (read_index < write_index){ |
candre97 | 109:1d95a4596fb5 | 171 | if ((write_index-1) >= read_index + window){ |
candre97 | 109:1d95a4596fb5 | 172 | return true; |
candre97 | 109:1d95a4596fb5 | 173 | } |
candre97 | 109:1d95a4596fb5 | 174 | else{ |
candre97 | 109:1d95a4596fb5 | 175 | return false; |
candre97 | 109:1d95a4596fb5 | 176 | } |
candre97 | 109:1d95a4596fb5 | 177 | } |
candre97 | 109:1d95a4596fb5 | 178 | else if(write_index == 0){ |
candre97 | 109:1d95a4596fb5 | 179 | if (buffer_size-read_index >= window){ |
candre97 | 109:1d95a4596fb5 | 180 | return true; |
candre97 | 109:1d95a4596fb5 | 181 | } |
candre97 | 109:1d95a4596fb5 | 182 | else{ |
candre97 | 109:1d95a4596fb5 | 183 | return false; |
candre97 | 109:1d95a4596fb5 | 184 | } |
candre97 | 109:1d95a4596fb5 | 185 | } |
candre97 | 109:1d95a4596fb5 | 186 | else{ |
candre97 | 109:1d95a4596fb5 | 187 | if((write_index - 1 + (buffer_size-read_index)) >= window){ |
candre97 | 109:1d95a4596fb5 | 188 | return true; |
candre97 | 109:1d95a4596fb5 | 189 | } |
candre97 | 109:1d95a4596fb5 | 190 | else{ |
candre97 | 109:1d95a4596fb5 | 191 | return false; |
candre97 | 109:1d95a4596fb5 | 192 | } |
candre97 | 109:1d95a4596fb5 | 193 | } |
candre97 | 109:1d95a4596fb5 | 194 | return true; |
candre97 | 109:1d95a4596fb5 | 195 | } |
candre97 | 109:1d95a4596fb5 | 196 | else{ |
candre97 | 109:1d95a4596fb5 | 197 | return false; |
candre97 | 109:1d95a4596fb5 | 198 | } |
candre97 | 109:1d95a4596fb5 | 199 | } |
candre97 | 109:1d95a4596fb5 | 200 | |
candre97 | 109:1d95a4596fb5 | 201 | //false if failed, true if success |
candre97 | 109:1d95a4596fb5 | 202 | template <class T> |
candre97 | 109:1d95a4596fb5 | 203 | T* CircularBuff<T>::pop(){ |
candre97 | 109:1d95a4596fb5 | 204 | T* retval; |
candre97 | 109:1d95a4596fb5 | 205 | if (!is_empty()){ |
candre97 | 109:1d95a4596fb5 | 206 | retval = buffer + read_index; |
candre97 | 109:1d95a4596fb5 | 207 | read_index = (read_index + 1) % buffer_size; |
candre97 | 109:1d95a4596fb5 | 208 | return retval; |
candre97 | 109:1d95a4596fb5 | 209 | } |
candre97 | 109:1d95a4596fb5 | 210 | else{ |
candre97 | 109:1d95a4596fb5 | 211 | return NULL; |
candre97 | 109:1d95a4596fb5 | 212 | } |
candre97 | 109:1d95a4596fb5 | 213 | } |
candre97 | 109:1d95a4596fb5 | 214 | |
candre97 | 109:1d95a4596fb5 | 215 | template <class T> |
candre97 | 109:1d95a4596fb5 | 216 | int CircularBuff<T>::size(){ |
candre97 | 109:1d95a4596fb5 | 217 | return (size_t) ((write_index - read_index + buffer_size) % buffer_size); |
candre97 | 109:1d95a4596fb5 | 218 | } |
candre97 | 109:1d95a4596fb5 | 219 | |
candre97 | 109:1d95a4596fb5 | 220 | template <class T> |
candre97 | 109:1d95a4596fb5 | 221 | int CircularBuff<T>::capacity(){ |
candre97 | 109:1d95a4596fb5 | 222 | return (size_t) buffer_size-1; |
candre97 | 109:1d95a4596fb5 | 223 | } |
candre97 | 109:1d95a4596fb5 | 224 | |
candre97 | 109:1d95a4596fb5 | 225 | template<class T> |
candre97 | 109:1d95a4596fb5 | 226 | void CircularBuff<T>::print(){ |
candre97 | 109:1d95a4596fb5 | 227 | printf("Buffer contents: [\n"); |
candre97 | 109:1d95a4596fb5 | 228 | for(int i = 0; i < buffer_size; i++){ |
candre97 | 109:1d95a4596fb5 | 229 | printf("%s,", std::to_string(buffer[i]).c_str()); |
candre97 | 109:1d95a4596fb5 | 230 | //printf("%08x,", buffer[i]); |
candre97 | 109:1d95a4596fb5 | 231 | } |
candre97 | 109:1d95a4596fb5 | 232 | printf("\b\n]\n"); |
candre97 | 109:1d95a4596fb5 | 233 | printf("Read index: %d \t Write index: %d \t Size: %d\n", read_index, write_index, size()); |
candre97 | 109:1d95a4596fb5 | 234 | } |
candre97 | 109:1d95a4596fb5 | 235 | |
candre97 | 109:1d95a4596fb5 | 236 | template<class T> |
candre97 | 109:1d95a4596fb5 | 237 | void CircularBuff<T>::clear(){ |
candre97 | 109:1d95a4596fb5 | 238 | for(int i = 0; i < buffer_size; i++){ |
candre97 | 109:1d95a4596fb5 | 239 | buffer[i] = NULL; |
candre97 | 109:1d95a4596fb5 | 240 | } |
candre97 | 109:1d95a4596fb5 | 241 | read_index = 0; |
candre97 | 109:1d95a4596fb5 | 242 | write_index = 0; |
candre97 | 109:1d95a4596fb5 | 243 | } |
candre97 | 109:1d95a4596fb5 | 244 | |
candre97 | 109:1d95a4596fb5 | 245 | template<class T> |
candre97 | 109:1d95a4596fb5 | 246 | void CircularBuff<T>::set_AE_thres(int thres){ |
candre97 | 109:1d95a4596fb5 | 247 | ae_thres = thres; |
candre97 | 109:1d95a4596fb5 | 248 | } |
candre97 | 109:1d95a4596fb5 | 249 | |
candre97 | 109:1d95a4596fb5 | 250 | template<class T> |
candre97 | 109:1d95a4596fb5 | 251 | int CircularBuff<T>::get_AE_thres(){ |
candre97 | 109:1d95a4596fb5 | 252 | return ae_thres; |
candre97 | 109:1d95a4596fb5 | 253 | } |
candre97 | 109:1d95a4596fb5 | 254 | |
candre97 | 109:1d95a4596fb5 | 255 | template<class T> |
candre97 | 109:1d95a4596fb5 | 256 | bool CircularBuff<T>::almost_empty(){ |
candre97 | 109:1d95a4596fb5 | 257 | return (size() < ae_thres); |
candre97 | 109:1d95a4596fb5 | 258 | } |
candre97 | 109:1d95a4596fb5 | 259 | |
candre97 | 109:1d95a4596fb5 | 260 | template<class T> |
candre97 | 109:1d95a4596fb5 | 261 | void CircularBuff<T>::set_AF_thres(int thres){ |
candre97 | 109:1d95a4596fb5 | 262 | af_thres = thres; |
candre97 | 109:1d95a4596fb5 | 263 | } |
candre97 | 109:1d95a4596fb5 | 264 | |
candre97 | 109:1d95a4596fb5 | 265 | template<class T> |
candre97 | 109:1d95a4596fb5 | 266 | T* CircularBuff<T>::read_window(){ |
candre97 | 109:1d95a4596fb5 | 267 | if(window_possible()){ |
candre97 | 109:1d95a4596fb5 | 268 | T* temp = buffer + read_index; |
candre97 | 109:1d95a4596fb5 | 269 | read_index += window; |
candre97 | 109:1d95a4596fb5 | 270 | return temp; |
candre97 | 109:1d95a4596fb5 | 271 | } |
candre97 | 109:1d95a4596fb5 | 272 | } |
candre97 | 109:1d95a4596fb5 | 273 | |
candre97 | 109:1d95a4596fb5 | 274 | template<class T> |
candre97 | 109:1d95a4596fb5 | 275 | int CircularBuff<T>::get_AF_thres(){ |
candre97 | 109:1d95a4596fb5 | 276 | return af_thres; |
candre97 | 109:1d95a4596fb5 | 277 | } |
candre97 | 109:1d95a4596fb5 | 278 | |
candre97 | 109:1d95a4596fb5 | 279 | template<class T> |
candre97 | 109:1d95a4596fb5 | 280 | bool CircularBuff<T>::almost_full(){ |
candre97 | 109:1d95a4596fb5 | 281 | return (size() > af_thres); |
candre97 | 109:1d95a4596fb5 | 282 | } |