diff options
author | Jens Arnold <amiconn@rockbox.org> | 2007-01-22 23:29:39 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2007-01-22 23:29:39 +0000 |
commit | 4376abb74868d792702dfa613a551f7748cb1dd4 (patch) | |
tree | 5d9940e12634017a02f0574c35f5d1a365d2b46c | |
parent | ea37d4c0729057b01c0e0b82b3bef7030379da2f (diff) | |
download | rockbox-4376abb74868d792702dfa613a551f7748cb1dd4.tar.gz rockbox-4376abb74868d792702dfa613a551f7748cb1dd4.zip |
Disk and filesystem speed and stress test plugin. Aimed at developers, not built by default.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12091 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/test_disk.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/apps/plugins/test_disk.c b/apps/plugins/test_disk.c new file mode 100644 index 0000000000..3292cfa930 --- /dev/null +++ b/apps/plugins/test_disk.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Jens Arnold | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "plugin.h" | ||
21 | |||
22 | PLUGIN_HEADER | ||
23 | |||
24 | #define TEST_FILE "/test_disk.tmp" | ||
25 | #define FRND_SEED 0x78C3 /* arbirary */ | ||
26 | |||
27 | #ifdef HAVE_MMC | ||
28 | #define TEST_SIZE (20*1024*1024) | ||
29 | #else | ||
30 | #define TEST_SIZE (300*1024*1024) | ||
31 | #endif | ||
32 | |||
33 | static struct plugin_api* rb; | ||
34 | static unsigned char* audiobuf; | ||
35 | static int audiobufsize; | ||
36 | |||
37 | static unsigned short frnd_buffer; | ||
38 | static int line = 0; | ||
39 | static int max_line = 0; | ||
40 | |||
41 | static void mem_fill_frnd(unsigned char *addr, int len) | ||
42 | { | ||
43 | unsigned char *end = addr + len; | ||
44 | unsigned random = frnd_buffer; | ||
45 | |||
46 | while (addr < end) | ||
47 | { | ||
48 | random = 75 * random + 74; | ||
49 | *addr++ = random >> 8; | ||
50 | } | ||
51 | frnd_buffer = random; | ||
52 | } | ||
53 | |||
54 | static bool mem_cmp_frnd(unsigned char *addr, int len) | ||
55 | { | ||
56 | unsigned char *end = addr + len; | ||
57 | unsigned random = frnd_buffer; | ||
58 | |||
59 | while (addr < end) | ||
60 | { | ||
61 | random = 75 * random + 74; | ||
62 | if (*addr++ != ((random >> 8) & 0xff)) | ||
63 | return false; | ||
64 | } | ||
65 | frnd_buffer = random; | ||
66 | return true; | ||
67 | } | ||
68 | |||
69 | static void log_init(void) | ||
70 | { | ||
71 | int h; | ||
72 | |||
73 | rb->lcd_getstringsize("A", NULL, &h); | ||
74 | max_line = LCD_HEIGHT / h; | ||
75 | line = 0; | ||
76 | rb->lcd_clear_display(); | ||
77 | rb->lcd_update(); | ||
78 | } | ||
79 | |||
80 | static void log_lcd(char *text, bool advance) | ||
81 | { | ||
82 | rb->lcd_puts(0, line, text); | ||
83 | rb->lcd_update(); | ||
84 | if (advance) | ||
85 | if (++line >= max_line) | ||
86 | line = 0; | ||
87 | } | ||
88 | |||
89 | static bool test_fs(void) | ||
90 | { | ||
91 | unsigned char text_buf[32]; | ||
92 | unsigned char *buf_start; | ||
93 | int align, buf_len; | ||
94 | int total, current; | ||
95 | int fd; | ||
96 | |||
97 | align = (-(int)audiobuf) & 3; | ||
98 | buf_start = audiobuf + align; | ||
99 | buf_len = (audiobufsize - align - 4) & ~3; | ||
100 | |||
101 | log_init(); | ||
102 | rb->snprintf(text_buf, sizeof text_buf, "FS stress test: %dKB", (TEST_SIZE>>10)); | ||
103 | log_lcd(text_buf, true); | ||
104 | |||
105 | fd = rb->creat(TEST_FILE, 0); | ||
106 | if (fd < 0) | ||
107 | { | ||
108 | rb->splash(0, true, "Couldn't create testfile."); | ||
109 | goto error; | ||
110 | } | ||
111 | |||
112 | frnd_buffer = FRND_SEED; | ||
113 | total = TEST_SIZE; | ||
114 | while (total > 0) | ||
115 | { | ||
116 | current = rb->rand() % buf_len; | ||
117 | current = MIN(current, total); | ||
118 | align = rb->rand() & 3; | ||
119 | rb->snprintf(text_buf, sizeof text_buf, "Wrt %dKB, %dKB left", | ||
120 | current >> 10, total >> 10); | ||
121 | log_lcd(text_buf, false); | ||
122 | |||
123 | mem_fill_frnd(buf_start + align, current); | ||
124 | if (current != rb->write(fd, buf_start + align, current)) | ||
125 | { | ||
126 | rb->splash(0, true, "Write error."); | ||
127 | rb->close(fd); | ||
128 | goto error; | ||
129 | } | ||
130 | total -= current; | ||
131 | } | ||
132 | rb->close(fd); | ||
133 | |||
134 | fd = rb->open(TEST_FILE, O_RDONLY); | ||
135 | if (fd < 0) | ||
136 | { | ||
137 | rb->splash(0, true, "Couldn't open testfile."); | ||
138 | goto error; | ||
139 | } | ||
140 | |||
141 | frnd_buffer = FRND_SEED; | ||
142 | total = TEST_SIZE; | ||
143 | while (total > 0) | ||
144 | { | ||
145 | current = rb->rand() % buf_len; | ||
146 | current = MIN(current, total); | ||
147 | align = rb->rand() & 3; | ||
148 | rb->snprintf(text_buf, sizeof text_buf, "Cmp %dKB, %dKB left", | ||
149 | current >> 10, total >> 10); | ||
150 | log_lcd(text_buf, false); | ||
151 | |||
152 | if (current != rb->read(fd, buf_start + align, current)) | ||
153 | { | ||
154 | rb->splash(0, true, "Read error."); | ||
155 | rb->close(fd); | ||
156 | goto error; | ||
157 | } | ||
158 | if (!mem_cmp_frnd(buf_start + align, current)) | ||
159 | { | ||
160 | log_lcd(text_buf, true); | ||
161 | log_lcd("Compare error.", true); | ||
162 | rb->close(fd); | ||
163 | goto error; | ||
164 | } | ||
165 | total -= current; | ||
166 | } | ||
167 | rb->close(fd); | ||
168 | log_lcd(text_buf, true); | ||
169 | log_lcd("Test passed.", true); | ||
170 | |||
171 | error: | ||
172 | rb->remove(TEST_FILE); | ||
173 | rb->button_clear_queue(); | ||
174 | rb->button_get(true); | ||
175 | |||
176 | return false; | ||
177 | } | ||
178 | |||
179 | static bool test_speed(void) | ||
180 | { | ||
181 | unsigned char text_buf[32]; | ||
182 | unsigned char *buf_start; | ||
183 | long time; | ||
184 | int buf_len; | ||
185 | int fd; | ||
186 | |||
187 | buf_len = (-(int)audiobuf) & 3; | ||
188 | buf_start = audiobuf + buf_len; | ||
189 | buf_len = (audiobufsize - buf_len) & ~3; | ||
190 | rb->memset(buf_start, 'T', buf_len); | ||
191 | buf_len -= 2; | ||
192 | |||
193 | log_init(); | ||
194 | log_lcd("Disk speed test", true); | ||
195 | |||
196 | fd = rb->creat(TEST_FILE, 0); | ||
197 | if (fd < 0) | ||
198 | { | ||
199 | rb->splash(0, true, "Couldn't create testfile."); | ||
200 | goto error; | ||
201 | } | ||
202 | time = *rb->current_tick; | ||
203 | if (buf_len != rb->write(fd, buf_start, buf_len)) | ||
204 | { | ||
205 | rb->splash(0, true, "Write error."); | ||
206 | rb->close(fd); | ||
207 | goto error; | ||
208 | } | ||
209 | time = *rb->current_tick - time; | ||
210 | rb->snprintf(text_buf, sizeof text_buf, "Create: %d KByte/s", | ||
211 | (25 * buf_len / time) >> 8); | ||
212 | log_lcd(text_buf, true); | ||
213 | rb->close(fd); | ||
214 | |||
215 | fd = rb->open(TEST_FILE, O_WRONLY); | ||
216 | if (fd < 0) | ||
217 | { | ||
218 | rb->splash(0, true, "Couldn't open testfile."); | ||
219 | goto error; | ||
220 | } | ||
221 | time = *rb->current_tick; | ||
222 | if (buf_len != rb->write(fd, buf_start, buf_len)) | ||
223 | { | ||
224 | rb->splash(0, true, "Write error."); | ||
225 | rb->close(fd); | ||
226 | goto error; | ||
227 | } | ||
228 | time = *rb->current_tick - time; | ||
229 | rb->snprintf(text_buf, sizeof text_buf, "Write A: %d KByte/s", | ||
230 | (25 * buf_len / time) >> 8); | ||
231 | log_lcd(text_buf, true); | ||
232 | rb->close(fd); | ||
233 | |||
234 | fd = rb->open(TEST_FILE, O_WRONLY); | ||
235 | if (fd < 0) | ||
236 | { | ||
237 | rb->splash(0, true, "Couldn't open testfile."); | ||
238 | goto error; | ||
239 | } | ||
240 | time = *rb->current_tick; | ||
241 | if (buf_len != rb->write(fd, buf_start + 1, buf_len)) | ||
242 | { | ||
243 | rb->splash(0, true, "Write error."); | ||
244 | rb->close(fd); | ||
245 | goto error; | ||
246 | } | ||
247 | time = *rb->current_tick - time; | ||
248 | rb->snprintf(text_buf, sizeof text_buf, "Write U: %d KByte/s", | ||
249 | (25 * buf_len / time) >> 8); | ||
250 | log_lcd(text_buf, true); | ||
251 | rb->close(fd); | ||
252 | |||
253 | fd = rb->open(TEST_FILE, O_RDONLY); | ||
254 | if (fd < 0) | ||
255 | { | ||
256 | rb->splash(0, true, "Couldn't open testfile."); | ||
257 | goto error; | ||
258 | } | ||
259 | time = *rb->current_tick; | ||
260 | if (buf_len != rb->read(fd, buf_start, buf_len)) | ||
261 | { | ||
262 | rb->splash(0, true, "Read error."); | ||
263 | rb->close(fd); | ||
264 | goto error; | ||
265 | } | ||
266 | time = *rb->current_tick - time; | ||
267 | rb->snprintf(text_buf, sizeof text_buf, "Read A: %d KByte/s", | ||
268 | (25 * buf_len / time) >> 8); | ||
269 | log_lcd(text_buf, true); | ||
270 | rb->close(fd); | ||
271 | |||
272 | fd = rb->open(TEST_FILE, O_RDONLY); | ||
273 | if (fd < 0) | ||
274 | { | ||
275 | rb->splash(0, true, "Couldn't open testfile."); | ||
276 | goto error; | ||
277 | } | ||
278 | time = *rb->current_tick; | ||
279 | if (buf_len != rb->read(fd, buf_start + 1, buf_len)) | ||
280 | { | ||
281 | rb->splash(0, true, "Read error."); | ||
282 | rb->close(fd); | ||
283 | goto error; | ||
284 | } | ||
285 | time = *rb->current_tick - time; | ||
286 | rb->snprintf(text_buf, sizeof text_buf, "Read U: %d KByte/s", | ||
287 | (25 * buf_len / time) >> 8); | ||
288 | log_lcd(text_buf, true); | ||
289 | rb->close(fd); | ||
290 | |||
291 | error: | ||
292 | rb->remove(TEST_FILE); | ||
293 | rb->button_clear_queue(); | ||
294 | rb->button_get(true); | ||
295 | |||
296 | return false; | ||
297 | } | ||
298 | |||
299 | |||
300 | /* this is the plugin entry point */ | ||
301 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
302 | { | ||
303 | static const struct menu_item items[] = { | ||
304 | { "Disk speed", test_speed }, | ||
305 | { "FS stress test", test_fs }, | ||
306 | }; | ||
307 | int m; | ||
308 | |||
309 | (void)parameter; | ||
310 | rb = api; | ||
311 | audiobuf = rb->plugin_get_audio_buffer(&audiobufsize); | ||
312 | rb->srand(*rb->current_tick); | ||
313 | |||
314 | if (rb->global_settings->backlight_timeout > 0) | ||
315 | rb->backlight_set_timeout(1); /* keep the light on */ | ||
316 | |||
317 | m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, | ||
318 | NULL, NULL, NULL); | ||
319 | rb->menu_run(m); | ||
320 | rb->menu_exit(m); | ||
321 | |||
322 | /* restore normal backlight setting */ | ||
323 | rb->backlight_set_timeout(rb->global_settings->backlight_timeout); | ||
324 | |||
325 | return PLUGIN_OK; | ||
326 | } | ||