Rockbox

  • Status Closed
  • Percent Complete
    100%
  • Task Type Bugs
  • Category Database
  • Assigned To No-one
  • Operating System All players
  • Severity Low
  • Priority Very Low
  • Reported Version Daily build (which?)
  • Due in Version Undecided
  • Due Date Undecided
  • Votes
  • Private
Attached to Project: Rockbox
Opened by sideral - 2010-11-04
Last edited by Jonathan Gordon - 2010-11-23

FS#11723 - Tagcache returns stale numeric (runtime statistics) data

The problem is that tagcache_update_numeric queues database updates using tagcache.c’s command_queue, whereas tagcache_get_numeric consults the database directly without consulting the command_queue. This can lead to lost updates when pending changes have not yet been processed and committed.

I was able to reproduce this problem with my Sansa ClipV2, but not with the simulator, presumably because of a different thread schedule due to my PC’s better horsepower.

To reproduce, I have been jumping back and forth between two tracks of a playlist. The following slightly edited logf output shows the buffer and unbuffer events (“be:”, “ube:”) logged by tagtree_buffer_event and tagtree_track_finish_event, respectively, along with the playcount read from and written to the tagcache by these functions:

be:/PODCASTS/foo.mp3
-> 3
[...]
ube:/PODCASTS/foo.mp3
-> 4
[...]
be:/PODCASTS/bar.mp3
-> 4
[...]
ube:/PODCASTS/bar.mp3
-> 5
[...]
be:/PODCASTS/foo.mp3
-> 3
[...]
ube:/PODCASTS/foo.mp3
-> 4
[...]
be:/PODCASTS/bar.mp3
-> 4
[...]
ube:/PODCASTS/bar.mp3
-> 5
[...]

As you can see, tagtree_track_finish_event increments the playcount each time, but the next tagtree_buffer_event for the same track reads the old, stale playcount again.

I have considered three solutions to this problem:

1. Flush the command queue in tagcache_get_numeric with a call to run_command_queue(true).

2. Update the in-memory database synchronously in tagcache_update_numeric, and queue only updates to the on-disk database in the command_queue.

3. Store-to-load forwarding: In tagcache_get_numeric, consult the command queue for uncommitted updates to the tag being read.

Solution 1, while simple, also is the most inefficient one as it delays all tagcache reads until all writes have been committed. Also, I encountered the occasional lockup during background database updates – not quote sure why, though.

I was able to implement Solution 2 after some refactoring. Unfortunately, this solution is incomplete: It depends on the in-memory database, and it can fail if the tag being updated has not been loaded into memory yet.

I ended up with Solution 3 (patch attached). It may not be the shortest solution, but it is the most elegant one, as it does not alter the tagcache’s update policy and is complete nonetheless.

(You may wonder why I am so interested in tagcache accuracy (see also  FS#11721  and  FS#11722 ) – after all, this is only statistics data? The answer is that I am working on another use case for the tag cache that requires accuracy: I am using the tagcache as the ultimate resume database, which allows resuming every track at its last-played position, independent of the navigation mechanism used to access the track (no file browser / bookmarking system needed).)

Closed by  Jonathan Gordon
2010-11-23 00:15
Reason for closing:  Accepted
Additional comments about closing:  

r28645.

Jonathan Gordon commented on 2010-11-16 13:03

please fix tabs → 4 spaces and 80 char line widths, otherwise looks good

sideral commented on 2010-11-16 21:30

Thanks for your comment! I’ve updated the patch as advised.

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing