4644ee6e8ed3d002dc5b562d6fd6b9c24c7e1fe3
2 * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
19 /** \file ringbuffer.c simple ringbuffer implementation */
22 #include "ringbuffer.h"
26 * holds all information about one ring buffer
28 * It is intentionally not exported via ringbuffer.h. Think abstract.
35 * the size of this ring buffer
41 * the actual entries of the ringbuffer
47 * the next entry will be added at this position
52 * how many entries the ring buffer contains
58 * initialize a new ringbuffer
60 * @param size the number of entries the ringbuffer holds
62 * This function initializes a circular ring buffer which can hold up to \a
63 * size entries of arbitrary type. If performance is an issue, \a size should
64 * be a power of two to make the underlying modulo operations cheap. Arbitrary
65 * many ringbuffers may be initialized via this function. Each ringbuffer is
66 * identified by a 'cookie'.
68 * Return value: A 'cookie' which identifies the ringbuffer just created and
69 * which must be passed to ringbuffer_add() and ringbuffer_get().
71 void *ringbuffer_new(unsigned size
)
73 struct ringbuffer
*rb
= para_calloc(sizeof(struct ringbuffer
));
74 rb
->entries
= para_calloc(size
* sizeof(void *));
80 * add one entry to a ringbuffer
82 * @param cookie the ringbuffer identifier
83 * @param data the data to be inserted
85 * insert \a data into the ringbuffer associated with \a cookie. As soon as
86 * the ringbuffer fills up, its oldest entry is disregarded and replaced by \a
89 * \return The old \a data pointer which is going to be disregarded, or
90 * NULL if the ringbuffer is not yet full.
92 void *ringbuffer_add(void *cookie
, void *data
)
94 struct ringbuffer
*rb
= cookie
;
95 void *ret
= rb
->entries
[rb
->head
];
96 rb
->entries
[rb
->head
] = data
;
97 rb
->head
= (rb
->head
+ 1) % rb
->size
;
98 if (rb
->filled
< rb
->size
)
104 * get one entry from a ringbuffer
106 * @param cookie the ringbuffer identifier
107 * @param num the number of the entry
109 * \return A pointer to data previously added, or NULL if entry number
110 * \a num is not available. \a num counts backwards from zero, i.e.
111 * ringbuffer_get_entry(0) gets the entry which was added most recently.
113 void *ringbuffer_get(void *cookie
, int num
)
115 struct ringbuffer
*rb
= cookie
;
116 int pos
= (rb
->head
+ rb
->size
- 1 - num
) % rb
->size
;
117 // fprintf(stderr, "pos = %d\n", pos);
118 return rb
->entries
[pos
];
122 * get the number of entries in the ring buffer
124 * @param cookie the ringbuffer identifier
126 * This function always succeeds and never returns a number greater than the
127 * size of the ring buffer.
129 unsigned ringbuffer_filled(void *cookie
)
131 struct ringbuffer
*rb
= cookie
;