1
/* $Id: fifobuf.c 4537 2013-06-19 06:47:43Z riza $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include <pj/fifobuf.h>
22
#include <pj/assert.h>
25
#define THIS_FILE "fifobuf"
27
#define SZ sizeof(unsigned)
29
PJ_DEF(void) pj_fifobuf_init (pj_fifobuf_t *fifobuf, void *buffer, unsigned size)
34
"fifobuf_init fifobuf=%p buffer=%p, size=%d",
35
fifobuf, buffer, size));
37
fifobuf->first = (char*)buffer;
38
fifobuf->last = fifobuf->first + size;
39
fifobuf->ubegin = fifobuf->uend = fifobuf->first;
43
PJ_DEF(unsigned) pj_fifobuf_max_size (pj_fifobuf_t *fifobuf)
49
if (fifobuf->uend >= fifobuf->ubegin) {
50
s1 = (unsigned)(fifobuf->last - fifobuf->uend);
51
s2 = (unsigned)(fifobuf->ubegin - fifobuf->first);
53
s1 = s2 = (unsigned)(fifobuf->ubegin - fifobuf->uend);
56
return s1<s2 ? s2 : s1;
59
PJ_DEF(void*) pj_fifobuf_alloc (pj_fifobuf_t *fifobuf, unsigned size)
68
"fifobuf_alloc fifobuf=%p, size=%d: full!",
73
/* try to allocate from the end part of the fifo */
74
if (fifobuf->uend >= fifobuf->ubegin) {
75
available = (unsigned)(fifobuf->last - fifobuf->uend);
76
if (available >= size+SZ) {
77
char *ptr = fifobuf->uend;
78
fifobuf->uend += (size+SZ);
79
if (fifobuf->uend == fifobuf->last)
80
fifobuf->uend = fifobuf->first;
81
if (fifobuf->uend == fifobuf->ubegin)
83
*(unsigned*)ptr = size+SZ;
87
"fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p",
88
fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));
93
/* try to allocate from the start part of the fifo */
94
start = (fifobuf->uend <= fifobuf->ubegin) ? fifobuf->uend : fifobuf->first;
95
available = (unsigned)(fifobuf->ubegin - start);
96
if (available >= size+SZ) {
98
fifobuf->uend = start + size + SZ;
99
if (fifobuf->uend == fifobuf->ubegin)
101
*(unsigned*)ptr = size+SZ;
104
PJ_LOG(6, (THIS_FILE,
105
"fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p",
106
fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));
110
PJ_LOG(6, (THIS_FILE,
111
"fifobuf_alloc fifobuf=%p, size=%d: no space left! p1=%p, p2=%p",
112
fifobuf, size, fifobuf->ubegin, fifobuf->uend));
116
PJ_DEF(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fifobuf, void *buf)
118
char *ptr = (char*)buf;
125
sz = *(unsigned*)ptr;
127
endptr = fifobuf->uend;
128
if (endptr == fifobuf->first)
129
endptr = fifobuf->last;
131
if (ptr+sz != endptr) {
132
pj_assert(!"Invalid pointer to undo alloc");
139
PJ_LOG(6, (THIS_FILE,
140
"fifobuf_unalloc fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p",
141
fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));
146
PJ_DEF(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fifobuf, void *buf)
148
char *ptr = (char*)buf;
155
if (ptr < fifobuf->first || ptr >= fifobuf->last) {
156
pj_assert(!"Invalid pointer to free");
160
if (ptr != fifobuf->ubegin && ptr != fifobuf->first) {
161
pj_assert(!"Invalid free() sequence!");
165
end = (fifobuf->uend > fifobuf->ubegin) ? fifobuf->uend : fifobuf->last;
166
sz = *(unsigned*)ptr;
168
pj_assert(!"Invalid size!");
172
fifobuf->ubegin = ptr + sz;
175
if (fifobuf->ubegin == fifobuf->last)
176
fifobuf->ubegin = fifobuf->first;
178
/* Reset if fifobuf is empty */
179
if (fifobuf->ubegin == fifobuf->uend)
180
fifobuf->ubegin = fifobuf->uend = fifobuf->first;
184
PJ_LOG(6, (THIS_FILE,
185
"fifobuf_free fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p",
186
fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));