Project

General

Profile

Statistics
| Revision:

root / trunk / code / lib / include / libdragonfly / ring_buffer.h @ 88

History | View | Annotate | Download (3.44 KB)

1
/** @file Include macros to create a ring buffer. Originally written for 15-410.
2
 *  Modified for use in ATMega128 serial driver
3
 *
4
 *        @author Cornell Wright (cgwright)
5
 *        @author Jason P. Winters (jpwinter)
6
 *
7
 *        @bugs Could not create buffer of non byte-sized elements due to modding with sizeof(queue).  
8
 *                   Fixed 3/2/07, Felix Duvallet and Brad Neuman
9
 */
10

    
11
#ifndef _RING_BUFFER_H
12
#define _RING_BUFFER_H
13

    
14
/** @brief Creates the struct for a new ring buffer. This just expands to a
15
 *        structure definition and thus should be invoked in the global context.
16
 *
17
 *        @param struct_name Name of the ring buffer struct.
18
 *
19
 *        @param size The size of the buffer to create.
20
 *
21
 *        @param type The type of object that the queue is to hold.
22
 *
23
 *        @param ... Name or names of the instance or instances of the ring buffer(s)
24
 *        to be created.
25
 */
26
#define RING_BUFFER_NEW(struct_name, size, type, ...)        \
27
        struct struct_name {        \
28
                type queue[size];        \
29
                uint8_t start;                        \
30
                uint8_t end;                        \
31
                uint8_t buffer_size;                        \
32
        } __VA_ARGS__
33

    
34

    
35
/** @brief Initializes the ring buffer, setting its size to the correct value
36
 *
37
 *        @param buf The ring buffer to initialize.
38
 *
39
 *  @param size The size of the ring buffer (in array elements)
40
 */
41
#define RING_BUFFER_INIT(buf, size)                         \
42
        do {                                                                                \
43
                (buf).buffer_size = size;                                \
44
        } while(0)
45

    
46

    
47
/** @brief Sets the specified ring buffer to be empty.
48
 *
49
 *        @param buf The ring buffer to make empty.
50
 */
51
#define RING_BUFFER_CLEAR(buf)        \
52
        do {                                                \
53
                (buf).start = 0;                \
54
                (buf).end = 0;                        \
55
        } while (0)
56

    
57
/** @brief Returns true if the ring buffer specified is empty.
58
 *
59
 *        @param buf The buffer to check emptiness of.
60
 */
61
#define RING_BUFFER_EMPTY(buf) ((buf).start == (buf).end)
62

    
63

    
64
/** @brief Returns true if the ring buffer specified is full.
65
 *
66
 *        @param buf The buffer to check fullness of.
67
 */
68
#define RING_BUFFER_FULL(buf)        \
69
                (((buf).end + 1) % (buf).buffer_size == (buf).start)
70

    
71

    
72
/** @brief Adds val to ring buffer buf. Note that val must be of the type
73
 *        used in creating the ring buffer to prevent the compiler from spewing
74
 *        confusing errors. Also, this assumes that the ring buffer is not full.
75
 *
76
 *        @param buf The ring buffer to add to.
77
 *        @param val The value to add.
78
 */
79
#define RING_BUFFER_ADD(buf, val)                \
80
        do {                                                                \
81
                (buf).queue[(buf).end] = val;        \
82
                (buf).end = ((buf).end + 1) % (buf).buffer_size;        \
83
        } while (0)
84

    
85

    
86
/** @brief Removes the value at the head of the ring buffer and puts it in
87
 *        val_ret. Note that val_ret must be the same type used in creating the ring
88
 *        buffer to prevent the compiler from spewing confusing errors. Also, this
89
 *        assumes that the ring buffer is not empty.
90
 *
91
 *        @param buf The ring buffer to remove from.
92
 *        @param val_ret Where to put the value removed from the head of the ring
93
 *        buffer.
94
 */
95
#define RING_BUFFER_REMOVE(buf, val_ret)        \
96
        do {        \
97
                (val_ret) = (buf).queue[(buf).start];        \
98
                (buf).start = ((buf).start + 1) % (buf).buffer_size;        \
99
        } while (0)
100

    
101
/** @brief Checks the value at the head of the ring buffer without removing it
102
 *  and puts it into val_ret. Note that val_ret must be the same type used in
103
 *  creating the ring buffer to prevent the compiler from spewing confusing
104
 *  errors. Also, this assumes that the ring buffer is not empty.
105
 *
106
 *  @param buf The ring buffer to check from
107
 *  @param val_ret where to put the value checked from the head of the ring
108
 */
109
 #define RING_BUFFER_PEEK(buf, val_ret)  \
110
  do { \
111
    (val_ret) = (buf).queue[(buf).start]; \
112
  } while(0)
113

    
114
#endif /* _RING_BUFFER_H */
115