list_splice(リスト結合)(2)
list_splice(リスト結合)では、明示的なヘッダーを有するリストの結合でした。list_splice()で結合されるリストの引数は、リストから削除されます。下記のような有効なノードとするヘッダーのリストの結合はどうしたらいいでしょうか?
サンプルです。ポイントはinit_module()でlist_add_tail()で、ダミーとしてのスタック変数上のjoinをlist 2のnode_head2の末尾に追加しています。追加する場所は、結合する任意のポイントに追加すればいいわけです。list_splice()の引数として、このjoinでもって結合する事で実現しています。
1 | 5 4 2 | 8 6 3 | 7この場合、結合するリストの結合位置にダミーのノード(head list)を追加して、それを引数にしてlist_splice()をコールする事で実現します。
サンプルです。ポイントはinit_module()でlist_add_tail()で、ダミーとしてのスタック変数上のjoinをlist 2のnode_head2の末尾に追加しています。追加する場所は、結合する任意のポイントに追加すればいいわけです。list_splice()の引数として、このjoinでもって結合する事で実現しています。
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
struct my_object {
struct list_head list;
int sec;
};
void disp_obj(int sel);
void init_node_head1(void);
void init_node_head2(void);
static struct my_object *node_head1;
static struct my_object *node_head2;
int init_module(void)
{
struct my_object *myobj1, *myobj2;
struct list_head join;
int i;
init_node_head1();
for (i = 2; i <= 10; ++i) {
myobj1 = (struct my_object *)kmalloc(sizeof(struct my_object), GFP_KERNEL);
myobj1->sec = i;
list_add_tail(&myobj1->list, &node_head1->list);
}
init_node_head2();
for (i = 12; i <= 20; ++i) {
myobj2 = (struct my_object *)kmalloc(sizeof(struct my_object), GFP_KERNEL);
myobj2->sec = i;
list_add_tail(&myobj2->list, &node_head2->list);
}
disp_obj(1);
list_add_tail(&join, &node_head2->list);
list_splice(&join, node_head1->list.prev);
disp_obj(0);
return 0;
}
void disp_obj(int sel)
{
struct list_head *p;
struct my_object *myobj;
char entry[256], tmp[6];
entry[0] = 0;
printk("list 1\n");
sprintf(tmp, "%2d->", node_head1->sec);
strcat(entry, tmp);
list_for_each(p, &node_head1->list) {
myobj = list_entry(p, struct my_object, list);
sprintf(tmp, "%2d->", myobj->sec);
strcat(entry, tmp);
}
strcat(entry, "\n");
printk(entry);
if (sel == 1) {
entry[0] = 0;
printk("list 2\n");
sprintf(tmp, "%2d->", node_head2->sec);
strcat(entry, tmp);
list_for_each(p, &node_head2->list) {
myobj = list_entry(p, struct my_object, list);
sprintf(tmp, "%d->", myobj->sec);
strcat(entry, tmp);
}
strcat(entry, "\n");
printk(entry);
}
}
void init_node_head1(void)
{
node_head1 = (struct my_object *)kmalloc(sizeof(struct my_object), GFP_KERNEL);
INIT_LIST_HEAD(&node_head1->list);
node_head1->sec = 1;
}
void init_node_head2(void)
{
node_head2 = (struct my_object *)kmalloc(sizeof(struct my_object), GFP_KERNEL);
INIT_LIST_HEAD(&node_head2->list);
node_head2->sec = 11;
}
void cleanup_module(void)
{
struct my_object *myobj;
while(!list_empty(&node_head1->list)) {
myobj = list_entry(node_head1->list.next, struct my_object, list);
list_del(&myobj->list);
kfree(myobj);
}
kfree(node_head1);
}
結果[root@localhost lkm]# dmesg : : [63358.105255] list 1 [63358.105255] 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9->10-> [63358.105255] list 2 [63358.105721] 11->12->13->14->15->16->17->18->19->20-> [63358.105728] list 1 [63358.105748] 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9->10->11->12->13->14->15->16->17->18->19->20->





