diff options
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 183 |
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 | |||
145 | struct tagcache_command_entry { | ||
146 | long command; | ||
147 | long idx_id; | ||
148 | long tag; | ||
149 | long data; | ||
139 | }; | 150 | }; |
140 | 151 | ||
152 | static struct tagcache_command_entry command_queue[TAGCACHE_COMMAND_QUEUE_LENGTH]; | ||
153 | static volatile int command_queue_widx = 0; | ||
154 | static volatile int command_queue_ridx = 0; | ||
155 | static 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. */ | ||
158 | static 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 | ||
2740 | long 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 | |||
2757 | long tagcache_get_serial(void) | ||
2758 | { | ||
2759 | return current_tcmh.serial; | ||
2760 | } | ||
2761 | |||
2762 | long tagcache_get_commitid(void) | ||
2763 | { | ||
2764 | return current_tcmh.commitid; | ||
2765 | } | ||
2766 | |||
2767 | static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) | 2758 | static 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 | ||
2786 | bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, | 2778 | bool 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 | |||
2795 | static 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 | |||
2806 | void 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 | |||
2859 | static 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 | |||
2892 | long 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 | |||
2908 | void tagcache_update_numeric(int idx_id, int tag, long data) | ||
2909 | { | ||
2910 | queue_command(CMD_UPDATE_NUMERIC, idx_id, tag, data); | ||
2911 | } | ||
2912 | |||
2913 | long tagcache_get_serial(void) | ||
2914 | { | ||
2915 | return current_tcmh.serial; | ||
2916 | } | ||
2917 | |||
2918 | long tagcache_get_commitid(void) | ||
2919 | { | ||
2920 | return current_tcmh.commitid; | ||
2921 | } | ||
2799 | 2922 | ||
2800 | static bool write_tag(int fd, const char *tagstr, const char *datastr) | 2923 | static 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 | ||
3943 | void tagcache_shutdown(void) | 4068 | void 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 |