1
0
Fork 0
forked from len0rd/rockbox

Commit tagcache in background when possible (at least dircache enabled).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9686 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2006-04-16 17:32:54 +00:00
parent caec58bc0f
commit 3b31346103
8 changed files with 165 additions and 47 deletions

View file

@ -8474,3 +8474,16 @@
*: "" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_TAGCACHE_BUSY
desc: when trying to shutdown and tagcache is committing
<source>
*: "Tagcache is not ready"
</source>
<dest>
*: "Tagcache is not ready"
</dest>
<voice>
*: "Tagcache is not ready"
</voice>
</phrase>

View file

@ -44,6 +44,7 @@
#include "version.h" #include "version.h"
#include "font.h" #include "font.h"
#include "splash.h" #include "splash.h"
#include "tagcache.h"
#ifdef HAVE_MMC #ifdef HAVE_MMC
#include "ata_mmc.h" #include "ata_mmc.h"
#endif #endif
@ -487,6 +488,13 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
(void)parameter; (void)parameter;
exit(0); exit(0);
#else #else
if (tagcache_get_commit_step() > 0)
{
cancel_shutdown();
gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
return false;
}
#if defined(HAVE_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING) #if defined(HAVE_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING)
if(!charger_inserted()) if(!charger_inserted())
#endif #endif

View file

