summaryrefslogtreecommitdiff
path: root/apps/tagcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r--apps/tagcache.c183
1 files changed, 156 insertions, 27 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index f832f1e543..6d738bc5fb 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -136,8 +136,26 @@ enum tagcache_queue {
136 Q_IMPORT_CHANGELOG, 136 Q_IMPORT_CHANGELOG,
137 Q_UPDATE, 137 Q_UPDATE,
138 Q_REBUILD, 138 Q_REBUILD,
139
140 /* Internal tagcache command queue. */
141 CMD_UPDATE_MASTER_HEADER,
142 CMD_UPDATE_NUMERIC,
143};
144
145struct tagcache_command_entry {
146 long command;
147 long idx_id;
148 long tag;
149 long data;
139}; 150};
140 151
152static struct tagcache_command_entry command_queue[TAGCACHE_COMMAND_QUEUE_LENGTH];
153static volatile int command_queue_widx = 0;
154static volatile int command_queue_ridx = 0;
155static struct mutex command_queue_mutex;
156/* Timestamp of the last added event, so we can wait a bit before committing the
157 * whole queue at once. */
158static long command_queue_timestamp = 0;
141 159
142/* Tag database structures. */ 160/* Tag database structures. */
143 161
@@ -2737,33 +2755,6 @@ static void free_tempbuf(void)
2737 tempbuf_size = 0; 2755 tempbuf_size = 0;
2738} 2756}
2739 2757
2740long tagcache_increase_serial(void)
2741{
2742 long old;
2743
2744 if (!tc_stat.ready)
2745 return -2;
2746
2747 while (read_lock)
2748 sleep(1);
2749
2750 old = current_tcmh.serial++;
2751 if (!update_master_header())
2752 return -1;
2753
2754 return old;
2755}
2756
2757long tagcache_get_serial(void)
2758{
2759 return current_tcmh.serial;
2760}
2761
2762long tagcache_get_commitid(void)
2763{
2764 return current_tcmh.commitid;
2765}
2766
2767static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) 2758static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data)
2768{ 2759{
2769 struct index_entry idx; 2760 struct index_entry idx;
@@ -2783,6 +2774,7 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data)
2783 return write_index(masterfd, idx_id, &idx); 2774 return write_index(masterfd, idx_id, &idx);
2784} 2775}
2785 2776
2777#if 0
2786bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, 2778bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
2787 int tag, long data) 2779 int tag, long data)
2788{ 2780{
@@ -2796,6 +2788,137 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
2796 2788
2797 return modify_numeric_entry(tcs->masterfd, tcs->idx_id, tag, data); 2789 return modify_numeric_entry(tcs->masterfd, tcs->idx_id, tag, data);
2798} 2790}
2791#endif
2792
2793#define COMMAND_QUEUE_IS_EMPTY (command_queue_ridx == command_queue_widx)
2794
2795static bool command_queue_is_full(void)
2796{
2797 int next;
2798
2799 next = command_queue_widx + 1;
2800 if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH)
2801 next = 0;
2802
2803 return (next == command_queue_ridx);
2804}
2805
2806void run_command_queue(bool force)
2807{
2808 struct master_header myhdr;
2809 int masterfd;
2810
2811 if (COMMAND_QUEUE_IS_EMPTY)
2812 return;
2813
2814 if (!force && !command_queue_is_full()
2815 && current_tick - TAGCACHE_COMMAND_QUEUE_COMMIT_DELAY
2816 < command_queue_timestamp)
2817 {
2818 return;
2819 }
2820
2821 mutex_lock(&command_queue_mutex);
2822
2823 if ( (masterfd = open_master_fd(&myhdr, true)) < 0)
2824 return;
2825
2826 while (command_queue_ridx != command_queue_widx)
2827 {
2828 struct tagcache_command_entry *ce = &command_queue[command_queue_ridx];
2829
2830 switch (ce->command)
2831 {
2832 case CMD_UPDATE_MASTER_HEADER:
2833 {
2834 close(masterfd);
2835 update_master_header();
2836
2837 /* Re-open the masterfd. */
2838 if ( (masterfd = open_master_fd(&myhdr, true)) < 0)
2839 return;
2840
2841 break;
2842 }
2843 case CMD_UPDATE_NUMERIC:
2844 {
2845 modify_numeric_entry(masterfd, ce->idx_id, ce->tag, ce->data);
2846 break;
2847 }
2848 }
2849
2850 if (++command_queue_ridx >= TAGCACHE_COMMAND_QUEUE_LENGTH)
2851 command_queue_ridx = 0;
2852 }
2853
2854 close(masterfd);
2855
2856 mutex_unlock(&command_queue_mutex);
2857}
2858
2859static void queue_command(int cmd, long idx_id, int tag, long data)
2860{
2861 while (1)
2862 {
2863 int next;
2864
2865 mutex_lock(&command_queue_mutex);
2866 next = command_queue_widx + 1;
2867 if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH)
2868 next = 0;
2869
2870 /* Make sure queue is not full. */
2871 if (next != command_queue_ridx)
2872 {
2873 struct tagcache_command_entry *ce = &command_queue[command_queue_widx];
2874
2875 ce->command = cmd;
2876 ce->idx_id = idx_id;
2877 ce->tag = tag;
2878 ce->data = data;
2879
2880 command_queue_widx = next;
2881 command_queue_timestamp = current_tick;
2882 mutex_unlock(&command_queue_mutex);
2883 break;
2884 }
2885
2886 /* Queue is full, try again later... */
2887 mutex_unlock(&command_queue_mutex);
2888 sleep(1);
2889 }
2890}
2891
2892long tagcache_increase_serial(void)
2893{
2894 long old;
2895
2896 if (!tc_stat.ready)
2897 return -2;
2898
2899 while (read_lock)
2900 sleep(1);
2901
2902 old = current_tcmh.serial++;
2903 queue_command(CMD_UPDATE_MASTER_HEADER, 0, 0, 0);
2904
2905 return old;
2906}
2907
2908void tagcache_update_numeric(int idx_id, int tag, long data)
2909{
2910 queue_command(CMD_UPDATE_NUMERIC, idx_id, tag, data);
2911}
2912
2913long tagcache_get_serial(void)
2914{
2915 return current_tcmh.serial;
2916}
2917
2918long tagcache_get_commitid(void)
2919{
2920 return current_tcmh.commitid;
2921}
2799 2922
2800static bool write_tag(int fd, const char *tagstr, const char *datastr) 2923static bool write_tag(int fd, const char *tagstr, const char *datastr)
2801{ 2924{
@@ -3860,6 +3983,8 @@ static void tagcache_thread(void)
3860 3983
3861 while (1) 3984 while (1)
3862 { 3985 {
3986 run_command_queue(false);
3987
3863 queue_wait_w_tmo(&tagcache_queue, &ev, HZ); 3988 queue_wait_w_tmo(&tagcache_queue, &ev, HZ);
3864 3989
3865 switch (ev.id) 3990 switch (ev.id)
@@ -3942,6 +4067,9 @@ bool tagcache_prepare_shutdown(void)
3942 4067
3943void tagcache_shutdown(void) 4068void tagcache_shutdown(void)
3944{ 4069{
4070 /* Flush the command queue. */
4071 run_command_queue(true);
4072
3945#ifdef HAVE_EEPROM_SETTINGS 4073#ifdef HAVE_EEPROM_SETTINGS
3946 if (tc_stat.ramcache) 4074 if (tc_stat.ramcache)
3947 tagcache_dumpsave(); 4075 tagcache_dumpsave();
@@ -4023,6 +4151,7 @@ void tagcache_init(void)
4023 write_lock = read_lock = 0; 4151 write_lock = read_lock = 0;
4024 4152
4025#ifndef __PCTOOL__ 4153#ifndef __PCTOOL__
4154 mutex_init(&command_queue_mutex);
4026 queue_init(&tagcache_queue, true); 4155 queue_init(&tagcache_queue, true);
4027 create_thread(tagcache_thread, tagcache_stack, 4156 create_thread(tagcache_thread, tagcache_stack,
4028 sizeof(tagcache_stack), tagcache_thread_name 4157 sizeof(tagcache_stack), tagcache_thread_name