summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-08-02 17:39:34 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-08-02 17:39:34 +0000
commitd8ac6074184ffc21c4da8c594df72ee42aa23df2 (patch)
treec42203d8bf2c7e85a9886616f0268250dbe5e9d6 /apps
parentd68ae6a7a62e0a32cfc84200092985910c0fd099 (diff)
downloadrockbox-d8ac6074184ffc21c4da8c594df72ee42aa23df2.tar.gz
rockbox-d8ac6074184ffc21c4da8c594df72ee42aa23df2.zip
Tagcache: Fixed runtime stats not being gathered when tagcache is kept
on disk. Initial attempt to make tagcache thread safe. Replaced a few direct buffer allocations with buffer_alloc from tagcache and dircache where possible. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10415 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/onplay.c2
-rw-r--r--apps/tagcache.c72
-rw-r--r--apps/tagcache.h1
-rw-r--r--apps/tagtree.c10
4 files changed, 70 insertions, 15 deletions
diff --git a/apps/onplay.c b/apps/onplay.c
index 53058b3bc9..4558da72fe 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -850,7 +850,7 @@ int onplay(char* file, int attr, int from)
850 850
851 if (context == CONTEXT_WPS || 851 if (context == CONTEXT_WPS ||
852 context == CONTEXT_TREE || 852 context == CONTEXT_TREE ||
853 (context == CONTEXT_ID3DB)) 853 context == CONTEXT_ID3DB)
854 { 854 {
855 items[i].desc = ID2P(LANG_PLAYLIST); 855 items[i].desc = ID2P(LANG_PLAYLIST);
856 items[i].function = playlist_options; 856 items[i].function = playlist_options;
diff --git a/apps/tagcache.c b/apps/tagcache.c
index d6a8a798e3..1485ed8e51 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -43,9 +43,9 @@
43 * | | | | +--x--------x---------+ | 43 * | | | | +--x--------x---------+ |
44 * | | | | | Temporary Commit DB | | 44 * | | | | | Temporary Commit DB | |
45 * | | | | +---------------------+ | 45 * | | | | +---------------------+ |
46 * +-x----x---x---x--+ | 46 * +-x----x-------x--+ |
47 * | TagCache RAM DB x==\(W) +-----------------+ | 47 * | TagCache RAM DB x==\(W) +-----------------+ |
48 * +-x----x---x---x--+ \===x | | 48 * +-----------------+ \===x | |
49 * | | | | (R) | Ram DB Loader x============x DirCache 49 * | | | | (R) | Ram DB Loader x============x DirCache
50 * +-x----x---x---x---+ /==x | | (optional) 50 * +-x----x---x---x---+ /==x | | (optional)
51 * | Tagcache Disk DB x==/ +-----------------+ | 51 * | Tagcache Disk DB x==/ +-----------------+ |
@@ -191,6 +191,10 @@ static int total_entry_count = 0;
191static int data_size = 0; 191static int data_size = 0;
192static int processed_dir_count; 192static int processed_dir_count;
193 193
194/* Thread safe locking */
195static volatile int write_lock;
196static volatile int read_lock;
197
194int tagcache_str_to_tag(const char *str) 198int tagcache_str_to_tag(const char *str)
195{ 199{
196 int i; 200 int i;
@@ -516,6 +520,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx)
516 sizeof(struct index_entry)) 520 sizeof(struct index_entry))
517 { 521 {
518 logf("write error #3"); 522 logf("write error #3");
523 logf("idxid: %d", idxid);
519 return false; 524 return false;
520 } 525 }
521 526
@@ -818,9 +823,12 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
818 struct master_header master_hdr; 823 struct master_header master_hdr;
819 int i; 824 int i;
820 825
821 if (tcs->valid) 826 if (tcs->initialized)
822 tagcache_search_finish(tcs); 827 tagcache_search_finish(tcs);
823 828
829 while (read_lock)
830 sleep(1);
831
824 memset(tcs, 0, sizeof(struct tagcache_search)); 832 memset(tcs, 0, sizeof(struct tagcache_search));
825 if (stat.commit_step > 0 || !stat.ready) 833 if (stat.commit_step > 0 || !stat.ready)
826 return false; 834 return false;
@@ -830,7 +838,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
830 tcs->seek_pos = 0; 838 tcs->seek_pos = 0;
831 tcs->seek_list_count = 0; 839 tcs->seek_list_count = 0;
832 tcs->filter_count = 0; 840 tcs->filter_count = 0;
833 tcs->valid = true;
834 tcs->masterfd = -1; 841 tcs->masterfd = -1;
835 842
836 for (i = 0; i < TAG_COUNT; i++) 843 for (i = 0; i < TAG_COUNT; i++)
@@ -848,18 +855,28 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
848#endif 855#endif
849 { 856 {
850 if (tagcache_is_numeric_tag(tcs->type)) 857 if (tagcache_is_numeric_tag(tcs->type))
858 {
859 tcs->valid = true;
860 tcs->initialized = true;
851 return true; 861 return true;
862 }
852 863
853 tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); 864 tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false);
854 if (tcs->idxfd[tcs->type] < 0) 865 if (tcs->idxfd[tcs->type] < 0)
855 return false; 866 return false;
856 867
857 tcs->masterfd = open_master_fd(&master_hdr, false); 868 /* Always open as R/W so we can pass tcs to functions that modify data also
869 * without failing. */
870 tcs->masterfd = open_master_fd(&master_hdr, true);
858 871
859 if (tcs->masterfd < 0) 872 if (tcs->masterfd < 0)
860 return false; 873 return false;
861 } 874 }
862 875
876 tcs->valid = true;
877 tcs->initialized = true;
878 write_lock++;
879
863 return true; 880 return true;
864} 881}
865 882
@@ -1153,6 +1170,9 @@ void tagcache_search_finish(struct tagcache_search *tcs)
1153{ 1170{
1154 int i; 1171 int i;
1155 1172
1173 if (!tcs->initialized)
1174 return;
1175
1156 if (tcs->masterfd >= 0) 1176 if (tcs->masterfd >= 0)
1157 { 1177 {
1158 close(tcs->masterfd); 1178 close(tcs->masterfd);
@@ -1170,6 +1190,9 @@ void tagcache_search_finish(struct tagcache_search *tcs)
1170 1190
1171 tcs->ramsearch = false; 1191 tcs->ramsearch = false;
1172 tcs->valid = false; 1192 tcs->valid = false;
1193 tcs->initialized = 0;
1194 if (write_lock > 0)
1195 write_lock--;
1173} 1196}
1174 1197
1175#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) 1198#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
@@ -2076,6 +2099,9 @@ static bool commit(void)
2076 2099
2077 logf("committing tagcache"); 2100 logf("committing tagcache");
2078 2101
2102 while (write_lock)
2103 sleep(1);
2104
2079 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 2105 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY);
2080 if (tmpfd < 0) 2106 if (tmpfd < 0)
2081 { 2107 {
@@ -2103,6 +2129,8 @@ static bool commit(void)
2103 return true; 2129 return true;
2104 } 2130 }
2105 2131
2132 read_lock++;
2133
2106 /* Try to steal every buffer we can :) */ 2134 /* Try to steal every buffer we can :) */
2107 if (tempbuf_size == 0) 2135 if (tempbuf_size == 0)
2108 local_allocation = true; 2136 local_allocation = true;
@@ -2138,6 +2166,7 @@ static bool commit(void)
2138 logf("delaying commit until next boot"); 2166 logf("delaying commit until next boot");
2139 stat.commit_delayed = true; 2167 stat.commit_delayed = true;
2140 close(tmpfd); 2168 close(tmpfd);
2169 read_lock--;
2141 return false; 2170 return false;
2142 } 2171 }
2143 2172
@@ -2169,6 +2198,7 @@ static bool commit(void)
2169 else 2198 else
2170 stat.commit_delayed = true; 2199 stat.commit_delayed = true;
2171 stat.commit_step = 0; 2200 stat.commit_step = 0;
2201 read_lock--;
2172 return false; 2202 return false;
2173 } 2203 }
2174 } 2204 }
@@ -2178,8 +2208,11 @@ static bool commit(void)
2178 2208
2179 /* Update the master index headers. */ 2209 /* Update the master index headers. */
2180 if ( (masterfd = open_master_fd(&tcmh, true)) < 0) 2210 if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
2211 {
2212 read_lock--;
2181 return false; 2213 return false;
2182 2214 }
2215
2183 tcmh.tch.entry_count += tch.entry_count; 2216 tcmh.tch.entry_count += tch.entry_count;
2184 tcmh.tch.datasize = sizeof(struct master_header) 2217 tcmh.tch.datasize = sizeof(struct master_header)
2185 + sizeof(struct index_entry) * tcmh.tch.entry_count 2218 + sizeof(struct index_entry) * tcmh.tch.entry_count
@@ -2212,6 +2245,7 @@ static bool commit(void)
2212#endif 2245#endif
2213 2246
2214 queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0); 2247 queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0);
2248 read_lock--;
2215 2249
2216 return true; 2250 return true;
2217} 2251}
@@ -2263,6 +2297,9 @@ long tagcache_increase_serial(void)
2263 if (!stat.ready) 2297 if (!stat.ready)
2264 return -2; 2298 return -2;
2265 2299
2300 while (read_lock)
2301 sleep(1);
2302
2266 if (!update_current_serial(current_serial + 1)) 2303 if (!update_current_serial(current_serial + 1))
2267 return -1; 2304 return -1;
2268 2305
@@ -2478,6 +2515,9 @@ bool tagcache_import_changelog(void)
2478 if (!stat.ready) 2515 if (!stat.ready)
2479 return false; 2516 return false;
2480 2517
2518 while (read_lock)
2519 sleep(1);
2520
2481 clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); 2521 clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
2482 if (clfd < 0) 2522 if (clfd < 0)
2483 { 2523 {
@@ -2491,6 +2531,8 @@ bool tagcache_import_changelog(void)
2491 return false; 2531 return false;
2492 } 2532 }
2493 2533
2534 write_lock++;
2535
2494 /* Fast readline */ 2536 /* Fast readline */
2495 while ( 1 ) 2537 while ( 1 )
2496 { 2538 {
@@ -2530,6 +2572,8 @@ bool tagcache_import_changelog(void)
2530 close(clfd); 2572 close(clfd);
2531 close(masterfd); 2573 close(masterfd);
2532 2574
2575 write_lock--;
2576
2533 update_current_serial(current_serial); 2577 update_current_serial(current_serial);
2534 2578
2535 return true; 2579 return true;
@@ -2724,12 +2768,11 @@ static bool delete_entry(long idx_id)
2724#ifdef HAVE_TC_RAMCACHE 2768#ifdef HAVE_TC_RAMCACHE
2725static bool allocate_tagcache(void) 2769static bool allocate_tagcache(void)
2726{ 2770{
2771 struct master_header tcmh;
2727 int fd; 2772 int fd;
2728 2773
2729 /* Load the header. */ 2774 /* Load the header. */
2730 hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04); 2775 if ( (fd = open_master_fd(&tcmh, false)) < 0)
2731 memset(hdr, 0, sizeof(struct ramcache_header));
2732 if ( (fd = open_master_fd(&hdr->h, false)) < 0)
2733 { 2776 {
2734 hdr = NULL; 2777 hdr = NULL;
2735 return false; 2778 return false;
@@ -2737,17 +2780,17 @@ static bool allocate_tagcache(void)
2737 2780
2738 close(fd); 2781 close(fd);
2739 2782
2740 hdr->indices = (struct index_entry *)(hdr + 1);
2741
2742 /** 2783 /**
2743 * Now calculate the required cache size plus 2784 * Now calculate the required cache size plus
2744 * some extra space for alignment fixes. 2785 * some extra space for alignment fixes.
2745 */ 2786 */
2746 stat.ramcache_allocated = hdr->h.tch.datasize + 128 + TAGCACHE_RESERVE + 2787 stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE +
2747 sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); 2788 sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *);
2789 hdr = buffer_alloc(stat.ramcache_allocated + 128);
2790 memset(hdr, 0, sizeof(struct ramcache_header));
2791 memcpy(&hdr->h, &tcmh, sizeof(struct master_header));
2792 hdr->indices = (struct index_entry *)(hdr + 1);
2748 logf("tagcache: %d bytes allocated.", stat.ramcache_allocated); 2793 logf("tagcache: %d bytes allocated.", stat.ramcache_allocated);
2749 logf("at: 0x%04x", audiobuf);
2750 audiobuf += (long)((stat.ramcache_allocated & ~0x03) + 128);
2751 2794
2752 return true; 2795 return true;
2753} 2796}
@@ -3361,6 +3404,7 @@ void tagcache_init(void)
3361 memset(&stat, 0, sizeof(struct tagcache_stat)); 3404 memset(&stat, 0, sizeof(struct tagcache_stat));
3362 filenametag_fd = -1; 3405 filenametag_fd = -1;
3363 current_serial = 0; 3406 current_serial = 0;
3407 write_lock = read_lock = 0;
3364 3408
3365 queue_init(&tagcache_queue); 3409 queue_init(&tagcache_queue);
3366 create_thread(tagcache_thread, tagcache_stack, 3410 create_thread(tagcache_thread, tagcache_stack,
diff --git a/apps/tagcache.h b/apps/tagcache.h
index 1752d3ec45..450c21c26e 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -113,6 +113,7 @@ struct tagcache_search {
113 long position; 113 long position;
114 int entry_count; 114 int entry_count;
115 bool valid; 115 bool valid;
116 bool initialized;
116 117
117 /* Exported variables. */ 118 /* Exported variables. */
118 bool ramsearch; 119 bool ramsearch;
diff --git a/apps/tagtree.c b/apps/tagtree.c
index b5ec10b04f..4061e9d8d7 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -379,11 +379,17 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track)
379 379
380 /* Do not gather data unless proper setting has been enabled. */ 380 /* Do not gather data unless proper setting has been enabled. */
381 if (!global_settings.runtimedb) 381 if (!global_settings.runtimedb)
382 {
383 logf("runtimedb gathering not enabled");
382 return; 384 return;
385 }
383 386
384 /* Don't process unplayed tracks. */ 387 /* Don't process unplayed tracks. */
385 if (id3->elapsed == 0) 388 if (id3->elapsed == 0)
389 {
390 logf("not logging unplayed track");
386 return; 391 return;
392 }
387 393
388 if (!tagcache_find_index(&tcs, id3->path)) 394 if (!tagcache_find_index(&tcs, id3->path))
389 { 395 {
@@ -399,7 +405,11 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track)
399 405
400 lastplayed = tagcache_increase_serial(); 406 lastplayed = tagcache_increase_serial();
401 if (lastplayed < 0) 407 if (lastplayed < 0)
408 {
409 logf("incorrect tc serial:%d", lastplayed);
410 tagcache_search_finish(&tcs);
402 return; 411 return;
412 }
403 413
404 /* Ignore the last 15s (crossfade etc.) */ 414 /* Ignore the last 15s (crossfade etc.) */
405 playtime += MIN(id3->length, id3->elapsed + 15 * 1000); 415 playtime += MIN(id3->length, id3->elapsed + 15 * 1000);