00001
00041 #ifndef RING_H_INCLUDED
00042 #define RING_H_INCLUDED
00043
00044 #include <stdbool.h>
00045
00065 struct ring_head {
00067 unsigned long head;
00069 unsigned long tail;
00070 };
00071
00072 #ifdef CONFIG_RING_DEBUG
00073 #include <util.h>
00074
00075
00076
00077
00078
00079 extern void __bad_constant_ring_size(unsigned long size);
00080
00081
00082 extern void bad_ring_size(unsigned long size);
00083
00084 static inline void ring_check_size(unsigned long size)
00085 {
00086 if (!is_power_of_two(size)) {
00087 if (__builtin_constant_p(size))
00088 __bad_constant_ring_size(size);
00089 else
00090 bad_ring_size(size);
00091 }
00092 }
00093 #else
00094 static inline void ring_check_size(unsigned long size)
00095 {
00096
00097 }
00098 #endif
00099
00111 static inline unsigned long ring_get_head(struct ring_head *ring,
00112 unsigned long ring_size)
00113 {
00114 ring_check_size(ring_size);
00115
00116 return ring->head & (ring_size - 1);
00117 }
00118
00130 static inline unsigned long ring_get_tail(struct ring_head *ring,
00131 unsigned long ring_size)
00132 {
00133 ring_check_size(ring_size);
00134
00135 return ring->tail & (ring_size - 1);
00136 }
00137
00147 static inline unsigned long ring_entries_used(struct ring_head *ring,
00148 unsigned long ring_size)
00149 {
00150 ring_check_size(ring_size);
00151
00152 return ring->head - ring->tail;
00153 }
00154
00164 static inline unsigned long ring_entries_used_before_end(struct ring_head *ring,
00165 unsigned long ring_size)
00166 {
00167 unsigned long head = ring->head;
00168 unsigned long tail = ring->tail;
00169
00170 ring_check_size(ring_size);
00171
00172 if ((head ^ tail) & ring_size)
00173 return ring_size - (tail & (ring_size - 1));
00174 else
00175 return head - tail;
00176 }
00177
00187 static inline unsigned long ring_entries_unused(struct ring_head *ring,
00188 unsigned long ring_size)
00189 {
00190 return ring_size - ring_entries_used(ring, ring_size);
00191 }
00192
00203 static inline unsigned long ring_entries_unused_before_end(
00204 struct ring_head *ring, unsigned long ring_size)
00205 {
00206 unsigned long head = ring->head;
00207 unsigned long tail = ring->tail;
00208
00209 ring_check_size(ring_size);
00210
00211 if ((head ^ tail) & ring_size)
00212 return ring_size + tail - head;
00213 else
00214 return ring_size - (head & (ring_size - 1));
00215 }
00216
00226 static inline bool ring_is_empty(struct ring_head *ring,
00227 unsigned long ring_size)
00228 {
00229 return ring->head == ring->tail;
00230 }
00231
00243 static inline void ring_insert_entries(struct ring_head *ring,
00244 unsigned long nr_entries)
00245 {
00246 barrier();
00247 ring->head += nr_entries;
00248 }
00249
00261 static inline void ring_extract_entries(struct ring_head *ring,
00262 unsigned long nr_entries)
00263 {
00264 barrier();
00265 ring->tail += nr_entries;
00266 }
00267
00276 static inline void ring_reset(struct ring_head *ring)
00277 {
00278 ring->head = ring->tail = 0;
00279 }
00280
00281 #endif