1 /*
2     Copyright (C) 2000 Paul Davis
3     Copyright (C) 2003 Rohan Drape
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU Lesser General Public License as published by
7     the Free Software Foundation; either version 2.1 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19     $Id: rb.h 1245 2012-02-04 10:33:30Z assworth $
20 */
21 
22 #ifndef AQUALUNG_RB_H
23 #define AQUALUNG_RB_H
24 
25 #include <stddef.h>
26 
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /** @file ringbuffer.h
33  *
34  * A set of library functions to make lock-free ringbuffers available
35  * to JACK clients.  The `capture_client.c' (in the example_clients
36  * directory) is a fully functioning user of this API.
37  *
38  * The key attribute of a ringbuffer is that it can be safely accessed
39  * by two threads simultaneously -- one reading from the buffer and
40  * the other writing to it -- without using any synchronization or
41  * mutual exclusion primitives.  For this to work correctly, there can
42  * only be a single reader and a single writer thread.  Their
43  * identities cannot be interchanged.
44  */
45 
46 typedef struct
47 {
48   char  *buf;
49   size_t len;
50 }
51 rb_data_t ;
52 
53 typedef struct
54 {
55   char		 *buf;
56   volatile size_t write_ptr;
57   volatile size_t read_ptr;
58   size_t	  size;
59   size_t	  size_mask;
60   int		  mlocked;
61 }
62 rb_t ;
63 
64 /**
65  * Allocates a ringbuffer data structure of a specified size. The
66  * caller must arrange for a call to rb_free() to release
67  * the memory associated with the ringbuffer.
68  *
69  * @param sz the ringbuffer size in bytes.
70  *
71  * @return a pointer to a new rb_t, if successful; NULL
72  * otherwise.
73  */
74 rb_t *rb_create(size_t sz);
75 
76 /**
77  * Frees the ringbuffer data structure allocated by an earlier call to
78  * rb_create().
79  *
80  * @param rb a pointer to the ringbuffer structure.
81  */
82 void rb_free(rb_t *rb);
83 
84 /**
85  * Fill a data structure with a description of the current readable
86  * data held in the ringbuffer.  This description is returned in a two
87  * element array of rb_data_t.  Two elements are needed
88  * because the data to be read may be split across the end of the
89  * ringbuffer.
90  *
91  * The first element will always contain a valid @a len field, which
92  * may be zero or greater.  If the @a len field is non-zero, then data
93  * can be read in a contiguous fashion using the address given in the
94  * corresponding @a buf field.
95  *
96  * If the second element has a non-zero @a len field, then a second
97  * contiguous stretch of data can be read from the address given in
98  * its corresponding @a buf field.
99  *
100  * @param rb a pointer to the ringbuffer structure.
101  * @param vec a pointer to a 2 element array of rb_data_t.
102  *
103  */
104 void rb_get_read_vector(const rb_t *rb,
105 			rb_data_t *vec);
106 
107 /**
108  * Fill a data structure with a description of the current writable
109  * space in the ringbuffer.  The description is returned in a two
110  * element array of rb_data_t.  Two elements are needed
111  * because the space available for writing may be split across the end
112  * of the ringbuffer.
113  *
114  * The first element will always contain a valid @a len field, which
115  * may be zero or greater.  If the @a len field is non-zero, then data
116  * can be written in a contiguous fashion using the address given in
117  * the corresponding @a buf field.
118  *
119  * If the second element has a non-zero @a len field, then a second
120  * contiguous stretch of data can be written to the address given in
121  * the corresponding @a buf field.
122  *
123  * @param rb a pointer to the ringbuffer structure.
124  * @param vec a pointer to a 2 element array of rb_data_t.
125  */
126 void rb_get_write_vector(const rb_t *rb,
127 			 rb_data_t *vec);
128 
129 /**
130  * Read data from the ringbuffer.
131  *
132  * @param rb a pointer to the ringbuffer structure.
133  * @param dest a pointer to a buffer where data read from the
134  * ringbuffer will go.
135  * @param cnt the number of bytes to read.
136  *
137  * @return the number of bytes read, which may range from 0 to cnt.
138  */
139 size_t rb_read(rb_t *rb, char *dest, size_t cnt);
140 
141 /**
142  * Read data from the ringbuffer. Opposed to rb_read()
143  * this function does not move the read pointer. Thus it's
144  * a convenient way to inspect data in the ringbuffer in a
145  * continous fashion. The price is that the data is copied
146  * into a user provided buffer. For "raw" non-copy inspection
147  * of the data in the ringbuffer use rb_get_read_vector().
148  *
149  * @param rb a pointer to the ringbuffer structure.
150  * @param dest a pointer to a buffer where data read from the
151  * ringbuffer will go.
152  * @param cnt the number of bytes to read.
153  *
154  * @return the number of bytes read, which may range from 0 to cnt.
155  */
156 size_t rb_peek(rb_t *rb, char *dest, size_t cnt);
157 
158 /**
159  * Advance the read pointer.
160  *
161  * After data have been read from the ringbuffer using the pointers
162  * returned by rb_get_read_vector(), use this function to
163  * advance the buffer pointers, making that space available for future
164  * write operations.
165  *
166  * @param rb a pointer to the ringbuffer structure.
167  * @param cnt the number of bytes read.
168  */
169 void rb_read_advance(rb_t *rb, size_t cnt);
170 
171 /**
172  * Return the number of bytes available for reading.
173  *
174  * @param rb a pointer to the ringbuffer structure.
175  *
176  * @return the number of bytes available to read.
177  */
178 size_t rb_read_space(const rb_t *rb);
179 
180 /**
181  * Lock a ringbuffer data block into memory.
182  *
183  * Uses the mlock() system call.  This is not a realtime operation.
184  *
185  * @param rb a pointer to the ringbuffer structure.
186  */
187 int rb_mlock(rb_t *rb);
188 
189 /**
190  * Reset the read and write pointers, making an empty buffer.
191  *
192  * This is not thread safe.
193  *
194  * @param rb a pointer to the ringbuffer structure.
195  */
196 void rb_reset(rb_t *rb);
197 
198 /**
199  * Write data into the ringbuffer.
200  *
201  * @param rb a pointer to the ringbuffer structure.
202  * @param src a pointer to the data to be written to the ringbuffer.
203  * @param cnt the number of bytes to write.
204  *
205  * @return the number of bytes write, which may range from 0 to cnt
206  */
207 size_t rb_write(rb_t *rb, const char *src,
208 		size_t cnt);
209 
210 /**
211  * Advance the write pointer.
212  *
213  * After data have been written the ringbuffer using the pointers
214  * returned by rb_get_write_vector(), use this function
215  * to advance the buffer pointer, making the data available for future
216  * read operations.
217  *
218  * @param rb a pointer to the ringbuffer structure.
219  * @param cnt the number of bytes written.
220  */
221 void rb_write_advance(rb_t *rb, size_t cnt);
222 
223 /**
224  * Return the number of bytes available for writing.
225  *
226  * @param rb a pointer to the ringbuffer structure.
227  *
228  * @return the amount of free space (in bytes) available for writing.
229  */
230 size_t rb_write_space(const rb_t *rb);
231 
232 #ifdef __cplusplus
233 } /* extern "C" */
234 #endif
235 
236 
237 #endif /* AQUALUNG_RB_H */
238 
239 // vim: shiftwidth=8:tabstop=8:softtabstop=8 :
240 
241