Skip to content

Commit 2b3c955

Browse files
committed
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 <[email protected]>
1 parent 715334f commit 2b3c955

File tree

5 files changed

+510
-898
lines changed

5 files changed

+510
-898
lines changed

components/dfs/dfs_v2/filesystems/procfs/proc_devices.c

Lines changed: 12 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
#include <rtthread.h>
2222
#include <string.h>
2323

24-
25-
#define LIST_FIND_OBJ_NR 8
26-
2724
struct device_show
2825
{
2926
char *buf;
@@ -32,97 +29,6 @@ struct device_show
3229
int index;
3330
};
3431

35-
typedef struct
36-
{
37-
rt_list_t *list;
38-
rt_list_t **array;
39-
rt_uint8_t type;
40-
int nr; /* input: max nr, can't be 0 */
41-
int nr_out; /* out: got nr */
42-
} list_get_next_t;
43-
44-
static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
45-
{
46-
struct rt_object_information *info;
47-
rt_list_t *list;
48-
49-
info = rt_object_get_information((enum rt_object_class_type)type);
50-
list = &info->object_list;
51-
52-
p->list = list;
53-
p->type = type;
54-
p->array = array;
55-
p->nr = nr;
56-
p->nr_out = 0;
57-
}
58-
59-
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
60-
{
61-
int first_flag = 0;
62-
rt_base_t level;
63-
rt_list_t *node, *list;
64-
rt_list_t **array;
65-
struct rt_object_information *info;
66-
int nr;
67-
68-
arg->nr_out = 0;
69-
70-
if (!arg->nr || !arg->type)
71-
{
72-
return (rt_list_t *)RT_NULL;
73-
}
74-
75-
list = arg->list;
76-
info = rt_list_entry(list, struct rt_object_information, object_list);
77-
78-
if (!current) /* find first */
79-
{
80-
node = list;
81-
first_flag = 1;
82-
}
83-
else
84-
{
85-
node = current;
86-
}
87-
88-
level = rt_spin_lock_irqsave(&info->spinlock);
89-
90-
if (!first_flag)
91-
{
92-
struct rt_object *obj;
93-
/* The node in the list? */
94-
obj = rt_list_entry(node, struct rt_object, list);
95-
if ((obj->type & ~RT_Object_Class_Static) != arg->type)
96-
{
97-
rt_spin_unlock_irqrestore(&info->spinlock, level);
98-
return (rt_list_t *)RT_NULL;
99-
}
100-
}
101-
102-
nr = 0;
103-
array = arg->array;
104-
while (1)
105-
{
106-
node = node->next;
107-
108-
if (node == list)
109-
{
110-
node = (rt_list_t *)RT_NULL;
111-
break;
112-
}
113-
nr++;
114-
*array++ = node;
115-
if (nr == arg->nr)
116-
{
117-
break;
118-
}
119-
}
120-
121-
rt_spin_unlock_irqrestore(&info->spinlock, level);
122-
arg->nr_out = nr;
123-
return node;
124-
}
125-
12632
static char *const device_type_str[RT_Device_Class_Unknown] =
12733
{
12834
"Character Device",
@@ -193,47 +99,24 @@ static void save_info(struct device_show *dev, char *dev_name)
19399
}
194100
}
195101

196-
static void list_device(struct device_show *dev)
102+
static rt_err_t list_device_hook_(rt_object_t *object, void *data)
197103
{
198-
rt_base_t level;
199-
list_get_next_t find_arg;
200-
struct rt_object_information *info;
201-
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
202-
rt_list_t *next = (rt_list_t *)RT_NULL;
104+
struct device_show *dev = (struct device_show *)data;
105+
struct rt_device *device = (struct rt_device *)object;
203106

204-
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
205-
info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
206-
207-
do
107+
if (device->type < RT_Device_Class_Unknown)
208108
{
209-
next = list_get_next(next, &find_arg);
210-
{
211-
int i;
212-
for (i = 0; i < find_arg.nr_out; i++)
213-
{
214-
struct rt_object *obj;
215-
struct rt_device *device;
216-
217-
obj = rt_list_entry(obj_list[i], struct rt_object, list);
218-
level = rt_spin_lock_irqsave(&info->spinlock);
219-
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
220-
{
221-
rt_spin_unlock_irqrestore(&info->spinlock, level);
222-
continue;
223-
}
109+
save_info(dev + device->type, device->parent.name);
110+
}
224111

225-
rt_spin_unlock_irqrestore(&info->spinlock, level);
112+
return RT_EOK;
113+
}
226114

227-
device = (struct rt_device *)obj;
115+
static void list_device(struct device_show *dev)
116+
{
117+
rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR];
228118

229-
if (device->type < RT_Device_Class_Unknown)
230-
{
231-
save_info(dev + device->type, device->parent.name);
232-
}
233-
}
234-
}
235-
}
236-
while (next != (rt_list_t *)RT_NULL);
119+
rt_object_for_each_safe(RT_Object_Class_Device, list_device_hook_, dev, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
237120
}
238121

