Dircache: Allow dircache to be enabled without reboot.
Also add two dircache function, one of which does what dircache_disable() did previously as this now also frees the dircache buffer. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30393 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
c1ae789108
commit
7e14b935df
5 changed files with 77 additions and 41 deletions
|
@ -189,16 +189,14 @@ static int dircache_callback(int action,const struct menu_item_ex *this_item)
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case ACTION_EXIT_MENUITEM: /* on exit */
|
case ACTION_EXIT_MENUITEM: /* on exit */
|
||||||
switch (global_settings.dircache)
|
if (global_settings.dircache && !dircache_is_enabled())
|
||||||
{
|
{
|
||||||
case true:
|
if (dircache_build(0) < 0)
|
||||||
if (!dircache_is_enabled())
|
splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
|
||||||
splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
|
}
|
||||||
break;
|
else if (!global_settings.dircache && dircache_is_enabled())
|
||||||
case false:
|
{
|
||||||
if (dircache_is_enabled())
|
dircache_disable();
|
||||||
dircache_disable();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3099,7 +3099,7 @@ static bool commit(void)
|
||||||
#ifdef HAVE_DIRCACHE
|
#ifdef HAVE_DIRCACHE
|
||||||
/* Rebuild the dircache, if we stole the buffer. */
|
/* Rebuild the dircache, if we stole the buffer. */
|
||||||
if (dircache_buffer_stolen)
|
if (dircache_buffer_stolen)
|
||||||
dircache_build(0);
|
dircache_resume();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
|
|
|
@ -1216,7 +1216,7 @@ void tree_flush(void)
|
||||||
if (firmware_settings.initialized)
|
if (firmware_settings.initialized)
|
||||||
dircache_save();
|
dircache_save();
|
||||||
# endif
|
# endif
|
||||||
dircache_disable();
|
dircache_suspend();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "core_alloc.h"
|
#include "core_alloc.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
#include "audio.h"
|
||||||
#if CONFIG_RTC
|
#if CONFIG_RTC
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "timefuncs.h"
|
#include "timefuncs.h"
|
||||||
|
@ -845,7 +846,7 @@ static void dircache_thread(void)
|
||||||
case DIRCACHE_BUILD:
|
case DIRCACHE_BUILD:
|
||||||
thread_enabled = true;
|
thread_enabled = true;
|
||||||
if (dircache_do_rebuild() < 0)
|
if (dircache_do_rebuild() < 0)
|
||||||
core_free(dircache_handle);
|
dircache_handle = core_free(dircache_handle);
|
||||||
thread_enabled = false;
|
thread_enabled = false;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
@ -887,8 +888,8 @@ int dircache_build(int last_size)
|
||||||
remove_dircache_file();
|
remove_dircache_file();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Background build, dircache has been previously allocated */
|
/* Background build, dircache has been previously allocated and */
|
||||||
if (allocated_size > 0)
|
if (allocated_size > MAX(last_size, 0))
|
||||||
{
|
{
|
||||||
d_names_start = d_names_end;
|
d_names_start = d_names_end;
|
||||||
dircache_size = 0;
|
dircache_size = 0;
|
||||||
|
@ -901,6 +902,9 @@ int dircache_build(int last_size)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dircache_handle > 0)
|
||||||
|
dircache_handle = core_free(dircache_handle);
|
||||||
|
|
||||||
if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT )
|
if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT )
|
||||||
{
|
{
|
||||||
allocated_size = last_size + DIRCACHE_RESERVE;
|
allocated_size = last_size + DIRCACHE_RESERVE;
|
||||||
|
@ -922,12 +926,18 @@ int dircache_build(int last_size)
|
||||||
* and their corresponding d_name from the end
|
* and their corresponding d_name from the end
|
||||||
* after generation the buffer will be compacted with DIRCACHE_RESERVE
|
* after generation the buffer will be compacted with DIRCACHE_RESERVE
|
||||||
* free bytes inbetween */
|
* free bytes inbetween */
|
||||||
size_t got_size;
|
size_t available = audio_buffer_available();
|
||||||
dircache_handle = core_alloc_maximum("dircache", &got_size, &ops);
|
/* try to allocate at least 1MB, the more the better */
|
||||||
|
if (available < 1<<20) available = 1<<20;
|
||||||
|
if (available > DIRCACHE_LIMIT) available = DIRCACHE_LIMIT;
|
||||||
|
|
||||||
|
dircache_handle = core_alloc_ex("dircache", available, &ops);
|
||||||
|
if (dircache_handle <= 0)
|
||||||
|
return -1; /* that was not successful, should try rebooting */
|
||||||
char* buf = core_get_data(dircache_handle);
|
char* buf = core_get_data(dircache_handle);
|
||||||
dircache_root = (struct dircache_entry*)ALIGN_UP(buf,
|
dircache_root = (struct dircache_entry*)ALIGN_UP(buf,
|
||||||
sizeof(struct dircache_entry*));
|
sizeof(struct dircache_entry*));
|
||||||
d_names_start = d_names_end = buf + got_size - 1;
|
d_names_start = d_names_end = buf + available - 1;
|
||||||
dircache_size = 0;
|
dircache_size = 0;
|
||||||
generate_dot_d_names();
|
generate_dot_d_names();
|
||||||
|
|
||||||
|
@ -967,29 +977,9 @@ int dircache_build(int last_size)
|
||||||
return res;
|
return res;
|
||||||
fail:
|
fail:
|
||||||
dircache_disable();
|
dircache_disable();
|
||||||
core_free(dircache_handle);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Steal the allocated dircache buffer and disable dircache.
|
|
||||||
*/
|
|
||||||
void* dircache_steal_buffer(size_t *size)
|
|
||||||
{
|
|
||||||
dircache_disable();
|
|
||||||
if (dircache_size == 0)
|
|
||||||
{
|
|
||||||
*size = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* since we give up the buffer (without freeing), it must not move anymore */
|
|
||||||
dont_move = true;
|
|
||||||
*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.
|
||||||
|
@ -1085,10 +1075,10 @@ int dircache_get_build_ticks(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables the dircache. Usually called on shutdown or when
|
* Disables dircache without freeing the buffer (so it can be re-enabled
|
||||||
* accepting a usb connection.
|
* afterwards with dircache_resume() or dircache_build()), usually
|
||||||
*/
|
* called when accepting an usb connection */
|
||||||
void dircache_disable(void)
|
void dircache_suspend(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool cache_in_use;
|
bool cache_in_use;
|
||||||
|
@ -1117,6 +1107,52 @@ void dircache_disable(void)
|
||||||
entry_count = 0;
|
entry_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-enables the dircache if previous suspended by dircache_suspend
|
||||||
|
* or dircache_steal_buffer(), re-using the already allocated buffer
|
||||||
|
*
|
||||||
|
* Returns true if the background build is started, false otherwise
|
||||||
|
* (e.g. if no buffer was previously allocated)
|
||||||
|
*/
|
||||||
|
bool dircache_resume(void)
|
||||||
|
{
|
||||||
|
bool ret = allocated_size > 0;
|
||||||
|
if (ret) /* only resume if already allocated */
|
||||||
|
ret = (dircache_build(0) > 0);
|
||||||
|
|
||||||
|
return (allocated_size > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the dircache entirely. Usually called on shutdown or when
|
||||||
|
* deactivated
|
||||||
|
*/
|
||||||
|
void dircache_disable(void)
|
||||||
|
{
|
||||||
|
dircache_suspend();
|
||||||
|
dircache_handle = core_free(dircache_handle);
|
||||||
|
dircache_size = allocated_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steal the allocated dircache buffer and disable dircache.
|
||||||
|
*/
|
||||||
|
void* dircache_steal_buffer(size_t *size)
|
||||||
|
{
|
||||||
|
dircache_suspend();
|
||||||
|
if (dircache_size == 0)
|
||||||
|
{
|
||||||
|
*size = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* since we give up the buffer (without freeing), it must not move anymore */
|
||||||
|
dont_move = true;
|
||||||
|
*size = dircache_size + (DIRCACHE_RESERVE-reserve_used);
|
||||||
|
|
||||||
|
return dircache_root;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usermode function to return dircache_entry index to the given path.
|
* Usermode function to return dircache_entry index to the given path.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -76,6 +76,8 @@ int dircache_get_cache_size(void);
|
||||||
int dircache_get_reserve_used(void);
|
int dircache_get_reserve_used(void);
|
||||||
int dircache_get_build_ticks(void);
|
int dircache_get_build_ticks(void);
|
||||||
void dircache_disable(void);
|
void dircache_disable(void);
|
||||||
|
void dircache_suspend(void);
|
||||||
|
bool dircache_resume(void);
|
||||||
int dircache_get_entry_id(const char *filename);
|
int dircache_get_entry_id(const char *filename);
|
||||||
size_t dircache_copy_path(int index, char *buf, size_t size);
|
size_t dircache_copy_path(int index, char *buf, size_t size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue