summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2010-02-16 22:49:11 +0000
committerAmaury Pouly <pamaury@rockbox.org>2010-02-16 22:49:11 +0000
commit53b1af7a61898ac76a94018fc1863c2a2abf9d3c (patch)
treee76ff6264625ca97ccdd02348a687bda0aa38f55
parentf82c021b8b382613a8bb5e8915c218bc2277a8c1 (diff)
downloadrockbox-53b1af7a61898ac76a94018fc1863c2a2abf9d3c.zip
rockbox-53b1af7a61898ac76a94018fc1863c2a2abf9d3c.tar.gz
rockbox-53b1af7a61898ac76a94018fc1863c2a2abf9d3c.tar.bz2
rockbox-53b1af7a61898ac76a94018fc1863c2a2abf9d3c.tar.xz
-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
-rw-r--r--firmware/common/dircache.c95
-rw-r--r--firmware/include/dir.h2
-rw-r--r--firmware/include/dircache.h17
3 files changed, 61 insertions, 53 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index e610780..0788361 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -73,7 +73,7 @@ static unsigned int cache_build_ticks = 0;
static unsigned long appflags = 0;
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 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;
}
+/* 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)
{
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
- struct fat_dir dir; /* allocate on stack once for all scan */
struct fat_direntry direntry; /* ditto */
#ifdef HAVE_MULTIVOLUME
sab.volume = volume;
#endif
- sab.dir = &dir;
+ sab.dir = &sab_fat_dir;
sab.direntry = &direntry;
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)
#endif /* HAVE_MULTIVOLUME */
{
- logf("dircache_travel failed");
+ logf("dircache_scan_and_build failed");
cpu_boost(false);
dircache_size = 0;
dircache_initializing = false;
@@ -765,7 +767,7 @@ void dircache_init(void)
memset(opendirs, 0, sizeof(opendirs));
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);
@@ -1205,7 +1207,6 @@ void dircache_add_file(const char *path, long startcluster)
DIR_CACHED* opendir_cached(const char* name)
{
- struct dircache_entry *cache_entry;
int dd;
DIR_CACHED* pdir = opendirs;
@@ -1226,23 +1227,22 @@ DIR_CACHED* opendir_cached(const char* name)
errno = EMFILE;
return NULL;
}
+
+ pdir->busy = true;
if (!dircache_initialized)
{
- pdir->regulardir = opendir_uncached(name);
- if (!pdir->regulardir)
- return NULL;
-
- pdir->busy = true;
- return pdir;
+ pdir->internal_entry = NULL;
+ pdir->regulardir = opendir_uncached(name);
+ }
+ else
+ {
+ 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;
return NULL;
@@ -1251,10 +1251,10 @@ DIR_CACHED* opendir_cached(const char* name)
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 dircache_entry *ce;
if (!dir->busy)
return NULL;
@@ -1265,41 +1265,40 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir)
if (regentry == NULL)
return NULL;
- strlcpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH);
- dir->secondary_entry.size = regentry->size;
- dir->secondary_entry.startcluster = regentry->startcluster;
- dir->secondary_entry.attribute = regentry->attribute;
- dir->secondary_entry.wrttime = regentry->wrttime;
- dir->secondary_entry.wrtdate = regentry->wrtdate;
- dir->secondary_entry.next = NULL;
+ strlcpy(dir->theent.d_name, regentry->d_name, MAX_PATH);
+ dir->theent.size = regentry->size;
+ dir->theent.startcluster = regentry->startcluster;
+ dir->theent.attribute = regentry->attribute;
+ dir->theent.wrttime = regentry->wrttime;
+ dir->theent.wrtdate = regentry->wrtdate;
- return &dir->secondary_entry;
+ return &dir->theent;
}
-
- do {
- if (dir->entry == NULL)
+
+ /* if theent.attribute=-1 then this is the first call */
+ /* 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;
- ce = dir->entry;
- if (ce->name_len == 0)
- 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`
+ strlcpy(dir->theent.d_name, ce->d_name, MAX_PATH);
+ /* Can't do `dir->theent = *ce`
because that modifies the d_name pointer. */
- dir->secondary_entry.size = ce->size;
- dir->secondary_entry.startcluster = ce->startcluster;
- dir->secondary_entry.attribute = ce->attribute;
- dir->secondary_entry.wrttime = ce->wrttime;
- dir->secondary_entry.wrtdate = ce->wrtdate;
- dir->secondary_entry.next = NULL;
+ dir->theent.size = ce->size;
+ dir->theent.startcluster = ce->startcluster;
+ dir->theent.attribute = ce->attribute;
+ dir->theent.wrttime = ce->wrttime;
+ dir->theent.wrtdate = ce->wrtdate;
dir->internal_entry = ce;
//logf("-> %s", ce->name);
- return &dir->secondary_entry;
+ return &dir->theent;
}
int closedir_cached(DIR_CACHED* dir)
@@ -1325,7 +1324,7 @@ int mkdir_cached(const char *name)
int rmdir_cached(const char* name)
{
int rc=rmdir_uncached(name);
- if(rc>=0)
+ if(rc >= 0)
dircache_rmdir(name);
return(rc);
}
diff --git a/firmware/include/dir.h b/firmware/include/dir.h
index 5aa6cde..9ff96e3 100644
--- a/firmware/include/dir.h
+++ b/firmware/include/dir.h
@@ -44,7 +44,7 @@
#ifdef HAVE_DIRCACHE
# include "dircache.h"
# define DIR DIR_CACHED
-# define dirent dircache_entry
+# define dirent dirent_cached
# define opendir opendir_cached
# define closedir closedir_cached
# define readdir readdir_cached
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index b5b1b72..0950d00 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -76,11 +76,20 @@ struct dircache_entry {
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 {
bool busy;
- struct dircache_entry *entry;
- struct dircache_entry *internal_entry;
- struct dircache_entry secondary_entry;
+ struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */
+ /* the two following field can't be used at the same time so have an union */
+ struct dircache_entry *internal_entry; /* the current entry in the directory */
DIR_UNCACHED *regulardir;
} DIR_CACHED;
@@ -111,7 +120,7 @@ void dircache_rename(const char *oldpath, const char *newpath);
void dircache_add_file(const char *path, long startcluster);
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 mkdir_cached(const char *name);
int rmdir_cached(const char* name);