239122
static int show_info(struct dfs_seq_file *seq)

components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c

Lines changed: 11 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -21,145 +21,29 @@
2121
#include <rtthread.h>
2222
#include <string.h>
2323

24-
25-
#define LIST_FIND_OBJ_NR 8
26-
27-
typedef struct
28-
{
29-
rt_list_t *list;
30-
rt_list_t **array;
31-
rt_uint8_t type;
32-
int nr; /* input: max nr, can't be 0 */
33-
int nr_out; /* out: got nr */
34-
} list_get_next_t;
35-
36-
static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
24+
static rt_err_t show_info_hook_(rt_object_t object, void *data)
3725
{
38-
struct rt_object_information *info;
39-
rt_list_t *list;
40-
41-
info = rt_object_get_information((enum rt_object_class_type)type);
42-
list = &info->object_list;
43-
44-
p->list = list;
45-
p->type = type;
46-
p->array = array;
47-
p->nr = nr;
48-
p->nr_out = 0;
49-
}
50-
51-
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
52-
{
53-
int first_flag = 0;
54-
rt_base_t level;
55-
rt_list_t *node, *list;
56-
rt_list_t **array;
57-
struct rt_object_information *info;
58-
int nr;
59-
60-
arg->nr_out = 0;
61-
62-
if (!arg->nr || !arg->type)
63-
{
64-
return (rt_list_t *)RT_NULL;
65-
}
26+
rt_device_t device;
27+
struct dfs_seq_file *seq = (struct dfs_seq_file *) data;
6628

67-
list = arg->list;
68-
info = rt_list_entry(list, struct rt_object_information, object_list);
29+
device = (struct rt_device *)object;
6930

70-
if (!current) /* find first */
71-
{
72-
node = list;
73-
first_flag = 1;
74-
}
75-
else
31+
if (device->type == RT_Device_Class_Block)
7632
{
77-
node = current;
78-
}
33+
struct rt_device_blk_geometry geometry = { 0 };
7934

80-
level = rt_spin_lock_irqsave(&info->spinlock);
35+
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
8136

82-
if (!first_flag)
83-
{
84-
struct rt_object *obj;
85-
/* The node in the list? */
86-
obj = rt_list_entry(node, struct rt_object, list);
87-
if ((obj->type & ~RT_Object_Class_Static) != arg->type)
88-
{
89-
rt_spin_unlock_irqrestore(&info->spinlock, level);
90-
return (rt_list_t *)RT_NULL;
91-
}
37+
dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0,
38+
geometry.sector_count, device->parent.name);
9239
}
93-
94-
nr = 0;
95-
array = arg->array;
96-
while (1)
97-
{
98-
node = node->next;
99-
100-
if (node == list)
101-
{
102-
node = (rt_list_t *)RT_NULL;
103-
break;
104-
}
105-
nr++;
106-
*array++ = node;
107-
if (nr == arg->nr)
108-
{
109-
break;
110-
}
111-
}
112-
113-
rt_spin_unlock_irqrestore(&info->spinlock, level);
114-
arg->nr_out = nr;
115-
return node;
11640
}
11741

11842
static int show_info(struct dfs_seq_file *seq)
11943
{
120-
rt_base_t level;
121-
list_get_next_t find_arg;
122-
struct rt_object_information *info;
123-
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
124-
rt_list_t *next = (rt_list_t *)RT_NULL;
44+
rt_list_t *obj_list[RT_LIST_FIND_OBJ_NR];
12545

126-
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
127-
info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
128-
129-
do
130-
{
131-
next = list_get_next(next, &find_arg);
132-
{
133-
int i;
134-
for (i = 0; i < find_arg.nr_out; i++)
135-
{
136-
struct rt_object *obj;
137-
struct rt_device *device;
138-
139-
obj = rt_list_entry(obj_list[i], struct rt_object, list);
140-
level = rt_spin_lock_irqsave(&info->spinlock);
141-
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
142-
{
143-
rt_spin_unlock_irqrestore(&info->spinlock, level);
144-
continue;
145-
}
146-
147-
rt_spin_unlock_irqrestore(&info->spinlock, level);
148-
149-
device = (struct rt_device *)obj;
150-
151-
if (device->type == RT_Device_Class_Block)
152-
{
153-
struct rt_device_blk_geometry geometry = { 0 };
154-
155-
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
156-
157-
dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0,
158-
geometry.sector_count, device->parent.name);
159-
}
160-
}
161-
}
162-
} while (next != (rt_list_t *)RT_NULL);
46+
rt_object_for_each_safe(RT_Object_Class_Device, show_info_hook_, seq, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
16347

16448
return 0;
16549
}

0 commit comments

Comments
 (0)