またスケジューラを見てます。
__NR_sched_setaffinity @ unistd_32.hsys_call_table
sys_sched_setaffinity @ syscalls_32.Scompat_sys_sched_setaffinity @ ia32entry.S
compat_sys_sched_setaffinity @ compat.c
SYSCALL_DEFINE3(sched_setaffinity...) @ sched.c
sched_setaffinity() @ sched.c
→ここでマスクを設定
マスクは、以下の説明を見ればわかるかもしれません。
Manpage of SCHED_SETAFFINITY
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/sched_setaffinity.2.html
で、設定されたマスクは"どこかで実際にCPU切り替えに使われる"わけですが、CPUに"実行中CPU IDレジスタ"や、メモリ上に"スレッド-CPU割り付けテーブル"のようなものがあるわけではないわけです。
で最終的に所望のCPUのTSS(タスク・ステート・セグメント)を更新すればOKなわけです。
タスクってなんじゃ?と思う人もいるかもしれませんが、80286以降でCPU自体が「タスクスイッチングに対応」していますので、各種OSはそれに乗っかる形でスレッドやプロセスを実装しているに過ぎません。
もちろん、UNIX由来のプロセスの仕組みとx86のタスク制御がお互いに必要十分な関係ではないので、いろいろトリックを必要とするのは当然のことです。
組み込みの人なら、簡単なタスクスイッチルーチンくらい書いたことがあるかもしれませんが、x86のタスク制御ならスタックの入れ替えくらいまでは自動でやってくれると言えばわかるでしょうか。
たとえばx86で簡単なOSモドキを書くなら、一から書いても大変ではないでしょう。仮想メモリを使わずに固定アドレスで動作するシステムならページ例外などを考えなくてよいので、もっとシンプルです。そのようなシステムが組み込みでは多数使われていた/いると思います。
古いx86を触っていた人間にLinuxの実装を見せると、
ちんたらマイ構造体ばっかり見せてんじゃねぇよ。
さっさとGDT触ってるところ見せろよ。
という感想が出るのではないでしょうか。
混乱の源泉は、LinuxがUNIXのローカルな実装であり、UNIXはx86向けに設計されたものではないこと。またLinuxの最初の実装は386向けに書かれたものであり、x86寄りの部分があったのではないかということ。さらにLinuxが他アーキテクチャに移植されるにつれてりファクタリングして本質が見えない実装になっていたこと。などが考えられると思います。
# 「386向け」以外は勝手な推測なので真に受けないようお願いします。
リンク:
プロセッサー・アフィニティーの管理
http://www.ibm.com/developerworks/jp/linux/library/l-affinity/
↑↑↑この説明では、sched_set_affinityというアンダーバーが多い名前が出てきますが、これは古いシステムコールのようです。ようわかりませんな。
LinuxKernelHackJAPAN
http://hira-consulting.com/wiki/index.php?load_TLS%28%29%2Flinux2.6
↑↑↑しばらく、サイトが見れたり見れなかったりしたのですが、正式に再スタートしたんでしょうかね。
手元の『80x86・80x87ファミリーテクニカルハンドブック』も参考にしました。
コメント