-Cosmetic change in a comparison
-Move fat_dir structure out of dircache stack to RAM. Reduce dircache stack size (max level depth should stay be around 20). This should fix nano2g dircache stkov of FS#10679 -Change the structure returned by readdir_cached to match the one returned by readdir_uncached: remove useless fields to save space and avoid any potential incoherence -Remove one field from the internal structure used by {opend,read,close}dir_cached because it was mostly redundant. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24708 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f82c021b8b
commit
53b1af7a61
3 changed files with 61 additions and 53 deletions
|
@ -73,7 +73,7 @@ static unsigned int cache_build_ticks = 0;
|
||||||
static unsigned long appflags = 0;
|
static unsigned long appflags = 0;
|
||||||
|
|
||||||
static struct event_queue dircache_queue;
|
static struct event_queue dircache_queue;
|
||||||
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)];
|
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x200)/sizeof(long)];
|
||||||
static const char dircache_thread_name[] = "dircache";
|
static const char dircache_thread_name[] = "dircache";
|
||||||
|
|
||||||
static struct fdbind_queue fdbind_cache[MAX_PENDING_BINDINGS];
|
static struct fdbind_queue fdbind_cache[MAX_PENDING_BINDINGS];
|
||||||
|
@ -270,6 +270,9 @@ static int sab_process_dir(unsigned long startcluster, struct dircache_entry *ce
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* used during the generation */
|
||||||
|
static struct fat_dir sab_fat_dir;
|
||||||
|
|
||||||
static int dircache_scan_and_build(IF_MV2(int volume,) struct dircache_entry *ce)
|
static int dircache_scan_and_build(IF_MV2(int volume,) struct dircache_entry *ce)
|
||||||
{
|
{
|
||||||
memset(ce, 0, sizeof(struct dircache_entry));
|
memset(ce, 0, sizeof(struct dircache_entry));
|
||||||
|
@ -288,12 +291,11 @@ static int dircache_scan_and_build(IF_MV2(int volume,) struct dircache_entry *ce
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct fat_dir dir; /* allocate on stack once for all scan */
|
|
||||||
struct fat_direntry direntry; /* ditto */
|
struct fat_direntry direntry; /* ditto */
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_MULTIVOLUME
|
||||||
sab.volume = volume;
|
sab.volume = volume;
|
||||||
#endif
|
#endif
|
||||||
sab.dir = &dir;
|
sab.dir = &sab_fat_dir;
|
||||||
sab.direntry = &direntry;
|
sab.direntry = &direntry;
|
||||||
|
|
||||||
return sab_process_dir(0, ce);
|
return sab_process_dir(0, ce);
|
||||||
|
@ -615,7 +617,7 @@ static int dircache_do_rebuild(void)
|
||||||
if (dircache_scan_and_build(IF_MV2(0,) dircache_root) < 0)
|
if (dircache_scan_and_build(IF_MV2(0,) dircache_root) < 0)
|
||||||
#endif /* HAVE_MULTIVOLUME */
|
#endif /* HAVE_MULTIVOLUME */
|
||||||
{
|
{
|
||||||
logf("dircache_travel failed");
|
logf("dircache_scan_and_build failed");
|
||||||
cpu_boost(false);
|
cpu_boost(false);
|
||||||
dircache_size = 0;
|
dircache_size = 0;
|
||||||
dircache_initializing = false;
|
dircache_initializing = false;
|
||||||
|
@ -765,7 +767,7 @@ void dircache_init(void)
|
||||||
memset(opendirs, 0, sizeof(opendirs));
|
memset(opendirs, 0, sizeof(opendirs));
|
||||||
for (i = 0; i < MAX_OPEN_DIRS; i++)
|
for (i = 0; i < MAX_OPEN_DIRS; i++)
|
||||||
{
|
{
|
||||||
opendirs[i].secondary_entry.d_name = buffer_alloc(MAX_PATH);
|
opendirs[i].theent.d_name = buffer_alloc(MAX_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_init(&dircache_queue, true);
|
queue_init(&dircache_queue, true);
|
||||||
|
@ -1205,7 +1207,6 @@ void dircache_add_file(const char *path, long startcluster)
|
||||||
|
|
||||||
DIR_CACHED* opendir_cached(const char* name)
|
DIR_CACHED* opendir_cached(const char* name)
|
||||||
{
|
{
|
||||||
struct dircache_entry *cache_entry;
|
|
||||||
int dd;
|
int dd;
|
||||||
DIR_CACHED* pdir = opendirs;
|
DIR_CACHED* pdir = opendirs;
|
||||||
|
|
||||||
|
@ -1226,23 +1227,22 @@ DIR_CACHED* opendir_cached(const char* name)
|
||||||
errno = EMFILE;
|
errno = EMFILE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdir->busy = true;
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (!dircache_initialized)
|
||||||
{
|
{
|
||||||
pdir->regulardir = opendir_uncached(name);
|
pdir->internal_entry = NULL;
|
||||||
if (!pdir->regulardir)
|
pdir->regulardir = opendir_uncached(name);
|
||||||
return NULL;
|
}
|
||||||
|
else
|
||||||
pdir->busy = true;
|
{
|
||||||
return pdir;
|
pdir->regulardir = NULL;
|
||||||
|
pdir->internal_entry = dircache_get_entry(name, true);
|
||||||
|
pdir->theent.attribute = -1; /* used to make readdir_cached aware of the first call */
|
||||||
}
|
}
|
||||||
|
|
||||||
pdir->busy = true;
|
|
||||||
pdir->regulardir = NULL;
|
|
||||||
cache_entry = dircache_get_entry(name, true);
|
|
||||||
pdir->entry = cache_entry;
|
|
||||||
|
|
||||||
if (cache_entry == NULL)
|
if (pdir->internal_entry == NULL && pdir->regulardir == NULL)
|
||||||
{
|
{
|
||||||
pdir->busy = false;
|
pdir->busy = false;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1251,10 +1251,10 @@ DIR_CACHED* opendir_cached(const char* name)
|
||||||
return pdir;
|
return pdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dircache_entry* readdir_cached(DIR_CACHED* dir)
|
struct dirent_cached* readdir_cached(DIR_CACHED* dir)
|
||||||
{
|
{
|
||||||
|
struct dircache_entry *ce = dir->internal_entry;
|
||||||
struct dirent_uncached *regentry;
|
struct dirent_uncached *regentry;
|
||||||
struct dircache_entry *ce;
|
|
||||||
|
|
||||||
if (!dir->busy)
|
if (!dir->busy)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1265,41 +1265,40 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir)
|
||||||
if (regentry == NULL)
|
if (regentry == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
strlcpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH);
|
strlcpy(dir->theent.d_name, regentry->d_name, MAX_PATH);
|
||||||
dir->secondary_entry.size = regentry->size;
|
dir->theent.size = regentry->size;
|
||||||
dir->secondary_entry.startcluster = regentry->startcluster;
|
dir->theent.startcluster = regentry->startcluster;
|
||||||
dir->secondary_entry.attribute = regentry->attribute;
|
dir->theent.attribute = regentry->attribute;
|
||||||
dir->secondary_entry.wrttime = regentry->wrttime;
|
dir->theent.wrttime = regentry->wrttime;
|
||||||
dir->secondary_entry.wrtdate = regentry->wrtdate;
|
dir->theent.wrtdate = regentry->wrtdate;
|
||||||
dir->secondary_entry.next = NULL;
|
|
||||||
|
|
||||||
return &dir->secondary_entry;
|
return &dir->theent;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
/* if theent.attribute=-1 then this is the first call */
|
||||||
if (dir->entry == NULL)
|
/* otherwise, this is is not so we first take the entry's ->next */
|
||||||
|
/* NOTE: normal file can't have attribute=-1 */
|
||||||
|
if(dir->theent.attribute != -1)
|
||||||
|
ce = ce->next;
|
||||||
|
/* skip unused entries */
|
||||||
|
while(ce != NULL && ce->name_len == 0)
|
||||||
|
ce = ce->next;
|
||||||
|
|
||||||
|
if (ce == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ce = dir->entry;
|
strlcpy(dir->theent.d_name, ce->d_name, MAX_PATH);
|
||||||
if (ce->name_len == 0)
|
/* Can't do `dir->theent = *ce`
|
||||||
dir->entry = ce->next;
|
|
||||||
} while (ce->name_len == 0) ;
|
|
||||||
|
|
||||||
dir->entry = ce->next;
|
|
||||||
|
|
||||||
strlcpy(dir->secondary_entry.d_name, ce->d_name, MAX_PATH);
|
|
||||||
/* Can't do `dir->secondary_entry = *ce`
|
|
||||||
because that modifies the d_name pointer. */
|
because that modifies the d_name pointer. */
|
||||||
dir->secondary_entry.size = ce->size;
|
dir->theent.size = ce->size;
|
||||||
dir->secondary_entry.startcluster = ce->startcluster;
|
dir->theent.startcluster = ce->startcluster;
|
||||||
dir->secondary_entry.attribute = ce->attribute;
|
dir->theent.attribute = ce->attribute;
|
||||||
dir->secondary_entry.wrttime = ce->wrttime;
|
dir->theent.wrttime = ce->wrttime;
|
||||||
dir->secondary_entry.wrtdate = ce->wrtdate;
|
dir->theent.wrtdate = ce->wrtdate;
|
||||||
dir->secondary_entry.next = NULL;
|
|
||||||
dir->internal_entry = ce;
|
dir->internal_entry = ce;
|
||||||
|
|
||||||
//logf("-> %s", ce->name);
|
//logf("-> %s", ce->name);
|
||||||
return &dir->secondary_entry;
|
return &dir->theent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int closedir_cached(DIR_CACHED* dir)
|
int closedir_cached(DIR_CACHED* dir)
|
||||||
|
@ -1325,7 +1324,7 @@ int mkdir_cached(const char *name)
|
||||||
int rmdir_cached(const char* name)
|
int rmdir_cached(const char* name)
|
||||||
{
|
{
|
||||||
int rc=rmdir_uncached(name);
|
int rc=rmdir_uncached(name);
|
||||||
if(rc>=0)
|
if(rc >= 0)
|
||||||
dircache_rmdir(name);
|
dircache_rmdir(name);
|
||||||
return(rc);
|
return(rc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#ifdef HAVE_DIRCACHE
|
#ifdef HAVE_DIRCACHE
|
||||||
# include "dircache.h"
|
# include "dircache.h"
|
||||||
# define DIR DIR_CACHED
|
# define DIR DIR_CACHED
|
||||||
# define dirent dircache_entry
|
# define dirent dirent_cached
|
||||||
# define opendir opendir_cached
|
# define opendir opendir_cached
|
||||||
# define closedir closedir_cached
|
# define closedir closedir_cached
|
||||||
# define readdir readdir_cached
|
# define readdir readdir_cached
|
||||||
|
|
|
@ -76,11 +76,20 @@ struct dircache_entry {
|
||||||
char *d_name;
|
char *d_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dirent_cached {
|
||||||
|
char *d_name;
|
||||||
|
int attribute;
|
||||||
|
long size;
|
||||||
|
long startcluster;
|
||||||
|
unsigned short wrtdate; /* Last write date */
|
||||||
|
unsigned short wrttime; /* Last write time */
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool busy;
|
bool busy;
|
||||||
struct dircache_entry *entry;
|
struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */
|
||||||
struct dircache_entry *internal_entry;
|
/* the two following field can't be used at the same time so have an union */
|
||||||
struct dircache_entry secondary_entry;
|
struct dircache_entry *internal_entry; /* the current entry in the directory */
|
||||||
DIR_UNCACHED *regulardir;
|
DIR_UNCACHED *regulardir;
|
||||||
} DIR_CACHED;
|
} DIR_CACHED;
|
||||||
|
|
||||||
|
@ -111,7 +120,7 @@ void dircache_rename(const char *oldpath, const char *newpath);
|
||||||
void dircache_add_file(const char *path, long startcluster);
|
void dircache_add_file(const char *path, long startcluster);
|
||||||
|
|
||||||
DIR_CACHED* opendir_cached(const char* name);
|
DIR_CACHED* opendir_cached(const char* name);
|
||||||
struct dircache_entry* readdir_cached(DIR_CACHED* dir);
|
struct dirent_cached* readdir_cached(DIR_CACHED* dir);
|
||||||
int closedir_cached(DIR_CACHED *dir);
|
int closedir_cached(DIR_CACHED *dir);
|
||||||
int mkdir_cached(const char *name);
|
int mkdir_cached(const char *name);
|
||||||
int rmdir_cached(const char* name);
|
int rmdir_cached(const char* name);
|
||||||
|
|
Loading…
Reference in a new issue