無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

list_splice(リスト結合)(2)


list_splice(リスト結合)では、明示的なヘッダーを有するリストの結合でした。list_splice()で結合されるリストの引数は、リストから削除されます。下記のような有効なノードとするヘッダーのリストの結合はどうしたらいいでしょうか?
  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->


最終更新 2013/06/01 17:39:55 - north
(2013/06/01 17:39:55 作成)