1
0
Fork 0
forked from len0rd/rockbox

Make the OS stacks usage debug screen nicer, and unfiy the code for charcell/bmp lcds

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12921 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2007-03-26 12:09:08 +00:00
parent 21c930310c
commit cd1ccad9d6

View file

@ -35,6 +35,8 @@
#include "audio.h" #include "audio.h"
#include "mp3_playback.h" #include "mp3_playback.h"
#include "settings.h" #include "settings.h"
#include "list.h"
#include "statusbar.h"
#include "dir.h" #include "dir.h"
#include "panic.h" #include "panic.h"
#include "screens.h" #include "screens.h"
@ -93,7 +95,6 @@ extern int ata_io_address;
extern struct core_entry cores[NUM_CORES]; extern struct core_entry cores[NUM_CORES];
#ifndef SIMULATOR #ifndef SIMULATOR
#ifdef HAVE_LCD_BITMAP
static char thread_status_char(int status) static char thread_status_char(int status)
{ {
switch (status) switch (status)
@ -106,136 +107,93 @@ static char thread_status_char(int status)
return '?'; return '?';
} }
#if NUM_CORES > 1
#define IF_COP2(...) __VA_ARGS__
#else
#define IF_COP2(...)
#endif
/* the MSB of thread_ids[..] is the core, so this will need changing
if we ever get a target with more than 2 cores...
The next 7 bits are used for the thread number on that core...
SO, MAXTHREADS must be kept under 256... which shouldnt be a problem */
static unsigned char thread_ids[NUM_CORES * MAXTHREADS];
static char* dbg_os_getname(int selected_item, void * data, char *buffer)
{
(void)data;
struct thread_entry *thread = NULL;
int status, usage;
int core = (thread_ids[selected_item]&0x80)>>7;
int thread_number = thread_ids[selected_item]&0x7F;
thread = &cores[core].threads[thread_number];
if (thread == NULL)
return "";
usage = thread_stack_usage(thread);
status = thread_get_status(thread);
#ifdef HAVE_PRIORITY_SCHEDULING
snprintf(buffer, MAX_PATH, IF_COP2("(%d) ") "%c%c %d %2d%% %s",
IF_COP2(core,)
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
thread->priority,
usage, thread->name);
#else
snprintf(buffer, MAX_PATH, IF_COP2("(%d) ") "%c%c %2d%% %s",
IF_COP2(core,)
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
usage, thread->name);
#endif
return buffer;
}
/* Test code!!! */ /* Test code!!! */
static bool dbg_os(void) static bool dbg_os(void)
{ {
struct thread_entry *thread; struct gui_synclist lists;
char buf[32]; struct thread_entry *thread = NULL;
int i; int action, i;
int usage; int thread_count = 0;
int status; int core = 0;
#if NUM_CORES > 1 #if NUM_CORES > 1
unsigned int core; for(core = 0; core < NUM_CORES; core++)
int line;
#endif
lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED);
lcd_clear_display();
while(1)
{ {
#if 0 /* Enable to simulate UI lag. */
int _x;
for (_x = 0; _x < 1000000L; _x++) ;
#endif #endif
#if NUM_CORES > 1 for(i = 0;i < MAXTHREADS; i++)
lcd_puts(0, 0, "Core and stack usage:");
line = 0;
for(core = 0; core < NUM_CORES; core++)
{ {
for(i = 0; i < MAXTHREADS; i++) thread = &cores[core].threads[i];
if (thread->name != NULL)
{ {
thread = &cores[core].threads[i]; thread_ids[thread_count] = (core<<7)|i;
if (thread->name == NULL) thread_count++;
continue;
usage = thread_stack_usage(thread);
status = thread_get_status(thread);
# ifdef HAVE_PRIORITY_SCHEDULING
snprintf(buf, 32, "(%d) %c%c %d %s: %d%%", core,
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
cores[CURRENT_CORE].threads[i].priority,
cores[core].threads[i].name, usage);
# else
snprintf(buf, 32, "(%d) %c%c %s: %d%%", core,
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
cores[core].threads[i].name, usage);
# endif
lcd_puts(0, ++line, buf);
} }
} }
#else #if NUM_CORES > 1
lcd_puts(0, 0, "Stack usage:");
for(i = 0; i < MAXTHREADS; i++)
{
thread = &cores[CURRENT_CORE].threads[i];
if (thread->name == NULL)
continue;
usage = thread_stack_usage(thread);
status = thread_get_status(thread);
# ifdef HAVE_PRIORITY_SCHEDULING
snprintf(buf, 32, "%c%c %d %s: %d%%",
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
cores[CURRENT_CORE].threads[i].priority,
cores[CURRENT_CORE].threads[i].name, usage);
# else
snprintf(buf, 32, "%c%c %s: %d%%",
(status == STATE_RUNNING) ? '*' : ' ',
thread_status_char(status),
cores[CURRENT_CORE].threads[i].name, usage);
# endif
lcd_puts(0, 1+i, buf);
}
#endif
lcd_update();
if (action_userabort(HZ/10))
return false;
} }
return false; #endif
} gui_synclist_init(&lists, dbg_os_getname, NULL, false, 1);
#else /* !HAVE_LCD_BITMAP */ gui_synclist_set_title(&lists, IF_COP2("Core and ") "Stack usage:", NOICON);
static bool dbg_os(void) gui_synclist_set_icon_callback(&lists, NULL);
{ gui_synclist_set_nb_items(&lists, thread_count);
char buf[32]; action_signalscreenchange();
int button;
int usage;
int currval = 0;
lcd_clear_display();
while(1) while(1)
{ {
lcd_puts(0, 0, "Stack usage"); /* Do a redraw every time so the thread info is updated,
disabled scrolling, but the name isnt important */
/* Only Archos Player uses this - so assume a single core */ gui_synclist_draw(&lists);
usage = thread_stack_usage(&cores[CPU].threads[currval]); gui_syncstatusbar_draw(&statusbars, true);
snprintf(buf, 32, "%d: %d%% ", currval, usage); action = get_action(CONTEXT_STD, HZ/5);
lcd_puts(0, 1, buf); gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD);
if (action == ACTION_STD_CANCEL)
button = get_action(CONTEXT_SETTINGS,HZ/10);
switch(button)
{
case ACTION_STD_CANCEL:
action_signalscreenchange();
return false;
case ACTION_SETTINGS_DEC:
currval--;
if(currval < 0)
currval = MAXTHREADS-1;
break; break;
else if(default_event_handler(action) == SYS_USB_CONNECTED)
case ACTION_SETTINGS_INC: return true;
currval++;
if(currval > MAXTHREADS-1)
currval = 0;
break;
}
} }
action_signalscreenchange();
return false; return false;
} }
#endif /* !HAVE_LCD_BITMAP */
#endif /* !SIMULATOR */ #endif /* !SIMULATOR */
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#if CONFIG_CODEC != SWCODEC #if CONFIG_CODEC != SWCODEC
#ifndef SIMULATOR #ifndef SIMULATOR