Merge pull request #2123 from jesven/fix_list_thread

修正list_thread关中断时间过长的问题
This commit is contained in:
Bernard Xiong 2018-12-27 17:16:32 +08:00 committed by GitHub
commit 137ed381c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 602 additions and 343 deletions

View File

@ -26,6 +26,8 @@
* 2012-10-22 Bernard add MS VC++ patch. * 2012-10-22 Bernard add MS VC++ patch.
* 2016-06-02 armink beautify the list_thread command * 2016-06-02 armink beautify the list_thread command
* 2018-11-22 Jesven list_thread add smp support * 2018-11-22 Jesven list_thread add smp support
* 2018-12-27 Jesven Fix the problem that disable interrupt too long in list_thread
* Provide protection for the "first layer of objects" when list_*
*/ */
#include <rthw.h> #include <rthw.h>
@ -35,6 +37,8 @@
#include "finsh.h" #include "finsh.h"
#define LIST_FIND_OBJ_NR 8
long hello(void) long hello(void)
{ {
rt_kprintf("Hello RT-Thread!\n"); rt_kprintf("Hello RT-Thread!\n");
@ -53,41 +57,112 @@ long version(void)
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information); FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
MSH_CMD_EXPORT(version, show RT-Thread version information); MSH_CMD_EXPORT(version, show RT-Thread version information);
static int object_name_maxlen(const char *type_name, struct rt_list_node *list)
{
struct rt_list_node *node;
struct rt_object *object = NULL;
int max_length = rt_strlen(type_name), length;
rt_enter_critical();
for (node = list->next; node != list; node = node->next)
{
object = rt_list_entry(node, struct rt_object, list);
length = rt_strlen(object->name);
if (length > max_length) max_length = length;
}
rt_exit_critical();
if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX;
return max_length;
}
rt_inline void object_split(int len) rt_inline void object_split(int len)
{ {
while (len--) rt_kprintf("-"); while (len--) rt_kprintf("-");
} }
static long _list_thread(struct rt_list_node *list) typedef struct
{ {
int maxlen; rt_list_t *list;
rt_uint8_t *ptr; rt_list_t **array;
struct rt_thread *thread; rt_uint8_t type;
struct rt_list_node *node; int nr; /* input: max nr, can't be 0 */
const char *item_title = "thread"; int nr_out; /* out: got nr */
} list_get_next_t;
maxlen = object_name_maxlen(item_title, list); static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
{
struct rt_object_information *info;
rt_list_t *list;
info = rt_object_get_information(type);
list = &info->object_list;
p->list = list;
p->type = type;
p->array = array;
p->nr = nr;
p->nr_out = 0;
}
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
{
int first_flag = 0;
rt_ubase_t level;
rt_list_t *node, *list;
rt_list_t **array;
int nr;
arg->nr_out = 0;
if (!arg->nr || !arg->type)
{
return (rt_list_t *)RT_NULL;
}
list = arg->list;
if (!current) /* find first */
{
node = list;
first_flag = 1;
}
else
{
node = current;
}
level = rt_hw_interrupt_disable();
if (!first_flag)
{
struct rt_object *obj;
/* The node in the list? */
obj = rt_list_entry(node, struct rt_object, list);
if ((obj->type & ~RT_Object_Class_Static) != arg->type)
{
rt_hw_interrupt_enable(level);
return (rt_list_t *)RT_NULL;
}
}
nr = 0;
array = arg->array;
while (1)
{
node = node->next;
if (node == list)
{
node = (rt_list_t *)RT_NULL;
break;
}
nr++;
*array++ = node;
if (nr == arg->nr)
{
break;
}
}
rt_hw_interrupt_enable(level);
arg->nr_out = nr;
return node;
}
long list_thread(void)
{
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
const char *item_title = "thread";
int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
rt_kprintf("%-*.s cpu pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s cpu pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
@ -96,10 +171,34 @@ static long _list_thread(struct rt_list_node *list)
rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n"); rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
for (node = list->next; node != list; node = node->next)
do
{
next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_thread thread_info, *thread;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
/* copy info */
memcpy(&thread_info, obj, sizeof thread_info);
rt_hw_interrupt_enable(level);
thread = (struct rt_thread*)obj;
{ {
rt_uint8_t stat; rt_uint8_t stat;
thread = rt_list_entry(node, struct rt_thread, list); rt_uint8_t *ptr;
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
if (thread->oncpu != RT_CPU_DETACHED) if (thread->oncpu != RT_CPU_DETACHED)
rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->current_priority); rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->current_priority);
@ -138,22 +237,13 @@ static long _list_thread(struct rt_list_node *list)
thread->error); thread->error);
#endif #endif
} }
}
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_thread(void)
{
rt_ubase_t level;
struct rt_object_information *info;
long ret;
level = rt_hw_interrupt_disable();
info = rt_object_get_information(RT_Object_Class_Thread);
ret = _list_thread(&info->object_list);
rt_hw_interrupt_enable(level);
return ret;
}
FINSH_FUNCTION_EXPORT(list_thread, list thread); FINSH_FUNCTION_EXPORT(list_thread, list thread);
MSH_CMD_EXPORT(list_thread, list thread); MSH_CMD_EXPORT(list_thread, list thread);
@ -173,20 +263,43 @@ static void show_wait_queue(struct rt_list_node *list)
} }
#ifdef RT_USING_SEMAPHORE #ifdef RT_USING_SEMAPHORE
static long _list_sem(struct rt_list_node *list) long list_sem(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_semaphore *sem;
struct rt_list_node *node;
const char *item_title = "semaphore"; const char *item_title = "semaphore";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " --- --------------\n"); rt_kprintf( " --- --------------\n");
for (node = list->next; node != list; node = node->next)
do
{ {
sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_semaphore *sem;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
sem = (struct rt_semaphore*)obj;
if (!rt_list_isempty(&sem->parent.suspend_thread)) if (!rt_list_isempty(&sem->parent.suspend_thread))
{ {
rt_kprintf("%-*.*s %03d %d:", rt_kprintf("%-*.*s %03d %d:",
@ -206,37 +319,55 @@ static long _list_sem(struct rt_list_node *list)
rt_list_len(&sem->parent.suspend_thread)); rt_list_len(&sem->parent.suspend_thread));
} }
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
FINSH_FUNCTION_EXPORT(list_sem, list semaphore in system);
long list_sem(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_Semaphore);
return _list_sem(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system); MSH_CMD_EXPORT(list_sem, list semaphore in system);
#endif #endif
#ifdef RT_USING_EVENT #ifdef RT_USING_EVENT
static long _list_event(struct rt_list_node *list) long list_event(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_event *e;
struct rt_list_node *node;
const char *item_title = "event"; const char *item_title = "event";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- --------------\n"); rt_kprintf( " ---------- --------------\n");
for (node = list->next; node != list; node = node->next)
do
{ {
e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_event *e;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
e = (struct rt_event *)obj;
if (!rt_list_isempty(&e->parent.suspend_thread)) if (!rt_list_isempty(&e->parent.suspend_thread))
{ {
rt_kprintf("%-*.*s 0x%08x %03d:", rt_kprintf("%-*.*s 0x%08x %03d:",
@ -253,36 +384,55 @@ static long _list_event(struct rt_list_node *list)
maxlen, RT_NAME_MAX, e->parent.parent.name, e->set); maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
} }
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_event(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_Event);
return _list_event(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_event, list event in system); FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system); MSH_CMD_EXPORT(list_event, list event in system);
#endif #endif
#ifdef RT_USING_MUTEX #ifdef RT_USING_MUTEX
static long _list_mutex(struct rt_list_node *list) long list_mutex(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_mutex *m;
struct rt_list_node *node;
const char *item_title = "mutex"; const char *item_title = "mutex";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " -------- ---- --------------\n"); rt_kprintf( " -------- ---- --------------\n");
for (node = list->next; node != list; node = node->next)
do
{ {
m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_mutex *m;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
m = (struct rt_mutex *)obj;
rt_kprintf("%-*.*s %-8.*s %04d %d\n", rt_kprintf("%-*.*s %-8.*s %04d %d\n",
maxlen, RT_NAME_MAX, maxlen, RT_NAME_MAX,
m->parent.parent.name, m->parent.parent.name,
@ -290,38 +440,57 @@ static long _list_mutex(struct rt_list_node *list)
m->owner->name, m->owner->name,
m->hold, m->hold,
rt_list_len(&m->parent.suspend_thread)); rt_list_len(&m->parent.suspend_thread));
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_mutex(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_Mutex);
return _list_mutex(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system); FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system); MSH_CMD_EXPORT(list_mutex, list mutex in system);
#endif #endif
#ifdef RT_USING_MAILBOX #ifdef RT_USING_MAILBOX
static long _list_mailbox(struct rt_list_node *list) long list_mailbox(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_mailbox *m;
struct rt_list_node *node;
const char *item_title = "mailbox"; const char *item_title = "mailbox";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- ---- --------------\n"); rt_kprintf( " ---- ---- --------------\n");
for (node = list->next; node != list; node = node->next)
do
{ {
m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_mailbox *m;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
m = (struct rt_mailbox *)obj;
if (!rt_list_isempty(&m->parent.suspend_thread)) if (!rt_list_isempty(&m->parent.suspend_thread))
{ {
rt_kprintf("%-*.*s %04d %04d %d:", rt_kprintf("%-*.*s %04d %04d %d:",
@ -342,37 +511,56 @@ static long _list_mailbox(struct rt_list_node *list)
m->size, m->size,
rt_list_len(&m->parent.suspend_thread)); rt_list_len(&m->parent.suspend_thread));
} }
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_mailbox(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_MailBox);
return _list_mailbox(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system); FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system); MSH_CMD_EXPORT(list_mailbox, list mail box in system);
#endif #endif
#ifdef RT_USING_MESSAGEQUEUE #ifdef RT_USING_MESSAGEQUEUE
static long _list_msgqueue(struct rt_list_node *list) long list_msgqueue(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_messagequeue *m;
struct rt_list_node *node;
const char *item_title = "msgqueue"; const char *item_title = "msgqueue";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- --------------\n"); rt_kprintf( " ---- --------------\n");
for (node = list->next; node != list; node = node->next) do
{ {
m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_messagequeue *m;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
m = (struct rt_messagequeue *)obj;
if (!rt_list_isempty(&m->parent.suspend_thread)) if (!rt_list_isempty(&m->parent.suspend_thread))
{ {
rt_kprintf("%-*.*s %04d %d:", rt_kprintf("%-*.*s %04d %d:",
@ -392,36 +580,54 @@ static long _list_msgqueue(struct rt_list_node *list)
rt_list_len(&m->parent.suspend_thread)); rt_list_len(&m->parent.suspend_thread));
} }
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_msgqueue(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_MessageQueue);
return _list_msgqueue(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system); FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system); MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
#endif #endif
#ifdef RT_USING_MEMHEAP #ifdef RT_USING_MEMHEAP
static long _list_memheap(struct rt_list_node *list) long list_memheap(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_memheap *mh;
struct rt_list_node *node;
const char *item_title = "memheap"; const char *item_title = "memheap";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- ------------- --------------\n"); rt_kprintf( " ---------- ------------- --------------\n");
for (node = list->next; node != list; node = node->next) do
{ {
mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_memheap *mh;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
mh = (struct rt_memheap *)obj;
rt_kprintf("%-*.*s %-010d %-013d %-05d\n", rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
maxlen, RT_NAME_MAX, maxlen, RT_NAME_MAX,
@ -429,37 +635,56 @@ static long _list_memheap(struct rt_list_node *list)
mh->pool_size, mh->pool_size,
mh->max_used_size, mh->max_used_size,
mh->available_size); mh->available_size);
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_memheap(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_MemHeap);
return _list_memheap(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system); FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system); MSH_CMD_EXPORT(list_memheap, list memory heap in system);
#endif #endif
#ifdef RT_USING_MEMPOOL #ifdef RT_USING_MEMPOOL
static long _list_mempool(struct rt_list_node *list) long list_mempool(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_mempool *mp;
struct rt_list_node *node;
const char *item_title = "mempool"; const char *item_title = "mempool";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- ---- ---- --------------\n"); rt_kprintf( " ---- ---- ---- --------------\n");
for (node = list->next; node != list; node = node->next) do
{ {
mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_mempool *mp;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
mp = (struct rt_mempool *)obj;
if (mp->suspend_thread_count > 0) if (mp->suspend_thread_count > 0)
{ {
rt_kprintf("%-*.*s %04d %04d %04d %d:", rt_kprintf("%-*.*s %04d %04d %04d %d:",
@ -483,35 +708,52 @@ static long _list_mempool(struct rt_list_node *list)
mp->suspend_thread_count); mp->suspend_thread_count);
} }
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_mempool(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_MemPool);
return _list_mempool(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system) FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
MSH_CMD_EXPORT(list_mempool, list memory pool in system); MSH_CMD_EXPORT(list_mempool, list memory pool in system);
#endif #endif
static long _list_timer(struct rt_list_node *list) long list_timer(void)
{ {
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen; int maxlen;
struct rt_timer *timer;
struct rt_list_node *node;
const char *item_title = "timer"; const char *item_title = "timer";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- ---------- -----------\n"); rt_kprintf( " ---------- ---------- -----------\n");
for (node = list->next; node != list; node = node->next) do {
next = list_get_next(next, &find_arg);
{ {
timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list)); int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_timer *timer;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
timer = (struct rt_timer *)obj;
rt_kprintf("%-*.*s 0x%08x 0x%08x ", rt_kprintf("%-*.*s 0x%08x 0x%08x ",
maxlen, RT_NAME_MAX, maxlen, RT_NAME_MAX,
timer->parent.name, timer->parent.name,
@ -521,30 +763,21 @@ static long _list_timer(struct rt_list_node *list)
rt_kprintf("activated\n"); rt_kprintf("activated\n");
else else
rt_kprintf("deactivated\n"); rt_kprintf("deactivated\n");
} }
}
}
while (next != (rt_list_t*)RT_NULL);
rt_kprintf("current tick:0x%08x\n", rt_tick_get()); rt_kprintf("current tick:0x%08x\n", rt_tick_get());
return 0; return 0;
} }
long list_timer(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_Timer);
return _list_timer(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_timer, list timer in system); FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system); MSH_CMD_EXPORT(list_timer, list timer in system);
#ifdef RT_USING_DEVICE #ifdef RT_USING_DEVICE
static long _list_device(struct rt_list_node *list) static char *const device_type_str[] =
{
int maxlen;
struct rt_device *device;
struct rt_list_node *node;
char *const device_type_str[] =
{ {
"Character Device", "Character Device",
"Block Device", "Block Device",
@ -567,15 +800,44 @@ static long _list_device(struct rt_list_node *list)
"Miscellaneous Device", "Miscellaneous Device",
"Unknown" "Unknown"
}; };
long list_device(void)
{
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
int maxlen;
const char *item_title = "device"; const char *item_title = "device";
maxlen = object_name_maxlen(item_title, list); list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen); rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " -------------------- ----------\n"); rt_kprintf( " -------------------- ----------\n");
for (node = list->next; node != list; node = node->next) do
{ {
device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list)); next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_device *device;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_hw_interrupt_disable();
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_hw_interrupt_enable(level);
continue;
}
rt_hw_interrupt_enable(level);
device = (struct rt_device *)obj;
rt_kprintf("%-*.*s %-20s %-8d\n", rt_kprintf("%-*.*s %-20s %-8d\n",
maxlen, RT_NAME_MAX, maxlen, RT_NAME_MAX,
device->parent.name, device->parent.name,
@ -583,18 +845,14 @@ static long _list_device(struct rt_list_node *list)
device_type_str[device->type] : device_type_str[device->type] :
device_type_str[RT_Device_Class_Unknown], device_type_str[RT_Device_Class_Unknown],
device->ref_count); device->ref_count);
} }
}
}
while (next != (rt_list_t*)RT_NULL);
return 0; return 0;
} }
long list_device(void)
{
struct rt_object_information *info;
info = rt_object_get_information(RT_Object_Class_Device);
return _list_device(&info->object_list);
}
FINSH_FUNCTION_EXPORT(list_device, list device in system); FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system); MSH_CMD_EXPORT(list_device, list device in system);
#endif #endif

View File

@ -367,7 +367,8 @@ typedef struct rt_object *rt_object_t; /**< Type for kernel obj
*/ */
enum rt_object_class_type enum rt_object_class_type
{ {
RT_Object_Class_Thread = 0, /**< The object is a thread. */ RT_Object_Class_Null = 0, /**< The object is not used. */
RT_Object_Class_Thread, /**< The object is a thread. */
RT_Object_Class_Semaphore, /**< The object is a semaphore. */ RT_Object_Class_Semaphore, /**< The object is a semaphore. */
RT_Object_Class_Mutex, /**< The object is a mutex. */ RT_Object_Class_Mutex, /**< The object is a mutex. */
RT_Object_Class_Event, /**< The object is a event. */ RT_Object_Class_Event, /**< The object is a event. */