diff options
author | Thomas Martitz <kugel@rockbox.org> | 2013-11-21 11:40:04 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2013-12-22 23:11:32 +0100 |
commit | 64b9e1fa7b645daa36ca0018dc168d4f871fd538 (patch) | |
tree | 207a693773d001307c5f3247fd435f9bc65a192c | |
parent | d25a512caf4adf2aac3ce6ac8e1f2c556c0c6c37 (diff) | |
download | rockbox-64b9e1fa7b645daa36ca0018dc168d4f871fd538.tar.gz rockbox-64b9e1fa7b645daa36ca0018dc168d4f871fd538.zip |
buflib: Add buflib_context_relocate().
This function relocates a buflib back buffer, updating pointers in struct
buflib_context. It does not move any data by itself.
The intended use-case is buflib-on-buflib, where a buflib back buffer is
allocated with buflib and attempted to be moved. The move_callback() can call
this and return BUFLIB_CB_OK on success. No move_callback() is called for the
subordinate buflib buffer, therefore it must not contain non-movable
allocations. The caller is generally responsible moving the data and all its
implications.
Change-Id: I869219f9cff786a172c9e917a5f34470073892e6
-rw-r--r-- | firmware/buflib.c | 26 | ||||
-rw-r--r-- | firmware/include/buflib.h | 15 |
2 files changed, 41 insertions, 0 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c index 4233bf9a61..d7a24b8722 100644 --- a/firmware/buflib.c +++ b/firmware/buflib.c | |||
@@ -117,6 +117,32 @@ buflib_init(struct buflib_context *ctx, void *buf, size_t size) | |||
117 | (unsigned long)size / 1024, ((unsigned long)size%1000)/10); | 117 | (unsigned long)size / 1024, ((unsigned long)size%1000)/10); |
118 | } | 118 | } |
119 | 119 | ||
120 | bool buflib_context_relocate(struct buflib_context *ctx, void *buf) | ||
121 | { | ||
122 | union buflib_data *handle, *bd_buf = buf; | ||
123 | ptrdiff_t diff = bd_buf - ctx->buf_start; | ||
124 | |||
125 | /* cannot continue if the buffer is not aligned, since we would need | ||
126 | * to reduce the size of the buffer for aligning */ | ||
127 | if ((uintptr_t)buf & 0x3) | ||
128 | return false; | ||
129 | |||
130 | /* relocate the handle table entries */ | ||
131 | for (handle = ctx->last_handle; handle < ctx->handle_table; handle++) | ||
132 | { | ||
133 | if (handle->alloc) | ||
134 | handle->alloc += diff * sizeof(union buflib_data); | ||
135 | } | ||
136 | /* relocate the pointers in the context */ | ||
137 | ctx->handle_table += diff; | ||
138 | ctx->last_handle += diff; | ||
139 | ctx->first_free_handle += diff; | ||
140 | ctx->buf_start += diff; | ||
141 | ctx->alloc_end += diff; | ||
142 | |||
143 | return true; | ||
144 | } | ||
145 | |||
120 | /* Allocate a new handle, returning 0 on failure */ | 146 | /* Allocate a new handle, returning 0 on failure */ |
121 | static inline | 147 | static inline |
122 | union buflib_data* handle_alloc(struct buflib_context *ctx) | 148 | union buflib_data* handle_alloc(struct buflib_context *ctx) |
diff --git a/firmware/include/buflib.h b/firmware/include/buflib.h index aa6c232f72..0b26c04bcd 100644 --- a/firmware/include/buflib.h +++ b/firmware/include/buflib.h | |||
@@ -157,6 +157,21 @@ size_t buflib_available(struct buflib_context *ctx); | |||
157 | */ | 157 | */ |
158 | size_t buflib_allocatable(struct buflib_context *ctx); | 158 | size_t buflib_allocatable(struct buflib_context *ctx); |
159 | 159 | ||
160 | /** | ||
161 | * Relocates the fields in *ctx to the new buffer position pointed to by buf. | ||
162 | * This does _not_ move any data but updates the pointers. The data has | ||
163 | * to be moved afterwards manually and only if this function returned true. | ||
164 | * | ||
165 | * This is intended to be called from within a move_callback(), for | ||
166 | * buflib-on-buflib scenarios (i.e. a new buflib instance backed by a buffer | ||
167 | * that was allocated by another buflib instance). Be aware that if the parent | ||
168 | * move_callback() moves the underlying buffer _no_ move_callback() of the | ||
169 | * underlying buffer are called. | ||
170 | * | ||
171 | * Returns true of the relocation was successful. If it returns false no | ||
172 | * change to *ctx was made. | ||
173 | */ | ||
174 | bool buflib_context_relocate(struct buflib_context *ctx, void *buf); | ||
160 | 175 | ||
161 | /** | 176 | /** |
162 | * Allocates memory from buflib's memory pool | 177 | * Allocates memory from buflib's memory pool |