summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-05-16 00:45:08 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-05-16 00:45:08 +0000
commitc909878f94073a364f9b3c75663080c044bff3b8 (patch)
tree9ba9ad0efd7def7c77816ddd83e9bf0eb1fa51b2
parentd59bff092d461c013c0fed34ffa950e1f4ae2aa2 (diff)
downloadrockbox-c909878f94073a364f9b3c75663080c044bff3b8.tar.gz
rockbox-c909878f94073a364f9b3c75663080c044bff3b8.zip
Extend buflib to support shifting space out off the buffer for other use, and returning space to the buffer.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20952 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/lib/buflib.c48
-rw-r--r--apps/plugins/lib/buflib.h5
2 files changed, 53 insertions, 0 deletions
diff --git a/apps/plugins/lib/buflib.c b/apps/plugins/lib/buflib.c
index 514479600e..ddfc82c521 100644
--- a/apps/plugins/lib/buflib.c
+++ b/apps/plugins/lib/buflib.c
@@ -61,6 +61,7 @@ buflib_init(struct buflib_context *ctx, void *buf, size_t size)
61 ctx->last_handle = bd_buf + size; 61 ctx->last_handle = bd_buf + size;
62 ctx->first_free_handle = bd_buf + size - 1; 62 ctx->first_free_handle = bd_buf + size - 1;
63 ctx->first_free_block = bd_buf; 63 ctx->first_free_block = bd_buf;
64 ctx->buf_start = bd_buf;
64 /* A marker is needed for the end of allocated data, to make sure that it 65 /* A marker is needed for the end of allocated data, to make sure that it
65 * does not collide with the handle table, and to detect end-of-buffer. 66 * does not collide with the handle table, and to detect end-of-buffer.
66 */ 67 */
@@ -167,6 +168,53 @@ buflib_compact(struct buflib_context *ctx)
167 return ret || shift; 168 return ret || shift;
168} 169}
169 170
171/* Shift buffered items by size units, and update handle pointers. The shift
172 * value must be determined to be safe *before* calling.
173 */
174static void
175buflib_buffer_shift(struct buflib_context *ctx, int shift)
176{
177 rb->memmove(ctx->buf_start + shift, ctx->buf_start,
178 (ctx->alloc_end - ctx->buf_start) * sizeof(union buflib_data));
179 union buflib_data *ptr;
180 for (ptr = ctx->last_handle; ptr < ctx->handle_table; ptr++)
181 if (ptr->ptr)
182 ptr->ptr += shift;
183 ctx->first_free_block += shift;
184 ctx->buf_start += shift;
185 ctx->alloc_end += shift;
186}
187
188/* Shift buffered items up by size bytes, or as many as possible if size == 0.
189 * Set size to the number of bytes freed.
190 */
191void*
192buflib_buffer_out(struct buflib_context *ctx, size_t *size)
193{
194 if (!ctx->compact)
195 buflib_compact(ctx);
196 size_t avail = ctx->last_handle - ctx->alloc_end;
197 size_t avail_b = avail * sizeof(union buflib_data);
198 if (*size && *size < avail_b)
199 {
200 avail = (*size + sizeof(union buflib_data) - 1)
201 / sizeof(union buflib_data);
202 avail_b = avail * sizeof(union buflib_data);
203 }
204 *size = avail_b;
205 void *ret = ctx->buf_start;
206 buflib_buffer_shift(ctx, avail);
207 return ret;
208}
209
210/* Shift buffered items down by size bytes */
211void
212buflib_buffer_in(struct buflib_context *ctx, int size)
213{
214 size /= sizeof(union buflib_data);
215 buflib_buffer_shift(ctx, -size);
216}
217
170/* Allocate a buffer of size bytes, returning a handle for it */ 218/* Allocate a buffer of size bytes, returning a handle for it */
171int 219int
172buflib_alloc(struct buflib_context *ctx, size_t size) 220buflib_alloc(struct buflib_context *ctx, size_t size)
diff --git a/apps/plugins/lib/buflib.h b/apps/plugins/lib/buflib.h
index ddadb1b9a9..d4ef4af9ff 100644
--- a/apps/plugins/lib/buflib.h
+++ b/apps/plugins/lib/buflib.h
@@ -38,6 +38,7 @@ struct buflib_context
38 union buflib_data *first_free_handle; 38 union buflib_data *first_free_handle;
39 union buflib_data *last_handle; 39 union buflib_data *last_handle;
40 union buflib_data *first_free_block; 40 union buflib_data *first_free_block;
41 union buflib_data *buf_start;
41 union buflib_data *alloc_end; 42 union buflib_data *alloc_end;
42 bool compact; 43 bool compact;
43}; 44};
@@ -45,6 +46,10 @@ struct buflib_context
45void buflib_init(struct buflib_context *context, void *buf, size_t size); 46void buflib_init(struct buflib_context *context, void *buf, size_t size);
46int buflib_alloc(struct buflib_context *context, size_t size); 47int buflib_alloc(struct buflib_context *context, size_t size);
47void buflib_free(struct buflib_context *context, int handle); 48void buflib_free(struct buflib_context *context, int handle);
49void* buflib_buffer_out(struct buflib_context *ctx, size_t *size);
50void buflib_buffer_in(struct buflib_context *ctx, int size);
51
52
48 53
49/* always_inline is due to this not getting inlined when not optimizing, which 54/* always_inline is due to this not getting inlined when not optimizing, which
50 * leads to an unresolved reference since it doesn't exist as a non-inline 55 * leads to an unresolved reference since it doesn't exist as a non-inline