summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-08-30 14:01:33 +0000
committerThomas Martitz <kugel@rockbox.org>2011-08-30 14:01:33 +0000
commitd0b72e25903574acb1cf9184a6052cdd646dbc37 (patch)
tree5be8db5ee00b2a727e4821cf51a5f7bcf3991073 /firmware/common/dircache.c
parentc940811ade7d99a0e0d414df7c6509672413684a (diff)
downloadrockbox-d0b72e25903574acb1cf9184a6052cdd646dbc37.tar.gz
rockbox-d0b72e25903574acb1cf9184a6052cdd646dbc37.zip
GSoC/Buflib: Add buflib memory alocator to the core.
The buflib memory allocator is handle based and can free and compact, move or resize memory on demand. This allows to effeciently allocate memory dynamically without an MMU, by avoiding fragmentation through memory compaction. This patch adds the buflib library to the core, along with convinience wrappers to omit the context parameter. Compaction is not yet enabled, but will be in a later patch. Therefore, this acts as a replacement for buffer_alloc/buffer_get_buffer() with the benifit of a debug menu. See buflib.h for some API documentation. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30380 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index f47e65e428..334801ce57 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -38,7 +38,7 @@
38#include "kernel.h" 38#include "kernel.h"
39#include "usb.h" 39#include "usb.h"
40#include "file.h" 40#include "file.h"
41#include "buffer.h" 41#include "core_alloc.h"
42#include "dir.h" 42#include "dir.h"
43#include "storage.h" 43#include "storage.h"
44#if CONFIG_RTC 44#if CONFIG_RTC
@@ -57,6 +57,8 @@
57#else 57#else
58#define MAX_OPEN_DIRS 8 58#define MAX_OPEN_DIRS 8
59#endif 59#endif
60static DIR_CACHED opendirs[MAX_OPEN_DIRS];
61static char opendir_dnames[MAX_OPEN_DIRS][MAX_PATH];
60 62
61#define MAX_PENDING_BINDINGS 2 63#define MAX_PENDING_BINDINGS 2
62struct fdbind_queue { 64struct fdbind_queue {
@@ -571,7 +573,8 @@ int dircache_load(void)
571 } 573 }
572 574
573 allocated_size = maindata.size + DIRCACHE_RESERVE; 575 allocated_size = maindata.size + DIRCACHE_RESERVE;
574 dircache_root = buffer_alloc(allocated_size); 576 int handle = core_alloc("dircache", allocated_size);
577 dircache_root = core_get_data(handle);
575 /* needs to be struct-size aligned so that the pointer arithmetic below works */ 578 /* needs to be struct-size aligned so that the pointer arithmetic below works */
576 ALIGN_BUFFER(dircache_root, allocated_size, sizeof(struct dircache_entry)); 579 ALIGN_BUFFER(dircache_root, allocated_size, sizeof(struct dircache_entry));
577 entry_count = maindata.entry_count; 580 entry_count = maindata.entry_count;
@@ -814,6 +817,7 @@ static void generate_dot_d_names(void)
814 strcpy(dot, "."); 817 strcpy(dot, ".");
815 strcpy(dotdot, ".."); 818 strcpy(dotdot, "..");
816} 819}
820
817/** 821/**
818 * Start scanning the disk to build the dircache. 822 * Start scanning the disk to build the dircache.
819 * Either transparent or non-transparent build method is used. 823 * Either transparent or non-transparent build method is used.
@@ -841,11 +845,13 @@ int dircache_build(int last_size)
841 queue_post(&dircache_queue, DIRCACHE_BUILD, 0); 845 queue_post(&dircache_queue, DIRCACHE_BUILD, 0);
842 return 2; 846 return 2;
843 } 847 }
844 848
845 if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT ) 849 if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT )
846 { 850 {
851 int handle;
847 allocated_size = last_size + DIRCACHE_RESERVE; 852 allocated_size = last_size + DIRCACHE_RESERVE;
848 dircache_root = buffer_alloc(allocated_size); 853 handle = core_alloc("dircache", allocated_size);
854 dircache_root = core_get_data(handle);
849 ALIGN_BUFFER(dircache_root, allocated_size, sizeof(struct dircache_entry)); 855 ALIGN_BUFFER(dircache_root, allocated_size, sizeof(struct dircache_entry));
850 d_names_start = d_names_end = ((char*)dircache_root)+allocated_size-1; 856 d_names_start = d_names_end = ((char*)dircache_root)+allocated_size-1;
851 dircache_size = 0; 857 dircache_size = 0;
@@ -863,7 +869,8 @@ int dircache_build(int last_size)
863 * after generation the buffer will be compacted with DIRCACHE_RESERVE 869 * after generation the buffer will be compacted with DIRCACHE_RESERVE
864 * free bytes inbetween */ 870 * free bytes inbetween */
865 size_t got_size; 871 size_t got_size;
866 char* buf = buffer_get_buffer(&got_size); 872 int handle = core_alloc_maximum("dircache", &got_size, NULL);
873 char* buf = core_get_data(handle);
867 dircache_root = (struct dircache_entry*)ALIGN_UP(buf, 874 dircache_root = (struct dircache_entry*)ALIGN_UP(buf,
868 sizeof(struct dircache_entry)); 875 sizeof(struct dircache_entry));
869 d_names_start = d_names_end = buf + got_size - 1; 876 d_names_start = d_names_end = buf + got_size - 1;
@@ -902,11 +909,11 @@ int dircache_build(int last_size)
902 allocated_size = (d_names_end - buf); 909 allocated_size = (d_names_end - buf);
903 reserve_used = 0; 910 reserve_used = 0;
904 911
905 buffer_release_buffer(allocated_size); 912 core_shrink(handle, dircache_root, allocated_size);
906 return res; 913 return res;
907fail: 914fail:
908 dircache_disable(); 915 dircache_disable();
909 buffer_release_buffer(0); 916 core_free(handle);
910 return res; 917 return res;
911} 918}
912 919
@@ -942,7 +949,7 @@ void dircache_init(void)
942 memset(opendirs, 0, sizeof(opendirs)); 949 memset(opendirs, 0, sizeof(opendirs));
943 for (i = 0; i < MAX_OPEN_DIRS; i++) 950 for (i = 0; i < MAX_OPEN_DIRS; i++)
944 { 951 {
945 opendirs[i].theent.d_name = buffer_alloc(MAX_PATH); 952 opendirs[i].theent.d_name = opendir_dnames[i];
946 } 953 }
947 954
948 queue_init(&dircache_queue, true); 955 queue_init(&dircache_queue, true);