- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# include/ring.h

Go to the documentation of this file.

    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  * Undefined to force a link error when the ring size is constant and
    00077  * not a power of two.
    00078  */
    00079 extern void __bad_constant_ring_size(unsigned long size);
    00080
    00081 /* Implement this to catch bad non-constant ring sizes */
    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 /* RING_H_INCLUDED */