summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/buffering.c112
1 files changed, 68 insertions, 44 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index f261b5a711..ee375e9172 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -91,17 +91,6 @@
91#define BUF_HANDLE_MASK 0x7FFFFFFF 91#define BUF_HANDLE_MASK 0x7FFFFFFF
92 92
93 93
94/* Ring buffer helper macros */
95/* Buffer pointer (p) plus value (v), wrapped if necessary */
96#define RINGBUF_ADD(p,v) (((p)+(v))<buffer_len ? (p)+(v) : (p)+(v)-buffer_len)
97/* Buffer pointer (p) minus value (v), wrapped if necessary */
98#define RINGBUF_SUB(p,v) ((p>=v) ? (p)-(v) : (p)+buffer_len-(v))
99/* How far value (v) plus buffer pointer (p1) will cross buffer pointer (p2) */
100#define RINGBUF_ADD_CROSS(p1,v,p2) \
101((p1<p2) ? (int)((p1)+(v))-(int)(p2) : (int)((p1)+(v)-(p2))-(int)buffer_len)
102/* Bytes available in the buffer */
103#define BUF_USED RINGBUF_SUB(buf_widx, buf_ridx)
104
105/* assert(sizeof(struct memory_handle)%4==0) */ 94/* assert(sizeof(struct memory_handle)%4==0) */
106struct memory_handle { 95struct memory_handle {
107 int id; /* A unique ID for the handle */ 96 int id; /* A unique ID for the handle */
@@ -186,6 +175,41 @@ static struct queue_sender_list buffering_queue_sender_list;
186 175
187 176
188 177
178/* Ring buffer helper functions */
179/* Buffer pointer (p) plus value (v), wrapped if necessary */
180static inline uintptr_t ringbuf_add(uintptr_t p, size_t v)
181{
182 uintptr_t res = p + v;
183 if (res >= buffer_len)
184 res -= buffer_len; /* wrap if necssary */
185 return res;
186}
187
188
189/* Buffer pointer (p) minus value (v), wrapped if necessary */
190static inline uintptr_t ringbuf_sub(uintptr_t p, size_t v)
191{
192 uintptr_t res = p;
193 if (p < v)
194 res += buffer_len; /* wrap */
195
196 return res - v;
197}
198
199
200/* How far value (v) plus buffer pointer (p1) will cross buffer pointer (p2) */
201static inline ssize_t ringbuf_add_cross(uintptr_t p1, size_t v, uintptr_t p2)
202{
203 ssize_t res = p1 + v - p2;
204 if (p1 >= p2) /* wrap if necessary */
205 res -= buffer_len;
206
207 return res;
208}
209
210/* Bytes available in the buffer */
211#define BUF_USED ringbuf_sub(buf_widx, buf_ridx)
212
189/* 213/*
190LINKED LIST MANAGEMENT 214LINKED LIST MANAGEMENT
191====================== 215======================
@@ -239,19 +263,19 @@ static struct memory_handle *add_handle(size_t data_size, bool can_wrap,
239 a new one if there is already enough free space to finish 263 a new one if there is already enough free space to finish
240 the buffering. */ 264 the buffering. */
241 size_t req = cur_handle->filerem + sizeof(struct memory_handle); 265 size_t req = cur_handle->filerem + sizeof(struct memory_handle);
242 if (RINGBUF_ADD_CROSS(cur_handle->widx, req, buf_ridx) >= 0) { 266 if (ringbuf_add_cross(cur_handle->widx, req, buf_ridx) >= 0) {
243 /* Not enough space */ 267 /* Not enough space */
244 mutex_unlock(&llist_mod_mutex); 268 mutex_unlock(&llist_mod_mutex);
245 mutex_unlock(&llist_mutex); 269 mutex_unlock(&llist_mutex);
246 return NULL; 270 return NULL;
247 } else { 271 } else {
248 /* Allocate the remainder of the space for the current handle */ 272 /* Allocate the remainder of the space for the current handle */
249 buf_widx = RINGBUF_ADD(cur_handle->widx, cur_handle->filerem); 273 buf_widx = ringbuf_add(cur_handle->widx, cur_handle->filerem);
250 } 274 }
251 } 275 }
252 276
253 /* align to 4 bytes up */ 277 /* align to 4 bytes up */
254 new_widx = RINGBUF_ADD(buf_widx, 3) & ~3; 278 new_widx = ringbuf_add(buf_widx, 3) & ~3;
255 279
256 len = data_size + sizeof(struct memory_handle); 280 len = data_size + sizeof(struct memory_handle);
257 281
@@ -264,10 +288,10 @@ static struct memory_handle *add_handle(size_t data_size, bool can_wrap,
264 } 288 }
265 289
266 /* How far we shifted buf_widx to align things, must be < buffer_len */ 290 /* How far we shifted buf_widx to align things, must be < buffer_len */
267 shift = RINGBUF_SUB(new_widx, buf_widx); 291 shift = ringbuf_sub(new_widx, buf_widx);
268 292
269 /* How much space are we short in the actual ring buffer? */ 293 /* How much space are we short in the actual ring buffer? */
270 overlap = RINGBUF_ADD_CROSS(buf_widx, shift + len, buf_ridx); 294 overlap = ringbuf_add_cross(buf_widx, shift + len, buf_ridx);
271 if (overlap >= 0 && (alloc_all || (unsigned)overlap > data_size)) { 295 if (overlap >= 0 && (alloc_all || (unsigned)overlap > data_size)) {
272 /* Not enough space for required allocations */ 296 /* Not enough space for required allocations */
273 mutex_unlock(&llist_mod_mutex); 297 mutex_unlock(&llist_mod_mutex);
@@ -283,7 +307,7 @@ static struct memory_handle *add_handle(size_t data_size, bool can_wrap,
283 (struct memory_handle *)(&buffer[buf_widx]); 307 (struct memory_handle *)(&buffer[buf_widx]);
284 308
285 /* only advance the buffer write index of the size of the struct */ 309 /* only advance the buffer write index of the size of the struct */
286 buf_widx = RINGBUF_ADD(buf_widx, sizeof(struct memory_handle)); 310 buf_widx = ringbuf_add(buf_widx, sizeof(struct memory_handle));
287 311
288 new_handle->id = cur_handle_id; 312 new_handle->id = cur_handle_id;
289 /* Wrap signed int is safe and 0 doesn't happen */ 313 /* Wrap signed int is safe and 0 doesn't happen */
@@ -433,9 +457,9 @@ static bool move_handle(struct memory_handle **h, size_t *delta,
433 mutex_lock(&llist_mod_mutex); 457 mutex_lock(&llist_mod_mutex);
434 458
435 oldpos = (void *)src - (void *)buffer; 459 oldpos = (void *)src - (void *)buffer;
436 newpos = RINGBUF_ADD(oldpos, final_delta); 460 newpos = ringbuf_add(oldpos, final_delta);
437 overlap = RINGBUF_ADD_CROSS(newpos, size_to_move, buffer_len - 1); 461 overlap = ringbuf_add_cross(newpos, size_to_move, buffer_len - 1);
438 overlap_old = RINGBUF_ADD_CROSS(oldpos, size_to_move, buffer_len -1); 462 overlap_old = ringbuf_add_cross(oldpos, size_to_move, buffer_len -1);
439 463
440 if (overlap > 0) { 464 if (overlap > 0) {
441 /* Some part of the struct + data would wrap, maybe ok */ 465 /* Some part of the struct + data would wrap, maybe ok */
@@ -500,8 +524,8 @@ static bool move_handle(struct memory_handle **h, size_t *delta,
500 * copy may be ok but do this for safety and because wrapped copies should 524 * copy may be ok but do this for safety and because wrapped copies should
501 * be fairly uncommon */ 525 * be fairly uncommon */
502 526
503 here = (int32_t *)((RINGBUF_ADD(oldpos, size_to_move - 1) & ~3)+ (intptr_t)buffer); 527 here = (int32_t *)((ringbuf_add(oldpos, size_to_move - 1) & ~3)+ (intptr_t)buffer);
504 there =(int32_t *)((RINGBUF_ADD(newpos, size_to_move - 1) & ~3)+ (intptr_t)buffer); 528 there =(int32_t *)((ringbuf_add(newpos, size_to_move - 1) & ~3)+ (intptr_t)buffer);
505 end = (int32_t *)(( intptr_t)buffer + buffer_len - 4); 529 end = (int32_t *)(( intptr_t)buffer + buffer_len - 4);
506 begin =(int32_t *)buffer; 530 begin =(int32_t *)buffer;
507 531
@@ -561,14 +585,14 @@ static void update_data_counters(void)
561 m = first_handle; 585 m = first_handle;
562 while (m) { 586 while (m) {
563 buffered += m->available; 587 buffered += m->available;
564 wasted += RINGBUF_SUB(m->ridx, m->data); 588 wasted += ringbuf_sub(m->ridx, m->data);
565 remaining += m->filerem; 589 remaining += m->filerem;
566 590
567 if (m->id == base_handle_id) 591 if (m->id == base_handle_id)
568 is_useful = true; 592 is_useful = true;
569 593
570 if (is_useful) 594 if (is_useful)
571 useful += RINGBUF_SUB(m->widx, m->ridx); 595 useful += ringbuf_sub(m->widx, m->ridx);
572 596
573 m = m->next; 597 m = m->next;
574 } 598 }
@@ -643,14 +667,14 @@ static bool buffer_handle(int handle_id)
643 buffer_len - h->widx); 667 buffer_len - h->widx);
644 668
645 /* stop copying if it would overwrite the reading position */ 669 /* stop copying if it would overwrite the reading position */
646 if (RINGBUF_ADD_CROSS(h->widx, copy_n, buf_ridx) >= 0) 670 if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0)
647 return false; 671 return false;
648 672
649 /* This would read into the next handle, this is broken 673 /* This would read into the next handle, this is broken
650 if (h->next && RINGBUF_ADD_CROSS(h->widx, copy_n, 674 if (h->next && ringbuf_add_cross(h->widx, copy_n,
651 (unsigned)((void *)h->next - (void *)buffer)) > 0) { 675 (unsigned)((void *)h->next - (void *)buffer)) > 0) {
652 Try to recover by truncating this file 676 Try to recover by truncating this file
653 copy_n = RINGBUF_ADD_CROSS(h->widx, copy_n, 677 copy_n = ringbuf_add_cross(h->widx, copy_n,
654 (unsigned)((void *)h->next - (void *)buffer)); 678 (unsigned)((void *)h->next - (void *)buffer));
655 h->filerem -= copy_n; 679 h->filerem -= copy_n;
656 h->filesize -= copy_n; 680 h->filesize -= copy_n;
@@ -679,7 +703,7 @@ static bool buffer_handle(int handle_id)
679 } 703 }
680 704
681 /* Advance buffer */ 705 /* Advance buffer */
682 h->widx = RINGBUF_ADD(h->widx, rc); 706 h->widx = ringbuf_add(h->widx, rc);
683 if (h == cur_handle) 707 if (h == cur_handle)
684 buf_widx = h->widx; 708 buf_widx = h->widx;
685 h->available += rc; 709 h->available += rc;
@@ -726,7 +750,7 @@ static void reset_handle(int handle_id)
726 /* Align to desired storage alignment */ 750 /* Align to desired storage alignment */
727 alignment_pad = (h->offset - (size_t)(&buffer[h->start])) 751 alignment_pad = (h->offset - (size_t)(&buffer[h->start]))
728 & STORAGE_ALIGN_MASK; 752 & STORAGE_ALIGN_MASK;
729 h->ridx = h->widx = h->data = RINGBUF_ADD(h->start, alignment_pad); 753 h->ridx = h->widx = h->data = ringbuf_add(h->start, alignment_pad);
730 754
731 if (h == cur_handle) 755 if (h == cur_handle)
732 buf_widx = h->widx; 756 buf_widx = h->widx;
@@ -762,7 +786,7 @@ static void rebuffer_handle(int handle_id, size_t newpos)
762 queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id); 786 queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id);
763 787
764 size_t next = (unsigned)((void *)h->next - (void *)buffer); 788 size_t next = (unsigned)((void *)h->next - (void *)buffer);
765 if (RINGBUF_SUB(next, h->data) < h->filesize - newpos) 789 if (ringbuf_sub(next, h->data) < h->filesize - newpos)
766 { 790 {
767 /* There isn't enough space to rebuffer all of the track from its new 791 /* There isn't enough space to rebuffer all of the track from its new
768 offset, so we ask the user to free some */ 792 offset, so we ask the user to free some */
@@ -808,7 +832,7 @@ static void shrink_handle(struct memory_handle *h)
808 { 832 {
809 /* metadata handle: we can move all of it */ 833 /* metadata handle: we can move all of it */
810 size_t handle_distance = 834 size_t handle_distance =
811 RINGBUF_SUB((unsigned)((void *)h->next - (void*)buffer), h->data); 835 ringbuf_sub((unsigned)((void *)h->next - (void*)buffer), h->data);
812 delta = handle_distance - h->available; 836 delta = handle_distance - h->available;
813 837
814 /* The value of delta might change for alignment reasons */ 838 /* The value of delta might change for alignment reasons */
@@ -816,9 +840,9 @@ static void shrink_handle(struct memory_handle *h)
816 return; 840 return;
817 841
818 size_t olddata = h->data; 842 size_t olddata = h->data;
819 h->data = RINGBUF_ADD(h->data, delta); 843 h->data = ringbuf_add(h->data, delta);
820 h->ridx = RINGBUF_ADD(h->ridx, delta); 844 h->ridx = ringbuf_add(h->ridx, delta);
821 h->widx = RINGBUF_ADD(h->widx, delta); 845 h->widx = ringbuf_add(h->widx, delta);
822 846
823 if (h->type == TYPE_ID3 && h->filesize == sizeof(struct mp3entry)) { 847 if (h->type == TYPE_ID3 && h->filesize == sizeof(struct mp3entry)) {
824 /* when moving an mp3entry we need to readjust its pointers. */ 848 /* when moving an mp3entry we need to readjust its pointers. */
@@ -834,12 +858,12 @@ static void shrink_handle(struct memory_handle *h)
834 else 858 else
835 { 859 {
836 /* only move the handle struct */ 860 /* only move the handle struct */
837 delta = RINGBUF_SUB(h->ridx, h->data); 861 delta = ringbuf_sub(h->ridx, h->data);
838 if (!move_handle(&h, &delta, 0, true)) 862 if (!move_handle(&h, &delta, 0, true))
839 return; 863 return;
840 864
841 h->data = RINGBUF_ADD(h->data, delta); 865 h->data = ringbuf_add(h->data, delta);
842 h->start = RINGBUF_ADD(h->start, delta); 866 h->start = ringbuf_add(h->start, delta);
843 h->available -= delta; 867 h->available -= delta;
844 h->offset += delta; 868 h->offset += delta;
845 } 869 }
@@ -1016,7 +1040,7 @@ int bufopen(const char *file, size_t offset, enum data_type type,
1016 /* Align to desired storage alignment */ 1040 /* Align to desired storage alignment */
1017 alignment_pad = (adjusted_offset - (size_t)(&buffer[buf_widx])) 1041 alignment_pad = (adjusted_offset - (size_t)(&buffer[buf_widx]))
1018 & STORAGE_ALIGN_MASK; 1042 & STORAGE_ALIGN_MASK;
1019 buf_widx = RINGBUF_ADD(buf_widx, alignment_pad); 1043 buf_widx = ringbuf_add(buf_widx, alignment_pad);
1020 } 1044 }
1021 1045
1022 h->ridx = buf_widx; 1046 h->ridx = buf_widx;
@@ -1145,7 +1169,7 @@ int bufseek(int handle_id, size_t newpos)
1145 rebuffer_handle(handle_id, newpos); 1169 rebuffer_handle(handle_id, newpos);
1146 } 1170 }
1147 else { 1171 else {
1148 h->ridx = RINGBUF_ADD(h->data, newpos - h->offset); 1172 h->ridx = ringbuf_add(h->data, newpos - h->offset);
1149 } 1173 }
1150 return 0; 1174 return 0;
1151} 1175}
@@ -1158,7 +1182,7 @@ int bufadvance(int handle_id, off_t offset)
1158 if (!h) 1182 if (!h)
1159 return ERR_HANDLE_NOT_FOUND; 1183 return ERR_HANDLE_NOT_FOUND;
1160 1184
1161 size_t newpos = h->offset + RINGBUF_SUB(h->ridx, h->data) + offset; 1185 size_t newpos = h->offset + ringbuf_sub(h->ridx, h->data) + offset;
1162 return bufseek(handle_id, newpos); 1186 return bufseek(handle_id, newpos);
1163} 1187}
1164 1188
@@ -1173,7 +1197,7 @@ static struct memory_handle *prep_bufdata(int handle_id, size_t *size,
1173 if (!h) 1197 if (!h)
1174 return NULL; 1198 return NULL;
1175 1199
1176 size_t avail = RINGBUF_SUB(h->widx, h->ridx); 1200 size_t avail = ringbuf_sub(h->widx, h->ridx);
1177 1201
1178 if (avail == 0 && h->filerem == 0) 1202 if (avail == 0 && h->filerem == 0)
1179 { 1203 {
@@ -1207,7 +1231,7 @@ static struct memory_handle *prep_bufdata(int handle_id, size_t *size,
1207 h = find_handle(handle_id); 1231 h = find_handle(handle_id);
1208 if (!h) 1232 if (!h)
1209 return NULL; 1233 return NULL;
1210 avail = RINGBUF_SUB(h->widx, h->ridx); 1234 avail = ringbuf_sub(h->widx, h->ridx);
1211 } 1235 }
1212 while (h->filerem > 0 && avail < *size); 1236 while (h->filerem > 0 && avail < *size);
1213 } 1237 }
@@ -1296,7 +1320,7 @@ ssize_t bufgettail(int handle_id, size_t size, void **data)
1296 if (size > GUARD_BUFSIZE) 1320 if (size > GUARD_BUFSIZE)
1297 return ERR_INVALID_VALUE; 1321 return ERR_INVALID_VALUE;
1298 1322
1299 tidx = RINGBUF_SUB(h->widx, size); 1323 tidx = ringbuf_sub(h->widx, size);
1300 1324
1301 if (tidx + size > buffer_len) 1325 if (tidx + size > buffer_len)
1302 { 1326 {
@@ -1326,7 +1350,7 @@ ssize_t bufcuttail(int handle_id, size_t size)
1326 1350
1327 h->available -= adjusted_size; 1351 h->available -= adjusted_size;
1328 h->filesize -= adjusted_size; 1352 h->filesize -= adjusted_size;
1329 h->widx = RINGBUF_SUB(h->widx, adjusted_size); 1353 h->widx = ringbuf_sub(h->widx, adjusted_size);
1330 if (h == cur_handle) 1354 if (h == cur_handle)
1331 buf_widx = h->widx; 1355 buf_widx = h->widx;
1332 1356