multithreading example

Dependencies:   FastAnalogIn

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?

UserRevisionLine numberNew 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 }