Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
