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
This commit is contained in:
parent
ea37d4c072
commit
4376abb748
1 changed files with 326 additions and 0 deletions
326
apps/plugins/test_disk.c
Normal file
326
apps/plugins/test_disk.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 Jens Arnold
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
PLUGIN_HEADER
|
||||
|
||||
#define TEST_FILE "/test_disk.tmp"
|
||||
#define FRND_SEED 0x78C3 /* arbirary */
|
||||
|
||||
#ifdef HAVE_MMC
|
||||
#define TEST_SIZE (20*1024*1024)
|
||||
#else
|
||||
#define TEST_SIZE (300*1024*1024)
|
||||
#endif
|
||||
|
||||
static struct plugin_api* rb;
|
||||
static unsigned char* audiobuf;
|
||||
static int audiobufsize;
|
||||
|
||||
static unsigned short frnd_buffer;
|
||||
static int line = 0;
|
||||
static int max_line = 0;
|
||||
|
||||
static void mem_fill_frnd(unsigned char *addr, int len)
|
||||
{
|
||||
unsigned char *end = addr + len;
|
||||
unsigned random = frnd_buffer;
|
||||
|
||||
while (addr < end)
|
||||
{
|
||||
random = 75 * random + 74;
|
||||
*addr++ = random >> 8;
|
||||
}
|
||||
frnd_buffer = random;
|
||||
}
|
||||
|
||||
static bool mem_cmp_frnd(unsigned char *addr, int len)
|
||||
{
|
||||
unsigned char *end = addr + len;
|
||||
unsigned random = frnd_buffer;
|
||||
|
||||
while (addr < end)
|
||||
{
|
||||
random = 75 * random + 74;
|
||||
if (*addr++ != ((random >> 8) & 0xff))
|
||||
return false;
|
||||
}
|
||||
frnd_buffer = random;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void log_init(void)
|
||||
{
|
||||
int h;
|
||||
|
||||
rb->lcd_getstringsize("A", NULL, &h);
|
||||
max_line = LCD_HEIGHT / h;
|
||||
line = 0;
|
||||
rb->lcd_clear_display();
|
||||
rb->lcd_update();
|
||||
}
|
||||
|
||||
static void log_lcd(char *text, bool advance)
|
||||
{
|
||||
rb->lcd_puts(0, line, text);
|
||||
rb->lcd_update();
|
||||
if (advance)
|
||||
if (++line >= max_line)
|
||||
line = 0;
|
||||
}
|
||||
|
||||
static bool test_fs(void)
|
||||
{
|
||||
unsigned char text_buf[32];
|
||||
unsigned char *buf_start;
|
||||
int align, buf_len;
|
||||
int total, current;
|
||||
int fd;
|
||||
|
||||
align = (-(int)audiobuf) & 3;
|
||||
buf_start = audiobuf + align;
|
||||
buf_len = (audiobufsize - align - 4) & ~3;
|
||||
|
||||
log_init();
|
||||
rb->snprintf(text_buf, sizeof text_buf, "FS stress test: %dKB", (TEST_SIZE>>10));
|
||||
log_lcd(text_buf, true);
|
||||
|
||||
fd = rb->creat(TEST_FILE, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't create testfile.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
frnd_buffer = FRND_SEED;
|
||||
total = TEST_SIZE;
|
||||
while (total > 0)
|
||||
{
|
||||
current = rb->rand() % buf_len;
|
||||
current = MIN(current, total);
|
||||
align = rb->rand() & 3;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Wrt %dKB, %dKB left",
|
||||
current >> 10, total >> 10);
|
||||
log_lcd(text_buf, false);
|
||||
|
||||
mem_fill_frnd(buf_start + align, current);
|
||||
if (current != rb->write(fd, buf_start + align, current))
|
||||
{
|
||||
rb->splash(0, true, "Write error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
total -= current;
|
||||
}
|
||||
rb->close(fd);
|
||||
|
||||
fd = rb->open(TEST_FILE, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't open testfile.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
frnd_buffer = FRND_SEED;
|
||||
total = TEST_SIZE;
|
||||
while (total > 0)
|
||||
{
|
||||
current = rb->rand() % buf_len;
|
||||
current = MIN(current, total);
|
||||
align = rb->rand() & 3;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Cmp %dKB, %dKB left",
|
||||
current >> 10, total >> 10);
|
||||
log_lcd(text_buf, false);
|
||||
|
||||
if (current != rb->read(fd, buf_start + align, current))
|
||||
{
|
||||
rb->splash(0, true, "Read error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
if (!mem_cmp_frnd(buf_start + align, current))
|
||||
{
|
||||
log_lcd(text_buf, true);
|
||||
log_lcd("Compare error.", true);
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
total -= current;
|
||||
}
|
||||
rb->close(fd);
|
||||
log_lcd(text_buf, true);
|
||||
log_lcd("Test passed.", true);
|
||||
|
||||
error:
|
||||
rb->remove(TEST_FILE);
|
||||
rb->button_clear_queue();
|
||||
rb->button_get(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool test_speed(void)
|
||||
{
|
||||
unsigned char text_buf[32];
|
||||
unsigned char *buf_start;
|
||||
long time;
|
||||
int buf_len;
|
||||
int fd;
|
||||
|
||||
buf_len = (-(int)audiobuf) & 3;
|
||||
buf_start = audiobuf + buf_len;
|
||||
buf_len = (audiobufsize - buf_len) & ~3;
|
||||
rb->memset(buf_start, 'T', buf_len);
|
||||
buf_len -= 2;
|
||||
|
||||
log_init();
|
||||
log_lcd("Disk speed test", true);
|
||||
|
||||
fd = rb->creat(TEST_FILE, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't create testfile.");
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick;
|
||||
if (buf_len != rb->write(fd, buf_start, buf_len))
|
||||
{
|
||||
rb->splash(0, true, "Write error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick - time;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Create: %d KByte/s",
|
||||
(25 * buf_len / time) >> 8);
|
||||
log_lcd(text_buf, true);
|
||||
rb->close(fd);
|
||||
|
||||
fd = rb->open(TEST_FILE, O_WRONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't open testfile.");
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick;
|
||||
if (buf_len != rb->write(fd, buf_start, buf_len))
|
||||
{
|
||||
rb->splash(0, true, "Write error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick - time;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Write A: %d KByte/s",
|
||||
(25 * buf_len / time) >> 8);
|
||||
log_lcd(text_buf, true);
|
||||
rb->close(fd);
|
||||
|
||||
fd = rb->open(TEST_FILE, O_WRONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't open testfile.");
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick;
|
||||
if (buf_len != rb->write(fd, buf_start + 1, buf_len))
|
||||
{
|
||||
rb->splash(0, true, "Write error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick - time;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Write U: %d KByte/s",
|
||||
(25 * buf_len / time) >> 8);
|
||||
log_lcd(text_buf, true);
|
||||
rb->close(fd);
|
||||
|
||||
fd = rb->open(TEST_FILE, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't open testfile.");
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick;
|
||||
if (buf_len != rb->read(fd, buf_start, buf_len))
|
||||
{
|
||||
rb->splash(0, true, "Read error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick - time;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Read A: %d KByte/s",
|
||||
(25 * buf_len / time) >> 8);
|
||||
log_lcd(text_buf, true);
|
||||
rb->close(fd);
|
||||
|
||||
fd = rb->open(TEST_FILE, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
rb->splash(0, true, "Couldn't open testfile.");
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick;
|
||||
if (buf_len != rb->read(fd, buf_start + 1, buf_len))
|
||||
{
|
||||
rb->splash(0, true, "Read error.");
|
||||
rb->close(fd);
|
||||
goto error;
|
||||
}
|
||||
time = *rb->current_tick - time;
|
||||
rb->snprintf(text_buf, sizeof text_buf, "Read U: %d KByte/s",
|
||||
(25 * buf_len / time) >> 8);
|
||||
log_lcd(text_buf, true);
|
||||
rb->close(fd);
|
||||
|
||||
error:
|
||||
rb->remove(TEST_FILE);
|
||||
rb->button_clear_queue();
|
||||
rb->button_get(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* this is the plugin entry point */
|
||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||
{
|
||||
static const struct menu_item items[] = {
|
||||
{ "Disk speed", test_speed },
|
||||
{ "FS stress test", test_fs },
|
||||
};
|
||||
int m;
|
||||
|
||||
(void)parameter;
|
||||
rb = api;
|
||||
audiobuf = rb->plugin_get_audio_buffer(&audiobufsize);
|
||||
rb->srand(*rb->current_tick);
|
||||
|
||||
if (rb->global_settings->backlight_timeout > 0)
|
||||
rb->backlight_set_timeout(1); /* keep the light on */
|
||||
|
||||
m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL,
|
||||
NULL, NULL, NULL);
|
||||
rb->menu_run(m);
|
||||
rb->menu_exit(m);
|
||||
|
||||
/* restore normal backlight setting */
|
||||
rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
|
||||
|
||||
return PLUGIN_OK;
|
||||
}
|
Loading…
Reference in a new issue