diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-08-30 21:07:46 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-08-30 21:07:46 +0000 |
commit | 7e14b935dfdcd808cfb0703d19a43efd11eeef16 (patch) | |
tree | 57834f71db1bbaaabf7872d8609f8254371377cf /firmware | |
parent | c1ae789108942f3270fb90bd5a088adfee126333 (diff) | |
download | rockbox-7e14b935dfdcd808cfb0703d19a43efd11eeef16.tar.gz rockbox-7e14b935dfdcd808cfb0703d19a43efd11eeef16.zip |
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
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/dircache.c | 96 | ||||
-rw-r--r-- | firmware/include/dircache.h | 2 |
2 files changed, 68 insertions, 30 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 6b2260def3..c544abc567 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "core_alloc.h" | 41 | #include "core_alloc.h" |
42 | #include "dir.h" | 42 | #include "dir.h" |
43 | #include "storage.h" | 43 | #include "storage.h" |
44 | #include "audio.h" | ||
44 | #if CONFIG_RTC | 45 | #if CONFIG_RTC |
45 | #include "time.h" | 46 | #include "time.h" |
46 | #include "timefuncs.h" | 47 | #include "timefuncs.h" |
@@ -845,7 +846,7 @@ static void dircache_thread(void) | |||
845 | case DIRCACHE_BUILD: | 846 | case DIRCACHE_BUILD: |
846 | thread_enabled = true; | 847 | thread_enabled = true; |
847 | if (dircache_do_rebuild() < 0) | 848 | if (dircache_do_rebuild() < 0) |
848 | core_free(dircache_handle); | 849 | dircache_handle = core_free(dircache_handle); |
849 | thread_enabled = false; | 850 | thread_enabled = false; |
850 | break ; | 851 | break ; |
851 | 852 | ||
@@ -887,8 +888,8 @@ int dircache_build(int last_size) | |||
887 | remove_dircache_file(); | 888 | remove_dircache_file(); |
888 | #endif | 889 | #endif |
889 | 890 | ||
890 | /* Background build, dircache has been previously allocated */ | 891 | /* Background build, dircache has been previously allocated and */ |
891 | if (allocated_size > 0) | 892 | if (allocated_size > MAX(last_size, 0)) |
892 | { | 893 | { |
893 | d_names_start = d_names_end; | 894 | d_names_start = d_names_end; |
894 | dircache_size = 0; | 895 | dircache_size = 0; |
@@ -901,6 +902,9 @@ int dircache_build(int last_size) | |||
901 | return 2; | 902 | return 2; |
902 | } | 903 | } |
903 | 904 | ||
905 | if (dircache_handle > 0) | ||
906 | dircache_handle = core_free(dircache_handle); | ||
907 | |||
904 | if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT ) | 908 | if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT ) |
905 | { | 909 | { |
906 | allocated_size = last_size + DIRCACHE_RESERVE; | 910 | allocated_size = last_size + DIRCACHE_RESERVE; |
@@ -922,12 +926,18 @@ int dircache_build(int last_size) | |||
922 | * and their corresponding d_name from the end | 926 | * and their corresponding d_name from the end |
923 | * after generation the buffer will be compacted with DIRCACHE_RESERVE | 927 | * after generation the buffer will be compacted with DIRCACHE_RESERVE |
924 | * free bytes inbetween */ | 928 | * free bytes inbetween */ |
925 | size_t got_size; | 929 | size_t available = audio_buffer_available(); |
926 | dircache_handle = core_alloc_maximum("dircache", &got_size, &ops); | 930 | /* try to allocate at least 1MB, the more the better */ |
931 | if (available < 1<<20) available = 1<<20; | ||
932 | if (available > DIRCACHE_LIMIT) available = DIRCACHE_LIMIT; | ||
933 | |||
934 | dircache_handle = core_alloc_ex("dircache", available, &ops); | ||
935 | if (dircache_handle <= 0) | ||
936 | return -1; /* that was not successful, should try rebooting */ | ||
927 | char* buf = core_get_data(dircache_handle); | 937 | char* buf = core_get_data(dircache_handle); |
928 | dircache_root = (struct dircache_entry*)ALIGN_UP(buf, | 938 | dircache_root = (struct dircache_entry*)ALIGN_UP(buf, |
929 | sizeof(struct dircache_entry*)); | 939 | sizeof(struct dircache_entry*)); |
930 | d_names_start = d_names_end = buf + got_size - 1; | 940 | d_names_start = d_names_end = buf + available - 1; |
931 | dircache_size = 0; | 941 | dircache_size = 0; |
932 | generate_dot_d_names(); | 942 | generate_dot_d_names(); |
933 | 943 | ||
@@ -967,30 +977,10 @@ int dircache_build(int last_size) | |||
967 | return res; | 977 | return res; |
968 | fail: | 978 | fail: |
969 | dircache_disable(); | 979 | dircache_disable(); |
970 | core_free(dircache_handle); | ||
971 | return res; | 980 | return res; |
972 | } | 981 | } |
973 | 982 | ||
974 | /** | 983 | /** |
975 | * Steal the allocated dircache buffer and disable dircache. | ||
976 | */ | ||
977 | void* dircache_steal_buffer(size_t *size) | ||
978 | { | ||
979 | dircache_disable(); | ||
980 | if (dircache_size == 0) | ||
981 | { | ||
982 | *size = 0; | ||
983 | return NULL; | ||
984 | } | ||
985 | |||
986 | /* since we give up the buffer (without freeing), it must not move anymore */ | ||
987 | dont_move = true; | ||
988 | *size = dircache_size + (DIRCACHE_RESERVE-reserve_used); | ||
989 | |||
990 | return dircache_root; | ||
991 | } | ||
992 | |||
993 | /** | ||
994 | * Main initialization function that must be called before any other | 984 | * Main initialization function that must be called before any other |
995 | * operations within the dircache. | 985 | * operations within the dircache. |
996 | */ | 986 | */ |
@@ -1085,10 +1075,10 @@ int dircache_get_build_ticks(void) | |||
1085 | } | 1075 | } |
1086 | 1076 | ||
1087 | /** | 1077 | /** |
1088 | * Disables the dircache. Usually called on shutdown or when | 1078 | * Disables dircache without freeing the buffer (so it can be re-enabled |
1089 | * accepting a usb connection. | 1079 | * afterwards with dircache_resume() or dircache_build()), usually |
1090 | */ | 1080 | * called when accepting an usb connection */ |
1091 | void dircache_disable(void) | 1081 | void dircache_suspend(void) |
1092 | { | 1082 | { |
1093 | int i; | 1083 | int i; |
1094 | bool cache_in_use; | 1084 | bool cache_in_use; |
@@ -1118,6 +1108,52 @@ void dircache_disable(void) | |||
1118 | } | 1108 | } |
1119 | 1109 | ||
1120 | /** | 1110 | /** |
1111 | * Re-enables the dircache if previous suspended by dircache_suspend | ||
1112 | * or dircache_steal_buffer(), re-using the already allocated buffer | ||
1113 | * | ||
1114 | * Returns true if the background build is started, false otherwise | ||
1115 | * (e.g. if no buffer was previously allocated) | ||
1116 | */ | ||
1117 | bool dircache_resume(void) | ||
1118 | { | ||
1119 | bool ret = allocated_size > 0; | ||
1120 | if (ret) /* only resume if already allocated */ | ||
1121 | ret = (dircache_build(0) > 0); | ||
1122 | |||
1123 | return (allocated_size > 0); | ||
1124 | } | ||
1125 | |||
1126 | /** | ||
1127 | * Disables the dircache entirely. Usually called on shutdown or when | ||
1128 | * deactivated | ||
1129 | */ | ||
1130 | void dircache_disable(void) | ||
1131 | { | ||
1132 | dircache_suspend(); | ||
1133 | dircache_handle = core_free(dircache_handle); | ||
1134 | dircache_size = allocated_size = 0; | ||
1135 | } | ||
1136 | |||
1137 | /** | ||
1138 | * Steal the allocated dircache buffer and disable dircache. | ||
1139 | */ | ||
1140 | void* dircache_steal_buffer(size_t *size) | ||
1141 | { | ||
1142 | dircache_suspend(); | ||
1143 | if (dircache_size == 0) | ||
1144 | { | ||
1145 | *size = 0; | ||
1146 | return NULL; | ||
1147 | } | ||
1148 | |||
1149 | /* since we give up the buffer (without freeing), it must not move anymore */ | ||
1150 | dont_move = true; | ||
1151 | *size = dircache_size + (DIRCACHE_RESERVE-reserve_used); | ||
1152 | |||
1153 | return dircache_root; | ||
1154 | } | ||
1155 | |||
1156 | /** | ||
1121 | * Usermode function to return dircache_entry index to the given path. | 1157 | * Usermode function to return dircache_entry index to the given path. |
1122 | */ | 1158 | */ |
1123 | static int dircache_get_entry_id_ex(const char *filename, bool go_down) | 1159 | static int dircache_get_entry_id_ex(const char *filename, bool go_down) |
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 6beeeb6c23..019ccf49b7 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h | |||
@@ -76,6 +76,8 @@ int dircache_get_cache_size(void); | |||
76 | int dircache_get_reserve_used(void); | 76 | int dircache_get_reserve_used(void); |
77 | int dircache_get_build_ticks(void); | 77 | int dircache_get_build_ticks(void); |
78 | void dircache_disable(void); | 78 | void dircache_disable(void); |
79 | void dircache_suspend(void); | ||
80 | bool dircache_resume(void); | ||
79 | int dircache_get_entry_id(const char *filename); | 81 | int dircache_get_entry_id(const char *filename); |
80 | size_t dircache_copy_path(int index, char *buf, size_t size); | 82 | size_t dircache_copy_path(int index, char *buf, size_t size); |
81 | 83 | ||