blob: d0b41a1571cf5ae484a5638e7a7b8dd2e4f82cff [file] [log] [blame]
Benny Prijono0a749f12005-10-31 21:02:30 +00001/* $Header: /pjproject-0.3/pjlib/src/pj/fifobuf.c 4 9/17/05 10:37a Bennylp $ */
2/* $Log: /pjproject-0.3/pjlib/src/pj/fifobuf.c $
3 *
4 * 4 9/17/05 10:37a Bennylp
5 * Major reorganization towards version 0.3.
6 *
7 */
8#include <pj/fifobuf.h>
9#include <pj/log.h>
10#include <pj/assert.h>
11#include <pj/os.h>
12
13#define THIS_FILE "fifobuf"
14
15#define SZ sizeof(unsigned)
16
17PJ_DEF(void)
18pj_fifobuf_init (pj_fifobuf_t *fifobuf, void *buffer, unsigned size)
19{
20 PJ_CHECK_STACK();
21
22 PJ_LOG(6, (THIS_FILE,
23 "fifobuf_init fifobuf=%p buffer=%p, size=%d",
24 fifobuf, buffer, size));
25
26 fifobuf->first = buffer;
27 fifobuf->last = fifobuf->first + size;
28 fifobuf->ubegin = fifobuf->uend = fifobuf->first;
29 fifobuf->full = 0;
30}
31
32PJ_DEF(unsigned)
33pj_fifobuf_max_size (pj_fifobuf_t *fifobuf)
34{
35 unsigned s1, s2;
36
37 PJ_CHECK_STACK();
38
39 if (fifobuf->uend >= fifobuf->ubegin) {
40 s1 = fifobuf->last - fifobuf->uend;
41 s2 = fifobuf->ubegin - fifobuf->first;
42 } else {
43 s1 = s2 = fifobuf->ubegin - fifobuf->uend;
44 }
45
46 return s1<s2 ? s2 : s1;
47}
48
49PJ_DEF(void*)
50pj_fifobuf_alloc (pj_fifobuf_t *fifobuf, unsigned size)
51{
52 unsigned available;
53 char *start;
54
55 PJ_CHECK_STACK();
56
57 if (fifobuf->full) {
58 PJ_LOG(6, (THIS_FILE,
59 "fifobuf_alloc fifobuf=%p, size=%d: full!",
60 fifobuf, size));
61 return NULL;
62 }
63
64 /* try to allocate from the end part of the fifo */
65 if (fifobuf->uend >= fifobuf->ubegin) {
66 available = fifobuf->last - fifobuf->uend;
67 if (available >= size+SZ) {
68 char *ptr = fifobuf->uend;
69 fifobuf->uend += (size+SZ);
70 if (fifobuf->uend == fifobuf->last)
71 fifobuf->uend = fifobuf->first;
72 if (fifobuf->uend == fifobuf->ubegin)
73 fifobuf->full = 1;
74 *(unsigned*)ptr = size+SZ;
75 ptr += SZ;
76
77 PJ_LOG(6, (THIS_FILE,
78 "fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p",
79 fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));
80 return ptr;
81 }
82 }
83
84 /* try to allocate from the start part of the fifo */
85 start = (fifobuf->uend <= fifobuf->ubegin) ? fifobuf->uend : fifobuf->first;
86 available = fifobuf->ubegin - start;
87 if (available >= size+SZ) {
88 char *ptr = start;
89 fifobuf->uend = start + size + SZ;
90 if (fifobuf->uend == fifobuf->ubegin)
91 fifobuf->full = 1;
92 *(unsigned*)ptr = size+SZ;
93 ptr += SZ;
94
95 PJ_LOG(6, (THIS_FILE,
96 "fifobuf_alloc fifobuf=%p, size=%d: returning %p, p1=%p, p2=%p",
97 fifobuf, size, ptr, fifobuf->ubegin, fifobuf->uend));
98 return ptr;
99 }
100
101 PJ_LOG(6, (THIS_FILE,
102 "fifobuf_alloc fifobuf=%p, size=%d: no space left! p1=%p, p2=%p",
103 fifobuf, size, fifobuf->ubegin, fifobuf->uend));
104 return NULL;
105}
106
107PJ_DEF(pj_status_t)
108pj_fifobuf_unalloc (pj_fifobuf_t *fifobuf, void *buf)
109{
110 char *ptr = buf;
111 char *endptr;
112 unsigned sz;
113
114 PJ_CHECK_STACK();
115
116 ptr -= SZ;
117 sz = *(unsigned*)ptr;
118
119 endptr = fifobuf->uend;
120 if (endptr == fifobuf->first)
121 endptr = fifobuf->last;
122
123 if (ptr+sz != endptr) {
124 pj_assert(!"Invalid pointer to undo alloc");
125 return -1;
126 }
127
128 fifobuf->uend = ptr;
129 fifobuf->full = 0;
130
131 PJ_LOG(6, (THIS_FILE,
132 "fifobuf_unalloc fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p",
133 fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));
134
135 return 0;
136}
137
138PJ_DEF(pj_status_t)
139pj_fifobuf_free (pj_fifobuf_t *fifobuf, void *buf)
140{
141 char *ptr = buf;
142 char *end;
143 unsigned sz;
144
145 PJ_CHECK_STACK();
146
147 ptr -= SZ;
148 if (ptr < fifobuf->first || ptr >= fifobuf->last) {
149 pj_assert(!"Invalid pointer to free");
150 return -1;
151 }
152
153 if (ptr != fifobuf->ubegin && ptr != fifobuf->first) {
154 pj_assert(!"Invalid free() sequence!");
155 return -1;
156 }
157
158 end = (fifobuf->uend > fifobuf->ubegin) ? fifobuf->uend : fifobuf->last;
159 sz = *(unsigned*)ptr;
160 if (ptr+sz > end) {
161 pj_assert(!"Invalid size!");
162 return -1;
163 }
164
165 fifobuf->ubegin = ptr + sz;
166
167 /* Rollover */
168 if (fifobuf->ubegin == fifobuf->last)
169 fifobuf->ubegin = fifobuf->first;
170
171 /* Reset if fifobuf is empty */
172 if (fifobuf->ubegin == fifobuf->uend)
173 fifobuf->ubegin = fifobuf->uend = fifobuf->first;
174
175 fifobuf->full = 0;
176
177 PJ_LOG(6, (THIS_FILE,
178 "fifobuf_free fifobuf=%p, ptr=%p, size=%d, p1=%p, p2=%p",
179 fifobuf, buf, sz, fifobuf->ubegin, fifobuf->uend));
180
181 return 0;
182}