Tagcache: Fixed runtime stats not being gathered when tagcache is kept
on disk. Initial attempt to make tagcache thread safe. Replaced a few direct buffer allocations with buffer_alloc from tagcache and dircache where possible. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10415 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
d68ae6a7a6
commit
d8ac607418
5 changed files with 74 additions and 22 deletions
|
@ -850,7 +850,7 @@ int onplay(char* file, int attr, int from)
|
|||
|
||||
if (context == CONTEXT_WPS ||
|
||||
context == CONTEXT_TREE ||
|
||||
(context == CONTEXT_ID3DB))
|
||||
context == CONTEXT_ID3DB)
|
||||
{
|
||||
items[i].desc = ID2P(LANG_PLAYLIST);
|
||||
items[i].function = playlist_options;
|
||||
|
|
|
@ -43,9 +43,9 @@
|
|||
* | | | | +--x--------x---------+ |
|
||||
* | | | | | Temporary Commit DB | |
|
||||
* | | | | +---------------------+ |
|
||||
* +-x----x---x---x--+ |
|
||||
* +-x----x-------x--+ |
|
||||
* | TagCache RAM DB x==\(W) +-----------------+ |
|
||||
* +-x----x---x---x--+ \===x | |
|
||||
* +-----------------+ \===x | |
|
||||
* | | | | (R) | Ram DB Loader x============x DirCache
|
||||
* +-x----x---x---x---+ /==x | | (optional)
|
||||
* | Tagcache Disk DB x==/ +-----------------+ |
|
||||
|
@ -191,6 +191,10 @@ static int total_entry_count = 0;
|
|||
static int data_size = 0;
|
||||
static int processed_dir_count;
|
||||
|
||||
/* Thread safe locking */
|
||||
static volatile int write_lock;
|
||||
static volatile int read_lock;
|
||||
|
||||
int tagcache_str_to_tag(const char *str)
|
||||
{
|
||||
int i;
|
||||
|
@ -516,6 +520,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx)
|
|||
sizeof(struct index_entry))
|
||||
{
|
||||
logf("write error #3");
|
||||
logf("idxid: %d", idxid);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -818,9 +823,12 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
|||
struct master_header master_hdr;
|
||||
int i;
|
||||
|
||||
if (tcs->valid)
|
||||
if (tcs->initialized)
|
||||
tagcache_search_finish(tcs);
|
||||
|
||||
while (read_lock)
|
||||
sleep(1);
|
||||
|
||||
memset(tcs, 0, sizeof(struct tagcache_search));
|
||||
if (stat.commit_step > 0 || !stat.ready)
|
||||
return false;
|
||||
|
@ -830,7 +838,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
|||
tcs->seek_pos = 0;
|
||||
tcs->seek_list_count = 0;
|
||||
tcs->filter_count = 0;
|
||||
tcs->valid = true;
|
||||
tcs->masterfd = -1;
|
||||
|
||||
for (i = 0; i < TAG_COUNT; i++)
|
||||
|
@ -848,18 +855,28 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
|||
#endif
|
||||
{
|
||||
if (tagcache_is_numeric_tag(tcs->type))
|
||||
{
|
||||
tcs->valid = true;
|
||||
tcs->initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false);
|
||||
if (tcs->idxfd[tcs->type] < 0)
|
||||
return false;
|
||||
|
||||
tcs->masterfd = open_master_fd(&master_hdr, false);
|
||||
/* Always open as R/W so we can pass tcs to functions that modify data also
|
||||
* without failing. */
|
||||
tcs->masterfd = open_master_fd(&master_hdr, true);
|
||||
|
||||
if (tcs->masterfd < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
tcs->valid = true;
|
||||
tcs->initialized = true;
|
||||
write_lock++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1153,6 +1170,9 @@ void tagcache_search_finish(struct tagcache_search *tcs)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!tcs->initialized)
|
||||
return;
|
||||
|
||||
if (tcs->masterfd >= 0)
|
||||
{
|
||||
close(tcs->masterfd);
|
||||
|
@ -1170,6 +1190,9 @@ void tagcache_search_finish(struct tagcache_search *tcs)
|
|||
|
||||
tcs->ramsearch = false;
|
||||
tcs->valid = false;
|
||||
tcs->initialized = 0;
|
||||
if (write_lock > 0)
|
||||
write_lock--;
|
||||
}
|
||||
|
||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||
|
@ -2076,6 +2099,9 @@ static bool commit(void)
|
|||
|
||||
logf("committing tagcache");
|
||||
|
||||
while (write_lock)
|
||||
sleep(1);
|
||||
|
||||
tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY);
|
||||
if (tmpfd < 0)
|
||||
{
|
||||
|
@ -2103,6 +2129,8 @@ static bool commit(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
read_lock++;
|
||||
|
||||
/* Try to steal every buffer we can :) */
|
||||
if (tempbuf_size == 0)
|
||||
local_allocation = true;
|
||||
|
@ -2138,6 +2166,7 @@ static bool commit(void)
|
|||
logf("delaying commit until next boot");
|
||||
stat.commit_delayed = true;
|
||||
close(tmpfd);
|
||||
read_lock--;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2169,6 +2198,7 @@ static bool commit(void)
|
|||
else
|
||||
stat.commit_delayed = true;
|
||||
stat.commit_step = 0;
|
||||
read_lock--;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2178,8 +2208,11 @@ static bool commit(void)
|
|||
|
||||
/* Update the master index headers. */
|
||||
if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
|
||||
{
|
||||
read_lock--;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
tcmh.tch.entry_count += tch.entry_count;
|
||||
tcmh.tch.datasize = sizeof(struct master_header)
|
||||
+ sizeof(struct index_entry) * tcmh.tch.entry_count
|
||||
|
@ -2212,6 +2245,7 @@ static bool commit(void)
|
|||
#endif
|
||||
|
||||
queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0);
|
||||
read_lock--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2263,6 +2297,9 @@ long tagcache_increase_serial(void)
|
|||
if (!stat.ready)
|
||||
return -2;
|
||||
|
||||
while (read_lock)
|
||||
sleep(1);
|
||||
|
||||
if (!update_current_serial(current_serial + 1))
|
||||
return -1;
|
||||
|
||||
|
@ -2478,6 +2515,9 @@ bool tagcache_import_changelog(void)
|
|||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
while (read_lock)
|
||||
sleep(1);
|
||||
|
||||
clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
||||
if (clfd < 0)
|
||||
{
|
||||
|
@ -2491,6 +2531,8 @@ bool tagcache_import_changelog(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
write_lock++;
|
||||
|
||||
/* Fast readline */
|
||||
while ( 1 )
|
||||
{
|
||||
|
@ -2530,6 +2572,8 @@ bool tagcache_import_changelog(void)
|
|||
close(clfd);
|
||||
close(masterfd);
|
||||
|
||||
write_lock--;
|
||||
|
||||
update_current_serial(current_serial);
|
||||
|
||||
return true;
|
||||
|
@ -2724,12 +2768,11 @@ static bool delete_entry(long idx_id)
|
|||
#ifdef HAVE_TC_RAMCACHE
|
||||
static bool allocate_tagcache(void)
|
||||
{
|
||||
struct master_header tcmh;
|
||||
int fd;
|
||||
|
||||
/* Load the header. */
|
||||
hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04);
|
||||
memset(hdr, 0, sizeof(struct ramcache_header));
|
||||
if ( (fd = open_master_fd(&hdr->h, false)) < 0)
|
||||
if ( (fd = open_master_fd(&tcmh, false)) < 0)
|
||||
{
|
||||
hdr = NULL;
|
||||
return false;
|
||||
|
@ -2737,17 +2780,17 @@ static bool allocate_tagcache(void)
|
|||
|
||||
close(fd);
|
||||
|
||||
hdr->indices = (struct index_entry *)(hdr + 1);
|
||||
|
||||
/**
|
||||
* Now calculate the required cache size plus
|
||||
* some extra space for alignment fixes.
|
||||
*/
|
||||
stat.ramcache_allocated = hdr->h.tch.datasize + 128 + TAGCACHE_RESERVE +
|
||||
stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE +
|
||||
sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *);
|
||||
hdr = buffer_alloc(stat.ramcache_allocated + 128);
|
||||
memset(hdr, 0, sizeof(struct ramcache_header));
|
||||
memcpy(&hdr->h, &tcmh, sizeof(struct master_header));
|
||||
hdr->indices = (struct index_entry *)(hdr + 1);
|
||||
logf("tagcache: %d bytes allocated.", stat.ramcache_allocated);
|
||||
logf("at: 0x%04x", audiobuf);
|
||||
audiobuf += (long)((stat.ramcache_allocated & ~0x03) + 128);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3361,6 +3404,7 @@ void tagcache_init(void)
|
|||
memset(&stat, 0, sizeof(struct tagcache_stat));
|
||||
filenametag_fd = -1;
|
||||
current_serial = 0;
|
||||
write_lock = read_lock = 0;
|
||||
|
||||
queue_init(&tagcache_queue);
|
||||
create_thread(tagcache_thread, tagcache_stack,
|
||||
|
|
|
@ -113,6 +113,7 @@ struct tagcache_search {
|
|||
long position;
|
||||
int entry_count;
|
||||
bool valid;
|
||||
bool initialized;
|
||||
|
||||
/* Exported variables. */
|
||||
bool ramsearch;
|
||||
|
|
|
@ -379,11 +379,17 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track)
|
|||
|
||||
/* Do not gather data unless proper setting has been enabled. */
|
||||
if (!global_settings.runtimedb)
|
||||
{
|
||||
logf("runtimedb gathering not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't process unplayed tracks. */
|
||||
if (id3->elapsed == 0)
|
||||
{
|
||||
logf("not logging unplayed track");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tagcache_find_index(&tcs, id3->path))
|
||||
{
|
||||
|
@ -399,7 +405,11 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track)
|
|||
|
||||
lastplayed = tagcache_increase_serial();
|
||||
if (lastplayed < 0)
|
||||
{
|
||||
logf("incorrect tc serial:%d", lastplayed);
|
||||
tagcache_search_finish(&tcs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ignore the last 15s (crossfade etc.) */
|
||||
playtime += MIN(id3->length, id3->elapsed + 15 * 1000);
|
||||
|
|
|
@ -623,14 +623,10 @@ int dircache_build(int last_size)
|
|||
return 2;
|
||||
}
|
||||
|
||||
dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
|
||||
|
||||
if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT )
|
||||
{
|
||||
allocated_size = last_size + DIRCACHE_RESERVE;
|
||||
|
||||
/* We have to long align the audiobuf to keep the buffer access fast. */
|
||||
audiobuf += (long)((allocated_size & ~0x03) + 0x04);
|
||||
dircache_root = (struct dircache_entry *)buffer_alloc(allocated_size);
|
||||
thread_enabled = true;
|
||||
|
||||
/* Start a transparent rebuild. */
|
||||
|
@ -638,6 +634,8 @@ int dircache_build(int last_size)
|
|||
return 3;
|
||||
}
|
||||
|
||||
dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
|
||||
|
||||
/* Start a non-transparent rebuild. */
|
||||
return dircache_do_rebuild();
|
||||
}
|
||||
|
@ -672,8 +670,7 @@ void dircache_init(void)
|
|||
memset(opendirs, 0, sizeof(opendirs));
|
||||
for (i = 0; i < MAX_OPEN_DIRS; i++)
|
||||
{
|
||||
opendirs[i].secondary_entry.d_name = audiobuf;
|
||||
audiobuf += MAX_PATH;
|
||||
opendirs[i].secondary_entry.d_name = buffer_alloc(MAX_PATH);
|
||||
}
|
||||
|
||||
queue_init(&dircache_queue);
|
||||
|
|
Loading…
Reference in a new issue