@ -78,6 +78,8 @@ static int init_step;
/* Tag Cache Header version 'TCHxx' */ /* Tag Cache Header version 'TCHxx' */
#define TAGCACHE_MAGIC 0x54434802 #define TAGCACHE_MAGIC 0x54434802
#define TAGCACHE_RESERVE 32768
/* Tag database structures. */ /* Tag database structures. */
/* Variable-length tag entry in tag files. */ /* Variable-length tag entry in tag files. */
@ -575,6 +577,9 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
tagcache_search_finish(tcs); tagcache_search_finish(tcs);
memset(tcs, 0, sizeof(struct tagcache_search)); memset(tcs, 0, sizeof(struct tagcache_search));
if (tagcache_get_commit_step() > 0)
return false;
tcs->position = sizeof(struct tagcache_header); tcs->position = sizeof(struct tagcache_header);
tcs->fd = -1; tcs->fd = -1;
tcs->type = tag; tcs->type = tag;
@ -1453,6 +1458,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd)
* table when the index gets resorted. * table when the index gets resorted.
*/ */
tempbuf_insert(buf, loc + TAGFILE_MAX_ENTRIES, entry.idx_id); tempbuf_insert(buf, loc + TAGFILE_MAX_ENTRIES, entry.idx_id);
yield();
} }
} }
else else
@ -1592,6 +1598,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd)
/* Skip to next. */ /* Skip to next. */
lseek(tmpfd, entry.data_length - entry.tag_offset[index_type] - lseek(tmpfd, entry.data_length - entry.tag_offset[index_type] -
entry.tag_length[index_type], SEEK_CUR); entry.tag_length[index_type], SEEK_CUR);
yield();
} }
/* Sort the buffer data and write it to the index file. */ /* Sort the buffer data and write it to the index file. */
@ -1634,6 +1641,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd)
error = true; error = true;
goto error_exit; goto error_exit;
} }
yield();
} }
} }
@ -1731,6 +1739,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd)
break ; break ;
} }
yield();
} }
/* Finally write the uniqued tag index file. */ /* Finally write the uniqued tag index file. */
@ -1796,6 +1805,25 @@ static bool commit(void)
return true; return true;
} }
/* Try to steal every buffer we can :) */
#ifdef HAVE_TC_RAMCACHE
if (tempbuf_size == 0 && tagcache_size > 0)
{
ramcache = false;
tempbuf = (char *)(hdr + 1);
tempbuf_size = tagcache_size - sizeof(struct ramcache_header);
}
#endif
#ifdef HAVE_DIRCACHE
if (tempbuf_size == 0)
{
/* Try to steal the dircache buffer. */
tempbuf = dircache_steal_buffer(&tempbuf_size);
}
#endif
/* And finally fail if there are no buffers available. */
if (tempbuf_size == 0) if (tempbuf_size == 0)
{ {
logf("delaying commit until next boot"); logf("delaying commit until next boot");
@ -1855,6 +1883,17 @@ static bool commit(void)
logf("tagcache committed"); logf("tagcache committed");
remove(TAGCACHE_FILE_TEMP); remove(TAGCACHE_FILE_TEMP);
#ifdef HAVE_DIRCACHE
/* Rebuild the dircache, if we stole the buffer. */
dircache_build(0);
#endif
#ifdef HAVE_TC_RAMCACHE
/* Reload tagcache. */
if (tagcache_size > 0 && !ramcache)
tagcache_start_scan();
#endif
return true; return true;
} }
@ -1912,7 +1951,7 @@ static bool allocate_tagcache(void)
* Now calculate the required cache size plus * Now calculate the required cache size plus
* some extra space for alignment fixes. * some extra space for alignment fixes.
*/ */
tagcache_size = hdr->h.datasize + 128 + tagcache_size = hdr->h.datasize + 128 + TAGCACHE_RESERVE +
sizeof(struct index_entry) * hdr->h.entry_count + sizeof(struct index_entry) * hdr->h.entry_count +
sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *);
logf("tagcache: %d bytes allocated.", tagcache_size); logf("tagcache: %d bytes allocated.", tagcache_size);
@ -1932,8 +1971,8 @@ static bool load_tagcache(void)
int i; int i;
/* We really need the dircache for this. */ /* We really need the dircache for this. */
while (!dircache_is_enabled()) if (!dircache_is_enabled())
sleep(HZ); return false;
logf("loading tagcache to ram..."); logf("loading tagcache to ram...");
@ -1944,6 +1983,14 @@ static bool load_tagcache(void)
return false; return false;
} }
if (read(fd, &hdr->h, sizeof(struct tagcache_header))
!= sizeof(struct tagcache_header)
|| hdr->h.magic != TAGCACHE_MAGIC)
{
logf("incorrect header");
return false;
}
lseek(fd, sizeof(struct tagcache_header), SEEK_SET); lseek(fd, sizeof(struct tagcache_header), SEEK_SET);
idx = hdr->indices; idx = hdr->indices;
@ -2252,17 +2299,13 @@ static void tagcache_thread(void)
bool check_done = false; bool check_done = false;
/* If the previous cache build/update was interrupted, commit /* If the previous cache build/update was interrupted, commit
* the changes first. */ * the changes first in foreground. */
cpu_boost(true); cpu_boost(true);
allocate_tempbuf(); allocate_tempbuf();
commit(); commit();
free_tempbuf(); free_tempbuf();
cpu_boost(false); cpu_boost(false);
#ifdef HAVE_TC_RAMCACHE
/* Allocate space for the tagcache if found on disk. */
allocate_tagcache();
#endif
tagcache_init_done = true; tagcache_init_done = true;
while (1) while (1)
@ -2288,7 +2331,7 @@ static void tagcache_thread(void)
if (!ramcache && global_settings.tagcache_ram) if (!ramcache && global_settings.tagcache_ram)
load_ramcache(); load_ramcache();
if (global_settings.tagcache_ram) if (ramcache)
build_tagcache(); build_tagcache();
check_done = true; check_done = true;
@ -2303,6 +2346,7 @@ static void tagcache_thread(void)
#ifndef SIMULATOR #ifndef SIMULATOR
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
logf("USB: TagCache");
usb_acknowledge(SYS_USB_CONNECTED_ACK); usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&tagcache_queue); usb_wait_for_disconnect(&tagcache_queue);
break ; break ;
@ -2322,7 +2366,7 @@ int tagcache_get_progress(void)
} }
else else
{ {
if (hdr) if (hdr && ramcache)
total_count = hdr->h.entry_count; total_count = hdr->h.entry_count;
} }
#endif #endif
@ -2362,6 +2406,12 @@ void tagcache_init(void)
{ {
tagcache_init_done = false; tagcache_init_done = false;
init_step = 0; init_step = 0;
#ifdef HAVE_TC_RAMCACHE
/* Allocate space for the tagcache if found on disk. */
allocate_tagcache();
#endif
queue_init(&tagcache_queue); queue_init(&tagcache_queue);
create_thread(tagcache_thread, tagcache_stack, create_thread(tagcache_thread, tagcache_stack,
sizeof(tagcache_stack), tagcache_thread_name); sizeof(tagcache_stack), tagcache_thread_name);

View file

@ -399,7 +399,9 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
0, csi->name); 0, csi->name);
} }
tagcache_search(tcs, csi->tagorder[extra]); if (!tagcache_search(tcs, csi->tagorder[extra]))
return -1;
for (i = 0; i < extra; i++) for (i = 0; i < extra; i++)
{ {
tagcache_search_add_filter(tcs, csi->tagorder[i], csi->result_seek[i]); tagcache_search_add_filter(tcs, csi->tagorder[i], csi->result_seek[i]);
@ -502,10 +504,29 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
return total_count; return total_count;
} }
static int load_root(struct tree_context *c)
{
struct tagentry *dptr = (struct tagentry *)c->dircache;
int i;
c->currtable = root;
for (i = 0; i < si_count; i++)
{
dptr->name = (si+i)->name;
dptr->newtable = navibrowse;
dptr->extraseek = i;
dptr++;
}
current_offset = 0;
current_entry_count = i;
return i;
}
int tagtree_load(struct tree_context* c) int tagtree_load(struct tree_context* c)
{ {
int i; int count;
struct tagentry *dptr = (struct tagentry *)c->dircache;
int table = c->currtable; int table = c->currtable;
c->dentry_size = sizeof(struct tagentry); c->dentry_size = sizeof(struct tagentry);
@ -517,25 +538,15 @@ int tagtree_load(struct tree_context* c)
c->currtable = table; c->currtable = table;
} }
switch (table) { switch (table)
case root: { {
for (i = 0; i < si_count; i++) case root:
{ count = load_root(c);
dptr->name = (si+i)->name; break;
dptr->newtable = navibrowse;
dptr->extraseek = i;
dptr++;
}
c->dirlength = c->filesindir = i;
current_offset = 0;
current_entry_count = i;
return c->dirlength;
}
case navibrowse: case navibrowse:
logf("navibrowse..."); logf("navibrowse...");
i = retrieve_entries(c, &tcs, 0, true); count = retrieve_entries(c, &tcs, 0, true);
break; break;
default: default:
@ -543,11 +554,17 @@ int tagtree_load(struct tree_context* c)
return -1; return -1;
} }
if (count < 0)
{
c->dirlevel = 0;
count = load_root(c);
gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
}
/* The _total_ numer of entries available. */ /* The _total_ numer of entries available. */
c->dirlength = c->filesindir = i; c->dirlength = c->filesindir = count;
return i; return count;
} }
int tagtree_enter(struct tree_context* c) int tagtree_enter(struct tree_context* c)
@ -654,13 +671,15 @@ int tagtree_get_filename(struct tree_context* c, char *buf, int buflen)
entry = tagtree_get_entry(c, c->selected_item); entry = tagtree_get_entry(c, c->selected_item);
tagcache_search(&tcs, tag_filename); if (!tagcache_search(&tcs, tag_filename))
return -1;
tagcache_search_add_filter(&tcs, tag_title, entry->newtable); tagcache_search_add_filter(&tcs, tag_title, entry->newtable);
if (!tagcache_get_next(&tcs)) if (!tagcache_get_next(&tcs))
{ {
tagcache_search_finish(&tcs); tagcache_search_finish(&tcs);
return -1; return -2;
} }
strncpy(buf, tcs.result, buflen-1); strncpy(buf, tcs.result, buflen-1);
@ -681,7 +700,12 @@ static int tagtree_play_folder(struct tree_context* c)
} }
cpu_boost(true); cpu_boost(true);
tagcache_search(&tcs, tag_filename); if (!tagcache_search(&tcs, tag_filename))
{
gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
return -1;
}
for (i=0; i < c->filesindir; i++) for (i=0; i < c->filesindir; i++)
{ {
if (!show_search_progress(false, i)) if (!show_search_progress(false, i))
@ -717,7 +741,11 @@ struct tagentry* tagtree_get_entry(struct tree_context *c, int id)
/* Load the next chunk if necessary. */ /* Load the next chunk if necessary. */
if (realid >= current_entry_count || realid < 0) if (realid >= current_entry_count || realid < 0)
{ {
retrieve_entries(c, &tcs, MAX(0, id - (current_entry_count / 2)), false); if (retrieve_entries(c, &tcs, MAX(0, id - (current_entry_count / 2)),
false) < 0)
{
return NULL;
}
realid = id - current_offset; realid = id - current_offset;
} }

View file

@ -567,6 +567,7 @@ static int dircache_do_rebuild(void)
audiobuf += (long)((dircache_size & ~0x03) + 0x04); audiobuf += (long)((dircache_size & ~0x03) + 0x04);
audiobuf += DIRCACHE_RESERVE; audiobuf += DIRCACHE_RESERVE;
allocated_size = dircache_size + DIRCACHE_RESERVE; allocated_size = dircache_size + DIRCACHE_RESERVE;
reserve_used = 0;
} }
return 1; return 1;
@ -612,27 +613,20 @@ static void dircache_thread(void)
*/ */
int dircache_build(int last_size) int dircache_build(int last_size)
{ {
if (dircache_initialized) if (dircache_initialized || thread_enabled)
return -3; return -3;
while (thread_enabled)
sleep(1);
logf("Building directory cache"); logf("Building directory cache");
if (dircache_size > 0) if (dircache_size > 0)
{ {
allocated_size = dircache_size + (DIRCACHE_RESERVE-reserve_used);
thread_enabled = true; thread_enabled = true;
queue_post(&dircache_queue, DIRCACHE_BUILD, 0); queue_post(&dircache_queue, DIRCACHE_BUILD, 0);
return 2; return 2;
} }
else
{
dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
dircache_size = 0;
}
if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT) dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT )
{ {
allocated_size = last_size + DIRCACHE_RESERVE; allocated_size = last_size + DIRCACHE_RESERVE;
@ -649,6 +643,23 @@ int dircache_build(int last_size)
return dircache_do_rebuild(); return dircache_do_rebuild();
} }
/**
* Steal the allocated dircache buffer and disable dircache.
*/
void* dircache_steal_buffer(long *size)
{
dircache_disable();
if (dircache_size == 0)
{
*size = 0;
return NULL;
}
*size = dircache_size + (DIRCACHE_RESERVE-reserve_used);
return dircache_root;
}
/** /**
* Main initialization function that must be called before any other * Main initialization function that must be called before any other
* operations within the dircache. * operations within the dircache.

View file

@ -139,6 +139,7 @@ void set_sleep_timer(int seconds);
int get_sleep_timer(void); int get_sleep_timer(void);
void set_car_adapter_mode(bool setting); void set_car_adapter_mode(bool setting);
void reset_poweroff_timer(void); void reset_poweroff_timer(void);
void cancel_shutdown(void);
void shutdown_hw(void); void shutdown_hw(void);
void sys_poweroff(void); void sys_poweroff(void);

View file

@ -83,6 +83,7 @@ void dircache_init(void);
int dircache_load(const char *path); int dircache_load(const char *path);
int dircache_save(const char *path); int dircache_save(const char *path);
int dircache_build(int last_size); int dircache_build(int last_size);
void* dircache_steal_buffer(long *size);
bool dircache_is_enabled(void); bool dircache_is_enabled(void);
int dircache_get_entry_count(void); int dircache_get_entry_count(void);
int dircache_get_cache_size(void); int dircache_get_cache_size(void);

View file

@ -1019,6 +1019,12 @@ void sys_poweroff(void)
queue_post(&button_queue, SYS_POWEROFF, NULL); queue_post(&button_queue, SYS_POWEROFF, NULL);
} }
void cancel_shutdown(void)
{
logf("sys_cancel_shutdown()");
shutdown_timeout = 0;
}
/* Various hardware housekeeping tasks relating to shutting down the jukebox */ /* Various hardware housekeeping tasks relating to shutting down the jukebox */
void shutdown_hw(void) void shutdown_hw(void)
{ {