Skip to content

proposal & refactor: reuse list_find* related logic by adding rt_object_for_each_safe #10605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 12 additions & 129 deletions components/dfs/dfs_v2/filesystems/procfs/proc_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
#include <rtthread.h>
#include <string.h>


#define LIST_FIND_OBJ_NR 8

struct device_show
{
char *buf;
Expand All @@ -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",
Expand Down Expand Up @@ -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)
Expand Down
138 changes: 12 additions & 126 deletions components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,145 +21,31 @@
#include <rtthread.h>
#include <string.h>


#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;
rt_device_t device;
struct dfs_seq_file *seq = (struct dfs_seq_file *) data;

info = rt_object_get_information((enum rt_object_class_type)type);
list = &info->object_list;
device = (struct rt_device *)object;

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)
if (device->type == RT_Device_Class_Block)
{
return (rt_list_t *)RT_NULL;
}
struct rt_device_blk_geometry geometry = { 0 };

list = arg->list;
info = rt_list_entry(list, struct rt_object_information, object_list);
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);

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;
}
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;
return RT_EOK;
}

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;
}
Expand Down
Loading