xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/src/gcthread.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001-2003 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <[email protected]>
7  *
8  * For licensing information, see the file 'LICENCE' in this directory.
9  *
10  * $Id: gcthread.c,v 1.3 2005/01/22 16:01:12 lunn Exp $
11  *
12  */
13 #include <linux/kernel.h>
14 #include "nodelist.h"
15 //#include <cyg/kernel/kapi.h> prife
16 
17 #if defined(CYGOPT_FS_JFFS2_GCTHREAD)
18 
19 #define GC_THREAD_FLAG_TRIG 1
20 #define GC_THREAD_FLAG_STOP 2
21 #define GC_THREAD_FLAG_HAS_EXIT 4
22 
23 #if 0
24 static cyg_thread_entry_t jffs2_garbage_collect_thread;
25 
26 void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
27 {
28      struct super_block *sb=OFNI_BS_2SFFJ(c);
29 
30      /* Wake up the thread */
31      D1(printk("jffs2_garbage_collect_trigger\n"));
32 
33      cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_TRIG);
34 }
35 
36 
37 void
38 jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
39 {
40      struct super_block *sb=OFNI_BS_2SFFJ(c);
41 
42      RT_ASSERT(c);
43      RT_ASSERT(!sb->s_gc_thread_handle);
44 
45      cyg_flag_init(&sb->s_gc_thread_flags);
46      cyg_mutex_init(&sb->s_lock);
47 
48      D1(printk("jffs2_start_garbage_collect_thread\n"));
49      /* Start the thread. Doesn't matter if it fails -- it's only an
50       * optimisation anyway */
51      cyg_thread_create(CYGNUM_JFFS2_GC_THREAD_PRIORITY,
52                        jffs2_garbage_collect_thread,
53                        (unsigned long)c,"jffs2 gc thread",
54                        (void*)sb->s_gc_thread_stack,
55                        sizeof(sb->s_gc_thread_stack),
56                        &sb->s_gc_thread_handle,
57                        &sb->s_gc_thread);
58 
59      cyg_thread_resume(sb->s_gc_thread_handle);
60 }
61 
62 void
63 jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
64 {
65      struct super_block *sb=OFNI_BS_2SFFJ(c);
66 
67      RT_ASSERT(sb->s_gc_thread_handle);
68 
69      D1(printk("jffs2_stop_garbage_collect_thread\n"));
70      /* Stop the thread and wait for it if necessary */
71 
72      cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_STOP);
73 
74      D1(printk("jffs2_stop_garbage_collect_thread wait\n"));
75 
76      cyg_flag_wait(&sb->s_gc_thread_flags,
77                    GC_THREAD_FLAG_HAS_EXIT,
78                    CYG_FLAG_WAITMODE_OR| CYG_FLAG_WAITMODE_CLR);
79 
80      // Kill and free the resources ...  this is safe due to the flag
81      // from the thread.
82      cyg_thread_kill(sb->s_gc_thread_handle);
83      cyg_thread_delete(sb->s_gc_thread_handle);
84 
85      cyg_mutex_destroy(&sb->s_lock);
86      cyg_flag_destroy(&sb->s_gc_thread_flags);
87 }
88 
89 
90 static void
91 jffs2_garbage_collect_thread(unsigned long data)
92 {
93      struct jffs2_sb_info *c=(struct jffs2_sb_info *)data;
94      struct super_block *sb=OFNI_BS_2SFFJ(c);
95      cyg_flag_value_t flag;
96      cyg_mtab_entry *mte;
97 
98      D1(printk("jffs2_garbage_collect_thread START\n"));
99 
100      while(1) {
101           flag=cyg_flag_timed_wait(&sb->s_gc_thread_flags,
102                                    GC_THREAD_FLAG_TRIG|GC_THREAD_FLAG_STOP,
103                                    CYG_FLAG_WAITMODE_OR| CYG_FLAG_WAITMODE_CLR,
104                                    cyg_current_time()+
105                                    CYGNUM_JFFS2_GS_THREAD_TICKS);
106 
107           if (flag & GC_THREAD_FLAG_STOP)
108                break;
109 
110           D1(printk("jffs2: GC THREAD GC BEGIN\n"));
111 
112           mte=cyg_fs_root_lookup((cyg_dir *) sb->s_root);
113           CYG_ASSERT(mte, "Bad mount point");
114           cyg_fs_lock(mte, mte->fs->syncmode);
115 
116           if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
117                printf("No space for garbage collection. "
118                       "Aborting JFFS2 GC thread\n");
119                break;
120           }
121           cyg_fs_unlock(mte, mte->fs->syncmode);
122           D1(printk("jffs2: GC THREAD GC END\n"));
123      }
124 
125      D1(printk("jffs2_garbage_collect_thread EXIT\n"));
126      cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_HAS_EXIT);
127 }
128 #endif
129 
cyg_current_time(void)130 rt_uint32_t cyg_current_time(void)
131 {
132 	return 0;
133 }
134 
135 static void
136 jffs2_garbage_collect_thread(unsigned long data);
137 
jffs2_garbage_collect_trigger(struct jffs2_sb_info * c)138 void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
139 {
140      struct super_block *sb=OFNI_BS_2SFFJ(c);
141 
142      /* Wake up the thread */
143      D1(printk("jffs2_garbage_collect_trigger\n"));
144 
145      rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_TRIG);
146 }
147 
148 static struct rt_thread gc_thread;
149 void
jffs2_start_garbage_collect_thread(struct jffs2_sb_info * c)150 jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
151 {
152      struct super_block *sb=OFNI_BS_2SFFJ(c);
153      cyg_mtab_entry *mte;
154      int result;
155 
156      RT_ASSERT(c);
157      //RT_ASSERT(!sb->s_gc_thread_handle);
158 
159      mte=(cyg_dir *) sb->s_root;
160      RT_ASSERT(mte);
161 
162      rt_event_init(&sb->s_gc_thread_flags, "gc_event", RT_IPC_FLAG_FIFO);
163      rt_mutex_init(&sb->s_lock, "gc_mutex", RT_IPC_FLAG_FIFO);
164 //     rt_mutex_init(&mte->fs->syncmode, "fs_lock", RT_IPC_FLAG_FIFO);
165 
166      D1(printk("jffs2_start_garbage_collect_thread\n"));
167      /* Start the thread. Doesn't matter if it fails -- it's only an
168       * optimisation anyway */
169      result =  rt_thread_init(&sb->s_gc_thread,
170 	                   "jffs2_gc_thread",
171                        jffs2_garbage_collect_thread,
172                        (void *)c,
173                        (void*)sb->s_gc_thread_stack,
174                        sizeof(sb->s_gc_thread_stack),
175 					   CYGNUM_JFFS2_GC_THREAD_PRIORITY,
176 					   CYGNUM_JFFS2_GC_THREAD_TICKS
177 					   );
178 	 if (result != RT_EOK) {
179 		 rt_thread_startup(&sb->s_gc_thread);
180 		 /* how to deal with the following filed? */
181 		 /* sb->s_gc_thread_handle; */
182 	 }
183 }
184 
185 void
jffs2_stop_garbage_collect_thread(struct jffs2_sb_info * c)186 jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
187 {
188      struct super_block *sb=OFNI_BS_2SFFJ(c);
189      cyg_mtab_entry *mte;
190 	 rt_uint32_t  e;
191 
192      //RT_ASSERT(sb->s_gc_thread_handle);
193 
194      D1(printk("jffs2_stop_garbage_collect_thread\n"));
195      /* Stop the thread and wait for it if necessary */
196 
197      rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_STOP);
198 
199      D1(printk("jffs2_stop_garbage_collect_thread wait\n"));
200 
201      rt_event_recv(&sb->s_gc_thread_flags,
202                    GC_THREAD_FLAG_HAS_EXIT,
203                    RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
204 				   RT_WAITING_FOREVER,  &e);
205 
206      // Kill and free the resources ...  this is safe due to the flag
207      // from the thread.
208      rt_thread_detach(&sb->s_gc_thread);
209      rt_sem_detach(&sb->s_lock);
210      rt_event_detach(&sb->s_gc_thread_flags);
211 }
212 
213 
214 static void
jffs2_garbage_collect_thread(unsigned long data)215 jffs2_garbage_collect_thread(unsigned long data)
216 {
217      struct jffs2_sb_info *c=(struct jffs2_sb_info *)data;
218      struct super_block *sb=OFNI_BS_2SFFJ(c);
219      cyg_mtab_entry *mte;
220      rt_uint32_t flag = 0;
221 
222      D1(printk("jffs2_garbage_collect_thread START\n"));
223 
224      while(1) {
225           rt_event_recv(&sb->s_gc_thread_flags,
226                         GC_THREAD_FLAG_TRIG | GC_THREAD_FLAG_STOP,
227                         RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
228 				        cyg_current_time() + CYGNUM_JFFS2_GS_THREAD_TICKS,
229 						&flag);
230 
231           if (flag & GC_THREAD_FLAG_STOP)
232                break;
233 
234           D1(printk("jffs2: GC THREAD GC BEGIN\n"));
235 
236           mte=(cyg_dir *) sb->s_root;
237           RT_ASSERT(mte != NULL);
238 //          rt_mutex_take(&mte->fs->syncmode, RT_WAITING_FOREVER);
239 
240           if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
241                printf("No space for garbage collection. "
242                       "Aborting JFFS2 GC thread\n");
243                break;
244           }
245 //          rt_mutex_release(&mte->fs->syncmode);
246           D1(printk("jffs2: GC THREAD GC END\n"));
247      }
248 
249      D1(printk("jffs2_garbage_collect_thread EXIT\n"));
250      rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_HAS_EXIT);
251 }
252 #endif
253