summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-05-16 16:15:34 -0400
committerMichael Sevakis <jethead71@rockbox.org>2013-05-23 18:25:29 +0200
commitb7e0e1a0a3b44868ddb9ad60210158ccbe220e90 (patch)
treeab477ee6f568c4b84a4765d463f7b771d62cba14
parent33f3af2b8dbda1e67f07c9c63a07fb3e9af6fa59 (diff)
downloadrockbox-b7e0e1a0a3b44868ddb9ad60210158ccbe220e90.tar.gz
rockbox-b7e0e1a0a3b44868ddb9ad60210158ccbe220e90.zip
buflib: Remove compulsory IRQ disable during buffer move.
It can cause excessively long interrupt outages if moving a larger buffer and disrupt audio where DMA is not at a higher interrupt priority such as FIQ. Some targets, like Gigabeat S, have very low audio interrupt latency requirements and will even channel swap if they are missed. Pictureflow will make the issue very obvious. Even then, moves could take milliseconds or more depending on the buffer size which is far too long for any target. Change-Id: I8e7817213e901da67c36b7eb25d7cb1c1e3ba802 Reviewed-on: http://gerrit.rockbox.org/472 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
-rw-r--r--firmware/buflib.c18
1 files changed, 2 insertions, 16 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c
index a007603161..9b591ad786 100644
--- a/firmware/buflib.c
+++ b/firmware/buflib.c
@@ -208,18 +208,10 @@ move_block(struct buflib_context* ctx, union buflib_data* block, int shift)
208 new_block = block + shift; 208 new_block = block + shift;
209 new_start = tmp->alloc + shift*sizeof(union buflib_data); 209 new_start = tmp->alloc + shift*sizeof(union buflib_data);
210 210
211 /* disable IRQs to make accessing the buffer from interrupt context safe. */ 211 /* If move must be synchronized with use, user should have specified a
212 /* protect the move callback, as a cached global pointer might be updated 212 callback that handles this */
213 * in it. and protect "tmp->alloc = new_start" for buflib_get_data() */
214 /* call the callback before moving */
215 if (ops && ops->sync_callback) 213 if (ops && ops->sync_callback)
216 {
217 ops->sync_callback(handle, true); 214 ops->sync_callback(handle, true);
218 }
219 else
220 {
221 disable_irq();
222 }
223 215
224 bool retval = false; 216 bool retval = false;
225 if (!ops || ops->move_callback(handle, tmp->alloc, new_start) 217 if (!ops || ops->move_callback(handle, tmp->alloc, new_start)
@@ -231,13 +223,7 @@ move_block(struct buflib_context* ctx, union buflib_data* block, int shift)
231 } 223 }
232 224
233 if (ops && ops->sync_callback) 225 if (ops && ops->sync_callback)
234 {
235 ops->sync_callback(handle, false); 226 ops->sync_callback(handle, false);
236 }
237 else
238 {
239 enable_irq();
240 }
241 227
242 return retval; 228 return retval;
243} 229}