2. ハッシュをたどる

土曜, 2007-01-13 18:14 — Hiroshi Miura

ところで、pid_hash[][]からたどって、pid構造体を見つけても、タスク構造体のアドレスは容易に求めることができません。
なぜならば、pid構造体にはタスク構造体へのポインタはなく、単に埋め込まれているだけだからです。タスク構造体におけるpid構造体の位置を計算して、pid構造体のアドレスから計算すればよいということになります。

実際にやってみてください。

(gdb) p pid_hash
$1 = {0xc1403000, 0xc1405000, 0xc1407000, 0xc1409000}
(gdb) p pid_hash[0][0]
$2 = {first = 0xc0370384}

すぐにハッシュ値を求める必要が出てきました。
lxr.linux.noなどでpid_hashでカーネルソースを検索すると、

2.6.17では、

struct pid * fastcall find_pid(int nr)
{
struct hlist_node *elem;
struct pid *pid;

hlist_for_each_entry_rcu(pid, elem,
&pid_hash[pid_hashfn(nr)], pid_chain) {
if (pid->nr == nr)
return pid;
}
return NULL;
}

2.6.16では、

struct pid * fastcall find_pid(enum pid_type type, int nr)
{
struct hlist_node *elem;
struct pid *pid;

hlist_for_each_entry_rcu(pid, elem,
&pid_hash[type][pid_hashfn(nr)], pid_chain) {
if (pid->nr == nr)
return pid;
}
return NULL;
}

のようにpid番号からpid構造体を探す関数が見つかります。二つは、typeを引数に
取るかどうかが違いますが、遣っていることはほぼ一緒のようです。
2.6.17では、static struct hlist_head *pid_hash;と定義されているのに対して、
2.6.16では、static struct hlist_head *pid_hash[PIDTYPE_MAX];とtype別に
なっているようです。

さて、pid番号からタスク構造体を求める便利な関数はなんでしょうか。この見つかった
find_pidでさらに検索すると

2.6.16ではkernel/pid.cに

task_t *find_task_by_pid_type(int type, int nr)
{
struct pid *pid;

pid = find_pid(type, nr);
if (!pid)
return NULL;

return pid_task(&pid->pid_list, type);
}
EXPORT_SYMBOL(find_task_by_pid_type);

という関数があり、カーネル内部で自由に使えることが分かります。
やっと見つけたようです。


新しいコメントの投稿

  • Allowed HTML tags: <a> <p> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • 行と段落は自動的に分けます。

フォーマットのオプションに関する詳細情報

Firefox 2Get Thunderbird! Firefox 2 無料ダウンロード

Powered by Drupal, an open source content management system

ブックナビゲーション