From 2b3c955082a7bf9e5d29c78d7ac46e48a3f8e696 Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Tue, 12 Aug 2025 21:54:45 +0800 Subject: [PATCH 1/5] proposal & refactor: reuse `list_find*` related logic by adding `rt_object_for_each_safe` Hello, I found may duplicate logic which is related to `list_find*`. I'd like to do something to simplify them. At first, I found the `rt_object_for_each` and tried to use it. But after carefully checking, I found the logic is a little different from the previous version. The most important one is that the different logic is running without lock, which is different with `rt_object_for_each`. So I add `rt_object_for_each_safe`, It will use the same logic with `list_find*` and call the iterator without locked. Signed-off-by: a1012112796 <1012112796@qq.com> --- .../dfs_v2/filesystems/procfs/proc_devices.c | 141 +-- .../filesystems/procfs/proc_partitions.c | 138 +-- components/finsh/cmd.c | 960 ++++++------------ include/rtthread.h | 7 + src/object.c | 162 +++ 5 files changed, 510 insertions(+), 898 deletions(-) diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c b/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c index 7bd07187d09..7bc0651c75d 100644 --- a/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c +++ b/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c @@ -21,9 +21,6 @@ #include #include - -#define LIST_FIND_OBJ_NR 8 - struct device_show { char *buf; @@ -32,97 +29,6 @@ struct device_show int index; }; -typedef struct -{ - rt_list_t *list; - rt_list_t **array; - rt_uint8_t type; - int nr; /* input: max nr, can't be 0 */ - int nr_out; /* out: got nr */ -} list_get_next_t; - -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((enum rt_object_class_type)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_base_t level; - rt_list_t *node, *list; - rt_list_t **array; - struct rt_object_information *info; - int nr; - - arg->nr_out = 0; - - if (!arg->nr || !arg->type) - { - return (rt_list_t *)RT_NULL; - } - - list = arg->list; - info = rt_list_entry(list, struct rt_object_information, object_list); - - if (!current) /* find first */ - { - node = list; - first_flag = 1; - } - else - { - node = current; - } - - level = rt_spin_lock_irqsave(&info->spinlock); - - 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_spin_unlock_irqrestore(&info->spinlock, 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_spin_unlock_irqrestore(&info->spinlock, level); - arg->nr_out = nr; - return node; -} - static char *const device_type_str[RT_Device_Class_Unknown] = { "Character Device", @@ -193,47 +99,24 @@ static void save_info(struct device_show *dev, char *dev_name) } } -static void list_device(struct device_show *dev) +static rt_err_t list_device_hook_(rt_object_t *object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + struct device_show *dev = (struct device_show *)data; + struct rt_device *device = (struct rt_device *)object; - list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - - do + if (device->type < RT_Device_Class_Unknown) { - 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_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } + save_info(dev + device->type, device->parent.name); + } - rt_spin_unlock_irqrestore(&info->spinlock, level); + return RT_EOK; +} - device = (struct rt_device *)obj; +static void list_device(struct device_show *dev) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; - if (device->type < RT_Device_Class_Unknown) - { - save_info(dev + device->type, device->parent.name); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_Device, list_device_hook_, dev, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); } static int show_info(struct dfs_seq_file *seq) diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c b/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c index 1c7a48a3651..624b6d5fc80 100644 --- a/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c +++ b/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c @@ -21,145 +21,29 @@ #include #include - -#define LIST_FIND_OBJ_NR 8 - -typedef struct -{ - rt_list_t *list; - rt_list_t **array; - rt_uint8_t type; - int nr; /* input: max nr, can't be 0 */ - int nr_out; /* out: got nr */ -} list_get_next_t; - -static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr) +static rt_err_t show_info_hook_(rt_object_t object, void *data) { - struct rt_object_information *info; - rt_list_t *list; - - info = rt_object_get_information((enum rt_object_class_type)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_base_t level; - rt_list_t *node, *list; - rt_list_t **array; - struct rt_object_information *info; - int nr; - - arg->nr_out = 0; - - if (!arg->nr || !arg->type) - { - return (rt_list_t *)RT_NULL; - } + rt_device_t device; + struct dfs_seq_file *seq = (struct dfs_seq_file *) data; - list = arg->list; - info = rt_list_entry(list, struct rt_object_information, object_list); + device = (struct rt_device *)object; - if (!current) /* find first */ - { - node = list; - first_flag = 1; - } - else + if (device->type == RT_Device_Class_Block) { - node = current; - } + struct rt_device_blk_geometry geometry = { 0 }; - level = rt_spin_lock_irqsave(&info->spinlock); + rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - 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_spin_unlock_irqrestore(&info->spinlock, level); - return (rt_list_t *)RT_NULL; - } + dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0, + geometry.sector_count, device->parent.name); } - - 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_spin_unlock_irqrestore(&info->spinlock, level); - arg->nr_out = nr; - return node; } static int show_info(struct dfs_seq_file *seq) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; - list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - - 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_device *device; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - device = (struct rt_device *)obj; - - if (device->type == RT_Device_Class_Block) - { - struct rt_device_blk_geometry geometry = { 0 }; - - rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - - dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0, - geometry.sector_count, device->parent.name); - } - } - } - } while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_Device, show_info_hook_, seq, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index 9251ce4cb01..be8bcff05dd 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -42,7 +42,6 @@ #include #define LIST_DFS_OPT_ID 0x100 -#define LIST_FIND_OBJ_NR 8 static long clear(void) { @@ -65,111 +64,73 @@ rt_inline void object_split(int len) while (len--) rt_kprintf("-"); } -typedef struct +static rt_err_t thread_print_(rt_object_t object, void *data) { - rt_list_t *list; - rt_list_t **array; - rt_uint8_t type; - int nr; /* input: max nr, can't be 0 */ - int nr_out; /* out: got nr */ -} list_get_next_t; - -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((enum rt_object_class_type)type); - list = &info->object_list; + RT_UNUSED(data); - p->list = list; - p->type = type; - p->array = array; - p->nr = nr; - p->nr_out = 0; -} + rt_thread_t thread = (rt_thread_t) object; -static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg) -{ - int first_flag = 0; - rt_base_t level; - rt_list_t *node, *list; - rt_list_t **array; - struct rt_object_information *info; - int nr; + rt_uint8_t stat; + rt_uint8_t *ptr; - arg->nr_out = 0; - - if (!arg->nr || !arg->type) - { - return (rt_list_t *)RT_NULL; - } - - list = arg->list; - info = rt_list_entry(list, struct rt_object_information, object_list); - - if (!current) /* find first */ - { - node = list; - first_flag = 1; - } +#ifdef RT_USING_SMP + /* no synchronization applied since it's only for debug */ + if (RT_SCHED_CTX(thread).oncpu != RT_CPU_DETACHED) + rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, + thread->parent.name, RT_SCHED_CTX(thread).oncpu, + RT_SCHED_CTX(thread).bind_cpu, + RT_SCHED_PRIV(thread).current_priority); else - { - node = current; - } - - level = rt_spin_lock_irqsave(&info->spinlock); - - 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_spin_unlock_irqrestore(&info->spinlock, level); - return (rt_list_t *)RT_NULL; - } - } + rt_kprintf("%-*.*s N/A %3d %4d ", maxlen, RT_NAME_MAX, + thread->parent.name, + RT_SCHED_CTX(thread).bind_cpu, + RT_SCHED_PRIV(thread).current_priority); - nr = 0; - array = arg->array; - while (1) - { - node = node->next; +#else + /* no synchronization applied since it's only for debug */ + rt_kprintf("%-*.*s %3d ", RT_NAME_MAX, RT_NAME_MAX, thread->parent.name, RT_SCHED_PRIV(thread).current_priority); +#endif /*RT_USING_SMP*/ + stat = (RT_SCHED_CTX(thread).stat & RT_THREAD_STAT_MASK); + if (stat == RT_THREAD_READY) rt_kprintf(" ready "); + else if ((stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK) rt_kprintf(" suspend"); + else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); + else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close "); + else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running"); - if (node == list) - { - node = (rt_list_t *)RT_NULL; - break; - } - nr++; - *array++ = node; - if (nr == arg->nr) - { - break; - } - } +#if defined(ARCH_CPU_STACK_GROWS_UPWARD) + ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1; + while (*ptr == '#')ptr --; + + rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", + ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr), + thread->stack_size, + ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size, + thread->remaining_tick, + rt_strerror(thread->error), + thread); +#else + ptr = (rt_uint8_t *)thread->stack_addr; + while (*ptr == '#') ptr ++; + rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", + thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp), + thread->stack_size, + (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100 + / thread->stack_size, + RT_SCHED_PRIV(thread).remaining_tick, + rt_strerror(thread->error), + thread); +#endif - rt_spin_unlock_irqrestore(&info->spinlock, level); - arg->nr_out = nr; - return node; + return RT_EOK; } long list_thread(void) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; const char *item_title = "thread"; const size_t tcb_strlen = sizeof(void *) * 2 + 2; int maxlen; - list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - maxlen = RT_NAME_MAX; #ifdef RT_USING_SMP @@ -188,635 +149,375 @@ long list_thread(void) rt_kprintf("\n"); #endif /*RT_USING_SMP*/ - 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_spin_lock_irqsave(&info->spinlock); - - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - /* copy info */ - rt_memcpy(&thread_info, obj, sizeof thread_info); - rt_spin_unlock_irqrestore(&info->spinlock, level); - - thread = (struct rt_thread *)obj; - { - rt_uint8_t stat; - rt_uint8_t *ptr; + rt_object_for_each_safe(RT_Object_Class_Thread, thread_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); -#ifdef RT_USING_SMP - /* no synchronization applied since it's only for debug */ - if (RT_SCHED_CTX(thread).oncpu != RT_CPU_DETACHED) - rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, - thread->parent.name, RT_SCHED_CTX(thread).oncpu, - RT_SCHED_CTX(thread).bind_cpu, - RT_SCHED_PRIV(thread).current_priority); - else - rt_kprintf("%-*.*s N/A %3d %4d ", maxlen, RT_NAME_MAX, - thread->parent.name, - RT_SCHED_CTX(thread).bind_cpu, - RT_SCHED_PRIV(thread).current_priority); + return 0; +} -#else - /* no synchronization applied since it's only for debug */ - rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->parent.name, RT_SCHED_PRIV(thread).current_priority); -#endif /*RT_USING_SMP*/ - stat = (RT_SCHED_CTX(thread).stat & RT_THREAD_STAT_MASK); - if (stat == RT_THREAD_READY) rt_kprintf(" ready "); - else if ((stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK) rt_kprintf(" suspend"); - else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); - else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close "); - else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running"); +#ifdef RT_USING_SEMAPHORE +static rt_err_t sem_print_(rt_object_t object, void *data) +{ + RT_UNUSED(data); -#if defined(ARCH_CPU_STACK_GROWS_UPWARD) - ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1; - while (*ptr == '#')ptr --; - - rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", - ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr), - thread->stack_size, - ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size, - thread->remaining_tick, - rt_strerror(thread->error), - thread); -#else - ptr = (rt_uint8_t *)thread->stack_addr; - while (*ptr == '#') ptr ++; - rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", - thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp), - thread->stack_size, - (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100 - / thread->stack_size, - RT_SCHED_PRIV(thread).remaining_tick, - rt_strerror(thread->error), - thread); -#endif - } - } - } + struct rt_semaphore *sem = (struct rt_semaphore *)object; + + if (!rt_list_isempty(&sem->parent.suspend_thread)) + { + rt_kprintf("%-*.*s %03d %d:", + RT_NAME_MAX, RT_NAME_MAX, + sem->parent.parent.name, + sem->value, + rt_list_len(&sem->parent.suspend_thread)); + rt_susp_list_print(&(sem->parent.suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s %03d %d\n", + RT_NAME_MAX, RT_NAME_MAX, + sem->parent.parent.name, + sem->value, + rt_list_len(&sem->parent.suspend_thread)); } - while (next != (rt_list_t *)RT_NULL); - return 0; + return RT_EOK; } -#ifdef RT_USING_SEMAPHORE long list_sem(void) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; - + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; int maxlen; const char *item_title = "semaphore"; - - list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s v suspend thread\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" --- --------------\n"); - 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_semaphore *sem; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - rt_spin_unlock_irqrestore(&info->spinlock, level); - - sem = (struct rt_semaphore *)obj; - if (!rt_list_isempty(&sem->parent.suspend_thread)) - { - rt_kprintf("%-*.*s %03d %d:", - maxlen, RT_NAME_MAX, - sem->parent.parent.name, - sem->value, - rt_list_len(&sem->parent.suspend_thread)); - rt_susp_list_print(&(sem->parent.suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s %03d %d\n", - maxlen, RT_NAME_MAX, - sem->parent.parent.name, - sem->value, - rt_list_len(&sem->parent.suspend_thread)); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_Semaphore, sem_print_, RT_NULL, obj_list, sizeof(obj_list)/sizeof(obj_list[0])); return 0; } #endif /* RT_USING_SEMAPHORE */ #ifdef RT_USING_EVENT -long list_event(void) +static rt_err_t event_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); + + struct rt_event *event = (struct rt_event *)object; + if (!rt_list_isempty(&event->parent.suspend_thread)) + { + rt_kprintf("%-*.*s 0x%08x %03d:", + RT_NAME_MAX, RT_NAME_MAX, + event->parent.parent.name, + event->set, + rt_list_len(&event->parent.suspend_thread)); + rt_susp_list_print(&(event->parent.suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s 0x%08x 0\n", + RT_NAME_MAX, RT_NAME_MAX, event->parent.parent.name, event->set); + } + + return RT_EOK; +} + +long list_event(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; int maxlen; const char *item_title = "event"; - list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s set suspend thread\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---------- --------------\n"); - 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_event *e; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - e = (struct rt_event *)obj; - if (!rt_list_isempty(&e->parent.suspend_thread)) - { - rt_kprintf("%-*.*s 0x%08x %03d:", - maxlen, RT_NAME_MAX, - e->parent.parent.name, - e->set, - rt_list_len(&e->parent.suspend_thread)); - rt_susp_list_print(&(e->parent.suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s 0x%08x 0\n", - maxlen, RT_NAME_MAX, e->parent.parent.name, e->set); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_Event, event_print_, RT_NULL, obj_list, sizeof(obj_list)/sizeof(obj_list[0])); return 0; } #endif /* RT_USING_EVENT */ #ifdef RT_USING_MUTEX -long list_mutex(void) +static rt_err_t mutex_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); - int maxlen; - const char *item_title = "mutex"; + struct rt_mutex *mutex = (struct rt_mutex *)object; - list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + if (!rt_list_isempty(&mutex->parent.suspend_thread)) + { + rt_kprintf("%-*.*s %-8.*s %04d %8d %04d ", + RT_NAME_MAX, RT_NAME_MAX, + mutex->parent.parent.name, + RT_NAME_MAX, + (mutex->owner == RT_NULL) ? "(null)" : mutex->owner->parent.name, + mutex->hold, + mutex->priority, + rt_list_len(&mutex->parent.suspend_thread)); + rt_susp_list_print(&(mutex->parent.suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s %-8.*s %04d %8d %04d\n", + RT_NAME_MAX, RT_NAME_MAX, + mutex->parent.parent.name, + RT_NAME_MAX, + (mutex->owner == RT_NULL) ? "(null)" : mutex->owner->parent.name, + mutex->hold, + mutex->priority, + rt_list_len(&mutex->parent.suspend_thread)); + } + return RT_EOK; +} + +long list_mutex(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "mutex"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s owner hold priority suspend thread \n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" -------- ---- -------- --------------\n"); - 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_mutex *m; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - m = (struct rt_mutex *)obj; - if (!rt_list_isempty(&m->parent.suspend_thread)) - { - rt_kprintf("%-*.*s %-8.*s %04d %8d %04d ", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - RT_NAME_MAX, - (m->owner == RT_NULL) ? "(null)" : m->owner->parent.name, - m->hold, - m->priority, - rt_list_len(&m->parent.suspend_thread)); - rt_susp_list_print(&(m->parent.suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s %-8.*s %04d %8d %04d\n", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - RT_NAME_MAX, - (m->owner == RT_NULL) ? "(null)" : m->owner->parent.name, - m->hold, - m->priority, - rt_list_len(&m->parent.suspend_thread)); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_Mutex, mutex_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } #endif /* RT_USING_MUTEX */ #ifdef RT_USING_MAILBOX -long list_mailbox(void) +static rt_err_t mailbox_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); - int maxlen; - const char *item_title = "mailbox"; + struct rt_mailbox *mailbox = (struct rt_mailbox *)object; - list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + if (!rt_list_isempty(&mailbox->parent.suspend_thread)) + { + rt_kprintf("%-*.*s %04d %04d %d:", + RT_NAME_MAX, RT_NAME_MAX, + mailbox->parent.parent.name, + mailbox->entry, + mailbox->size, + rt_list_len(&mailbox->parent.suspend_thread)); + rt_susp_list_print(&(mailbox->parent.suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s %04d %04d %d\n", + RT_NAME_MAX, RT_NAME_MAX, + mailbox->parent.parent.name, + mailbox->entry, + mailbox->size, + rt_list_len(&mailbox->parent.suspend_thread)); + } + return RT_EOK; +} + +long list_mailbox(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "mailbox"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s entry size suspend thread\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---- ---- --------------\n"); - 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_mailbox *m; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - m = (struct rt_mailbox *)obj; - if (!rt_list_isempty(&m->parent.suspend_thread)) - { - rt_kprintf("%-*.*s %04d %04d %d:", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - m->entry, - m->size, - rt_list_len(&m->parent.suspend_thread)); - rt_susp_list_print(&(m->parent.suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s %04d %04d %d\n", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - m->entry, - m->size, - rt_list_len(&m->parent.suspend_thread)); - } - - } - } - } - while (next != (rt_list_t *)RT_NULL); + rt_object_for_each_safe(RT_Object_Class_MailBox, mailbox_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } #endif /* RT_USING_MAILBOX */ #ifdef RT_USING_MESSAGEQUEUE -long list_msgqueue(void) +static rt_err_t msqueue_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); - int maxlen; - const char *item_title = "msgqueue"; + struct rt_messagequeue *msgqueue = (struct rt_messagequeue *)object; + + if (!rt_list_isempty(&msgqueue->parent.suspend_thread)) + { + rt_kprintf("%-*.*s %04d %d:", + RT_NAME_MAX, RT_NAME_MAX, + msgqueue->parent.parent.name, + msgqueue->entry, + rt_list_len(&msgqueue->parent.suspend_thread)); + rt_susp_list_print(&(msgqueue->parent.suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s %04d %d\n", + RT_NAME_MAX, RT_NAME_MAX, + msgqueue->parent.parent.name, + msgqueue->entry, + rt_list_len(&msgqueue->parent.suspend_thread)); + } - list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + return RT_EOK; +} +long list_msgqueue(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "msgqueue"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s entry suspend thread\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---- --------------\n"); - 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_messagequeue *m; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - m = (struct rt_messagequeue *)obj; - if (!rt_list_isempty(&m->parent.suspend_thread)) - { - rt_kprintf("%-*.*s %04d %d:", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - m->entry, - rt_list_len(&m->parent.suspend_thread)); - rt_susp_list_print(&(m->parent.suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s %04d %d\n", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - m->entry, - rt_list_len(&m->parent.suspend_thread)); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + + rt_object_for_each_safe(RT_Object_Class_MessageQueue, msqueue_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } #endif /* RT_USING_MESSAGEQUEUE */ #ifdef RT_USING_MEMHEAP -long list_memheap(void) +static rt_err_t memheap_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); - int maxlen; - const char *item_title = "memheap"; + struct rt_memheap *memheap = (struct rt_memheap *)object; - list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + rt_kprintf("%-*.*s %-010d %-013d %-05d\n", + RT_NAME_MAX, RT_NAME_MAX, + memheap->parent.name, + memheap->pool_size, + memheap->max_used_size, + memheap->available_size); + return RT_EOK; +} + +long list_memheap(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "memheap"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s pool size max used size available size\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---------- ------------- --------------\n"); - 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_memheap *mh; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - mh = (struct rt_memheap *)obj; - - rt_kprintf("%-*.*s %-010d %-013d %-05d\n", - maxlen, RT_NAME_MAX, - mh->parent.name, - mh->pool_size, - mh->max_used_size, - mh->available_size); - - } - } - } - while (next != (rt_list_t *)RT_NULL); + + rt_object_for_each_safe(RT_Object_Class_MemHeap, memheap_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } #endif /* RT_USING_MEMHEAP */ #ifdef RT_USING_MEMPOOL -long list_mempool(void) +static rt_err_t mempool_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + int suspend_thread_count; + rt_list_t *node; - int maxlen; - const char *item_title = "mempool"; + RT_UNUSED(data); + + struct rt_mempool *mp = (struct rt_mempool *)object; - list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + suspend_thread_count = 0; + rt_list_for_each(node, &mp->suspend_thread) + { + suspend_thread_count++; + } + if (suspend_thread_count > 0) + { + rt_kprintf("%-*.*s %04d %04d %04d %d:", + RT_NAME_MAX, RT_NAME_MAX, + mp->parent.name, + mp->block_size, + mp->block_total_count, + mp->block_free_count, + suspend_thread_count); + rt_susp_list_print(&(mp->suspend_thread)); + rt_kprintf("\n"); + } + else + { + rt_kprintf("%-*.*s %04d %04d %04d %d\n", + RT_NAME_MAX, RT_NAME_MAX, + mp->parent.name, + mp->block_size, + mp->block_total_count, + mp->block_free_count, + suspend_thread_count); + } + + return RT_EOK; +} + +long list_mempool(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "mempool"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s block total free suspend thread\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---- ---- ---- --------------\n"); - 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_mempool *mp; - int suspend_thread_count; - rt_list_t *node; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - mp = (struct rt_mempool *)obj; - - suspend_thread_count = 0; - rt_list_for_each(node, &mp->suspend_thread) - { - suspend_thread_count++; - } - - if (suspend_thread_count > 0) - { - rt_kprintf("%-*.*s %04d %04d %04d %d:", - maxlen, RT_NAME_MAX, - mp->parent.name, - mp->block_size, - mp->block_total_count, - mp->block_free_count, - suspend_thread_count); - rt_susp_list_print(&(mp->suspend_thread)); - rt_kprintf("\n"); - } - else - { - rt_kprintf("%-*.*s %04d %04d %04d %d\n", - maxlen, RT_NAME_MAX, - mp->parent.name, - mp->block_size, - mp->block_total_count, - mp->block_free_count, - suspend_thread_count); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); + + rt_object_for_each_safe(RT_Object_Class_MemPool, mempool_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } #endif /* RT_USING_MEMPOOL */ -long list_timer(void) +static rt_err_t timer_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; + RT_UNUSED(data); - int maxlen; - const char *item_title = "timer"; + struct rt_timer *timer = (struct rt_timer *)object; + + rt_kprintf("%-*.*s 0x%08x 0x%08x ", + RT_NAME_MAX, RT_NAME_MAX, + timer->parent.name, + timer->init_tick, + timer->timeout_tick); + if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) + rt_kprintf("activated "); + else + rt_kprintf("deactivated "); + if (timer->parent.flag & RT_TIMER_FLAG_PERIODIC) + rt_kprintf("periodic\n"); + else + rt_kprintf("one shot\n"); - list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + return RT_EOK; +} +long list_timer(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "timer"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s periodic timeout activated mode\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" ---------- ---------- ----------- ---------\n"); - 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_timer *timer; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - timer = (struct rt_timer *)obj; - rt_kprintf("%-*.*s 0x%08x 0x%08x ", - maxlen, RT_NAME_MAX, - timer->parent.name, - timer->init_tick, - timer->timeout_tick); - if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) - rt_kprintf("activated "); - else - rt_kprintf("deactivated "); - if (timer->parent.flag & RT_TIMER_FLAG_PERIODIC) - rt_kprintf("periodic\n"); - else - rt_kprintf("one shot\n"); - - } - } - } - while (next != (rt_list_t *)RT_NULL); + + rt_object_for_each_safe(RT_Object_Class_Timer, timer_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); rt_kprintf("current tick:0x%08x\n", rt_tick_get()); @@ -859,63 +560,38 @@ static char *const device_type_str[RT_Device_Class_Unknown] = "Bus Device", }; -long list_device(void) +static rt_err_t device_print_(rt_object_t object, void *data) { - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; - const char *device_type; + RT_UNUSED(data); - int maxlen; - const char *item_title = "device"; + struct rt_device *device = (struct rt_device *)object; + const char *device_type = "Unknown"; + if (device->type < RT_Device_Class_Unknown && + device_type_str[device->type] != RT_NULL) + { + device_type = device_type_str[device->type]; + } + rt_kprintf("%-*.*s %-20s %-8d\n", + RT_NAME_MAX, RT_NAME_MAX, + device->parent.name, + device_type, + device->ref_count); - list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); + return RT_EOK; +} +long list_device(void) +{ + rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR]; + int maxlen; + const char *item_title = "device"; maxlen = RT_NAME_MAX; rt_kprintf("%-*.*s type ref count\n", maxlen, maxlen, item_title); object_split(maxlen); rt_kprintf(" -------------------- ----------\n"); - 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_device *device; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - device = (struct rt_device *)obj; - device_type = "Unknown"; - if (device->type < RT_Device_Class_Unknown && - device_type_str[device->type] != RT_NULL) - { - device_type = device_type_str[device->type]; - } - rt_kprintf("%-*.*s %-20s %-8d\n", - maxlen, RT_NAME_MAX, - device->parent.name, - device_type, - device->ref_count); - - } - } - } - while (next != (rt_list_t *)RT_NULL); + + rt_object_for_each_safe(RT_Object_Class_Device, device_print_, RT_NULL, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); return 0; } diff --git a/include/rtthread.h b/include/rtthread.h index d9b582ab1e2..8a7983e7f8a 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -76,6 +76,13 @@ rt_err_t rt_custom_object_destroy(rt_object_t obj); rt_bool_t rt_object_is_systemobject(rt_object_t object); rt_uint8_t rt_object_get_type(rt_object_t object); rt_err_t rt_object_for_each(rt_uint8_t type, rt_object_iter_t iter, void *data); + +#ifndef RT_LIST_FIND_OBJ_NR +#define RT_LIST_FIND_OBJ_NR 8 +#endif + +rt_err_t rt_object_for_each_safe(rt_uint8_t type, rt_object_iter_t iter, void *data, rt_list_t **buffer, rt_size_t buffer_num); + rt_object_t rt_object_find(const char *name, rt_uint8_t type); rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size); diff --git a/src/object.c b/src/object.c index f924f37bc9c..a45b948e4c8 100644 --- a/src/object.c +++ b/src/object.c @@ -674,6 +674,168 @@ rt_err_t rt_object_for_each(rt_uint8_t type, rt_object_iter_t iter, void *data) return RT_EOK; } +typedef struct +{ + rt_list_t *list; + rt_list_t **array; + rt_uint8_t type; + int nr; /* input: max nr, can't be 0 */ + int nr_out; /* out: got nr */ + struct rt_object_information *info; +} list_get_next_t; + +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((enum rt_object_class_type)type); + list = &info->object_list; + + p->info = info; + 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_base_t level; + rt_list_t *node, *list; + rt_list_t **array; + struct rt_object_information *info; + int nr; + + arg->nr_out = 0; + + if (!arg->nr || !arg->type) + { + return (rt_list_t *)RT_NULL; + } + + list = arg->list; + info = rt_list_entry(list, struct rt_object_information, object_list); + + if (!current) /* find first */ + { + node = list; + first_flag = 1; + } + else + { + node = current; + } + + level = rt_spin_lock_irqsave(&info->spinlock); + + 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_spin_unlock_irqrestore(&info->spinlock, 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_spin_unlock_irqrestore(&info->spinlock, level); + arg->nr_out = nr; + return node; +} + +static rt_err_t list_handle_result(list_get_next_t *find_arg, rt_object_iter_t iter, void *data) +{ + int i; + rt_base_t level; + rt_err_t result; + + for (i = 0; i < find_arg->nr_out; i++) + { + struct rt_object *obj; + + obj = rt_list_entry(find_arg->array[i], struct rt_object, list); + level = rt_spin_lock_irqsave(&find_arg->info->spinlock); + if ((obj->type & ~RT_Object_Class_Static) != find_arg->type) + { + rt_spin_unlock_irqrestore(&find_arg->info->spinlock, level); + continue; + } + + rt_spin_unlock_irqrestore(&find_arg->info->spinlock, level); + + result = iter(obj, data); + if (result != RT_EOK) + { + return result; + } + } + + return RT_EOK; +} + +/** + * @brief This function will iterate through each object from object with a buffer + * container. + * + * @param type is the type of object + * @param iter is the iterator + * @param data is the specified data passed to iterator + * @param buffer is the buffer to store the object pointers + * @param buffer_num is the size of the buffer + * + * @return RT_EOK on succeed, otherwise the error from `iter` + * + * @note this function shall not be invoked in interrupt status. + */ +rt_err_t rt_object_for_each_safe(rt_uint8_t type, rt_object_iter_t iter, void *data, rt_list_t **buffer, rt_size_t buffer_num) +{ + list_get_next_t find_arg; + rt_err_t result; + rt_list_t *next = (rt_list_t *)RT_NULL; + + /* which is invoke in interrupt status */ + RT_DEBUG_NOT_IN_INTERRUPT; + + list_find_init(&find_arg, type, buffer, buffer_num); + + do + { + next = list_get_next(next, &find_arg); + result = list_handle_result(&find_arg, iter, data); + if (result != RT_EOK) + { + return result; + } + } + while (next != (rt_list_t *)RT_NULL); + + return RT_EOK; +} + struct _obj_find_param { const char *match_name; From 3a928803ffbadb7915b301e0e926b8ae9e151d8f Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Tue, 12 Aug 2025 22:23:20 +0800 Subject: [PATCH 2/5] fix build --- components/dfs/dfs_v2/filesystems/procfs/proc_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c b/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c index 7bc0651c75d..a20e81cb5f7 100644 --- a/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c +++ b/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c @@ -99,7 +99,7 @@ static void save_info(struct device_show *dev, char *dev_name) } } -static rt_err_t list_device_hook_(rt_object_t *object, void *data) +static rt_err_t list_device_hook_(rt_object_t object, void *data) { struct device_show *dev = (struct device_show *)data; struct rt_device *device = (struct rt_device *)object; From 52ff277e8b76ed93ddcf3a7ce40ee127139d8282 Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Tue, 12 Aug 2025 22:29:07 +0800 Subject: [PATCH 3/5] fix build2 --- components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c b/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c index 624b6d5fc80..527a716bdae 100644 --- a/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c +++ b/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c @@ -37,6 +37,8 @@ static rt_err_t show_info_hook_(rt_object_t object, void *data) dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0, geometry.sector_count, device->parent.name); } + + return RT_EOK; } static int show_info(struct dfs_seq_file *seq) From b2dadba39c84ed231d397540fa980ced3af9b39f Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Tue, 12 Aug 2025 22:41:22 +0800 Subject: [PATCH 4/5] fix build3 --- components/finsh/cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index be8bcff05dd..e8107fa352d 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -76,12 +76,12 @@ static rt_err_t thread_print_(rt_object_t object, void *data) #ifdef RT_USING_SMP /* no synchronization applied since it's only for debug */ if (RT_SCHED_CTX(thread).oncpu != RT_CPU_DETACHED) - rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, + rt_kprintf("%-*.*s %3d %3d %4d ", RT_NAME_MAX, RT_NAME_MAX, thread->parent.name, RT_SCHED_CTX(thread).oncpu, RT_SCHED_CTX(thread).bind_cpu, RT_SCHED_PRIV(thread).current_priority); else - rt_kprintf("%-*.*s N/A %3d %4d ", maxlen, RT_NAME_MAX, + rt_kprintf("%-*.*s N/A %3d %4d ", RT_NAME_MAX, RT_NAME_MAX, thread->parent.name, RT_SCHED_CTX(thread).bind_cpu, RT_SCHED_PRIV(thread).current_priority); From c99913b416bdc8a7d67fe1d9dfc42860dd1c1bbe Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Wed, 13 Aug 2025 08:44:29 +0800 Subject: [PATCH 5/5] fix cppcheck --- tools/ci/cpp_check.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/ci/cpp_check.py b/tools/ci/cpp_check.py index 7f3ca5a4394..ad53db81e0c 100644 --- a/tools/ci/cpp_check.py +++ b/tools/ci/cpp_check.py @@ -62,6 +62,9 @@ def check(self): '-DRT_ASSERT(x)=', '-DRTM_EXPORT(x)=', '-Drt_list_for_each_entry(a,b,c)=a=(void*)b;', + '-DCMD_OPTIONS_STATEMENT(x)=', + '-DCMD_OPTIONS_NODE_START(x)=', + '-DCMD_OPTIONS_NODE(x,y,z)=', '-I include', '-I thread/components/finsh', # it's okay because CI will do the real compilation to check this