Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
HeapRing.cpp
00001 #include "HeapRing.h" 00002 00003 #include <cstdlib> 00004 00005 #include "cmsis.h" 00006 00007 /* 00008 * constructors 00009 */ 00010 00011 template<class kind> HeapRing<kind>::HeapRing() 00012 { 00013 head_i = tail_i = length = 0; 00014 ring = NULL; 00015 } 00016 00017 template<class kind> HeapRing<kind>::HeapRing(unsigned int length) 00018 { 00019 head_i = tail_i = 0; 00020 ring = new kind[length]; 00021 // TODO: handle allocation failure 00022 this->length = length; 00023 } 00024 00025 /* 00026 * destructor 00027 */ 00028 00029 template<class kind> HeapRing<kind>::~HeapRing() 00030 { 00031 head_i = tail_i = length = 0; 00032 if (ring) 00033 delete [] ring; 00034 ring = NULL; 00035 } 00036 00037 /* 00038 * index accessors (protected) 00039 */ 00040 00041 template<class kind> unsigned int HeapRing<kind>::next(unsigned int item) 00042 { 00043 if (length == 0) 00044 return 0; 00045 00046 if (++item >= length) 00047 return 0; 00048 00049 return item; 00050 } 00051 00052 template<class kind> unsigned int HeapRing<kind>::prev(unsigned int item) 00053 { 00054 if (length == 0) 00055 return 0; 00056 00057 if (item == 0) 00058 return (length - 1); 00059 else 00060 return (item - 1); 00061 } 00062 00063 /* 00064 * reference accessors 00065 */ 00066 00067 template<class kind> kind& HeapRing<kind>::head() 00068 { 00069 return ring[head_i]; 00070 } 00071 00072 template<class kind> kind& HeapRing<kind>::tail() 00073 { 00074 return ring[tail_i]; 00075 } 00076 00077 template<class kind> kind& HeapRing<kind>::item(unsigned int i) 00078 { 00079 return ring[i]; 00080 } 00081 00082 template<class kind> void HeapRing<kind>::push_front(kind& item) 00083 { 00084 ring[head_i] = item; 00085 head_i = next(head_i); 00086 } 00087 00088 template<class kind> kind& HeapRing<kind>::pop_back() 00089 { 00090 kind& r = ring[tail_i]; 00091 tail_i = next(tail_i); 00092 return r; 00093 } 00094 00095 /* 00096 * pointer accessors 00097 */ 00098 00099 template<class kind> kind* HeapRing<kind>::head_ref() 00100 { 00101 return &ring[head_i]; 00102 } 00103 00104 template<class kind> kind* HeapRing<kind>::tail_ref() 00105 { 00106 return &ring[tail_i]; 00107 } 00108 00109 template<class kind> kind* HeapRing<kind>::item_ref(unsigned int i) 00110 { 00111 return &ring[i]; 00112 } 00113 00114 template<class kind> void HeapRing<kind>::produce_head() 00115 { 00116 while (is_full()); 00117 head_i = next(head_i); 00118 } 00119 00120 template<class kind> void HeapRing<kind>::consume_tail() 00121 { 00122 if (!is_empty()) 00123 tail_i = next(tail_i); 00124 } 00125 00126 /* 00127 * queue status accessors 00128 */ 00129 00130 template<class kind> bool HeapRing<kind>::is_full() 00131 { 00132 __disable_irq(); 00133 bool r = (next(head_i) == tail_i); 00134 __enable_irq(); 00135 00136 return r; 00137 } 00138 00139 template<class kind> bool HeapRing<kind>::is_empty() 00140 { 00141 __disable_irq(); 00142 bool r = (head_i == tail_i); 00143 __enable_irq(); 00144 00145 return r; 00146 } 00147 00148 /* 00149 * resize 00150 */ 00151 00152 template<class kind> bool HeapRing<kind>::resize(unsigned int length) 00153 { 00154 if (is_empty()) 00155 { 00156 if (length == 0) 00157 { 00158 __disable_irq(); 00159 00160 if (is_empty()) // check again in case something was pushed 00161 { 00162 head_i = tail_i = this->length = 0; 00163 00164 __enable_irq(); 00165 00166 if (ring) 00167 delete [] ring; 00168 ring = NULL; 00169 00170 return true; 00171 } 00172 00173 __enable_irq(); 00174 00175 return false; 00176 } 00177 00178 // Note: we don't use realloc so we can fall back to the existing ring if allocation fails 00179 kind* newring = new kind[length]; 00180 00181 if (newring != NULL) 00182 { 00183 kind* oldring = ring; 00184 00185 __disable_irq(); 00186 00187 if (is_empty()) // check again in case something was pushed while malloc did its thing 00188 { 00189 ring = newring; 00190 this->length = length; 00191 head_i = tail_i = 0; 00192 00193 __enable_irq(); 00194 00195 if (oldring) 00196 delete [] oldring; 00197 00198 return true; 00199 } 00200 00201 __enable_irq(); 00202 00203 delete [] newring; 00204 } 00205 } 00206 00207 return false; 00208 } 00209 00210 template<class kind> bool HeapRing<kind>::provide(kind* buffer, unsigned int length) 00211 { 00212 __disable_irq(); 00213 00214 if (is_empty()) 00215 { 00216 kind* oldring = ring; 00217 00218 if ((buffer != NULL) && (length > 0)) 00219 { 00220 ring = buffer; 00221 this->length = length; 00222 head_i = tail_i = 0; 00223 00224 __enable_irq(); 00225 00226 if (oldring) 00227 delete [] oldring; 00228 return true; 00229 } 00230 } 00231 00232 __enable_irq(); 00233 00234 return false; 00235 }
Generated on Tue Jul 12 2022 20:09:02 by 1.7.2