<!--Chapter 11 Kernel Mechanisms-->
<sect>カーネルメカニズム<label id="chapter_km">
<p>
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/penguin2.gif">
</figure>

<!--
This chapter describes some of the general tasks and mechanisms that the
Linux kernel needs to supply so that other parts of the kernel work
effectively together. 
-->
<p>この章では、Linux カーネルが提供しなければならない汎用的なタスクとメカニズム
のいくつかについて解説する。それらは、カーネルの他の部分(すなわちこの章で述べら
れるいくつかのタスクやメカニズム以外の部分)が効率よく協調動作するために必要なも
のである。

<!--11.1  Bottom Half Handling-->
<sect1>ボトムハーフハンドラ<label id="chapter_km_sect1">
<p>

<!--          Figure 11.1: Bottom Half Handling Data Structures-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure11-1.gif">
</figure>
</#if>
<#unless output="html">
<verb>

          bh_active
31                            0          bh_base
+-----------------------------+     +---------------+
|                             |   0 |               |-->ボトムハーフ
|                             |     |---------------|   ハンドラ
+-----------------------------+     |               |   (timers)
                                    |---------------|
           bh_mask                  |               |
31                            0     |               |
+-----------------------------+     |               |
|                             |     |               |
|                             |     |               |
+-----------------------------+     |               |
                                    |               |
                                    |               |
                                    |---------------|
                                    |               |
                                    |---------------|
                                 31 |               |
                                    +---------------+
</verb>
</#if>
<p>図表(11.1) ボトムハーフハンドラのデータ構造

<!--
There are often times in a kernel when you do not want to do work at this
moment. A good example of this is during interrupt processing. When the
interrupt was asserted, the processor stopped what it was doing and the
operating system delivered the interrupt to the appropriate device driver.
Device drivers should not spend too much time handling interrupts as, during
this time, nothing else in the system can run. There is often some work that
could just as well be done later on. Linux's bottom half handlers were
invented so that device drivers and other parts of the Linux kernel could
queue work to be done later on. Figure  11.1 shows the kernel data
structures associated with bottom half handling. 
-->
<p>カーネルにタスク処理をさせる場合、この時点では処理をさせたくない、という時が
しばしばある。割り込みを処理させる場合は、特にそうである。割り込みが起こると、
プロセッサは実行中の処理を停止し、オペレーティングシステムがその割り込みを適切
なデバイスドライバに伝達する。しかし、デバイスドライバに割り込みを処理させる
場合、割り込み処理中には、システム上で他の処理を実行できない。したがって、デバ
イスドライバは、割り込みの処理にあまり時間を掛けてはいけない。他方、その場で直
ぐに処理せずとも、何の問題もないケースもしばしば存在する。Linux のボトムハーフ
ハンドラが発明されたのは、デバイスドライバやその他のカーネルルーチンがそうした
仕事を一旦キュー上に置いて、あとで処理できるようにするためである。図表(11.1)で
は、ボトムハーフハンドラに関するカーネルのデータ構造体が示されている。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/interrupt.h" 
name="include/linux/interrupt.h">]<newline>

<!--
There can be up to 32 different bottom half handlers; bh_base is a vector of
pointers to each of the kernel's bottom half handling routines. bh_active
and bh_mask have their bits set according to what handlers have been
installed and are active. If bit N of bh_mask is set then the Nth element of
bh_base contains the address of a bottom half routine. If bit N of
bh_active is set then the N'th bottom half handler routine should be
called as soon as the scheduler deems reasonable. These indices are
statically defined; the timer bottom half handler is the highest priority 
(index 0), the console bottom half handler is next in priority (index 1) and 
so on. Typically the bottom half handling routines have lists of tasks 
associated with them. For example, the immediate bottom half handler works 
its way through the immediate tasks queue (tq_immediate) which contains tasks
that need to be performed immediately. 
-->
<p>32 個までの異なるボトムハーフハンドラが存在し得る。
<tt><htmlurl url="./The-Linux-Kernel-images/linux/include/linux/interrupt.h" 
name="bh_base"></tt> は、
カーネルの個々のボトムハーフ処理ルーチンへのポインタのテーブルである。<tt>
bh_active</tt> と <tt>bh_mask</tt> は独自のビットセットを持っていて、その値
はどのようなハンドラがインストールされてアクティブになっているのかによる。
<tt>bh_mask</tt> にビット N がセットされた場合、<tt>bh_base</tt> の N 番目の
要素がそのボトムハーフハンドラのアドレスを含んでいる。<tt>bh_active</tt> に
ビット N がセットされた場合、スケジューラが合理的と考えた直後に N 番目の
ボトムハーフハンドラルーチンが呼び出される。それらのインデックスは静的に
定義されている。タイマー(timer)ボトムハーフハンドラは最優先であり(index 0)、
コンソール(console)ボトムハーフハンドラはそれに次ぐ優先度を持つ(index 1)等
である。
典型的には、ボトムハーフハンドラはそれらと関連したタスクのリストを持っている。
たとえば、イミディエート(immediate)ボトムハーフハンドラはイミディエートタスク
キュー(<tt><htmlurl url="./The-Linux-Kernel-images/linux/kernel/sched.c" 
name="tq_immediate"></tt>)
を通じて処理を行うが、そのキューには即座に(immediately)処理される必要のある
タスクが含まれる。

<!--
Some of the kernel's bottom half handers are device specific, but others are
more generic: 
-->
<p>カーネルのボトムハーフハンドラのいくつかは、デバイス固有のものであるが、
それ以外は汎用的である。

<!--
TIMER
      This handler is marked as active each time the system's periodic
      timer interrupts and is used to drive the kernel's timer queue
      mechanisms, 
CONSOLE
      This handler is used to process console messages, 
TQUEUE
      This handler is used to process tty messages, 
NET This handler handles general network processing, 
IMMEDIATE
      This is a generic handler used by several device drivers to queue
      work to be done later. 
-->
<descrip>
<tag>TIMER</tag>
このハンドラは、システムの定時的なタイマーが割り込むときに、いつもアクティブと
マークされ、カーネルのタイマーキューメカニズムを駆動するために使用される。

<tag>CONSOLE</tag>
このハンドラは、コンソールメッセージを処理するために使用される。

<tag>TQUEUE</tag>
このハンドラは、<tt>tty</tt> メッセージを処理するために使用される。

<tag>NET</tag>
このハンドラは、一般的なネットワーク処理をこなす。

<tag>IMMEDIATE</tag>
これは汎用ハンドラであり、いくつかのデバイスドライバが後で行おうとする仕事を
キューに入れるために使用される。
</descrip>

<!--
Whenever a device driver, or some other part of the kernel, needs to
schedule work to be done later, it adds work to the appropriate system
queue, for example the timer queue, and then signals the kernel that some
bottom half handling needs to be done. It does this by setting the appropriate
bit in bh_active. Bit 8 is set if the driver has queued something on the
immediate queue and wishes the immediate bottom half handler to run and
process it. The bh_active bitmask is checked at the end of each system
call, just before control is returned to the calling process. If it has any 
bits set, the bottom half handler routines that are active are called. Bit 0 is
checked first, then 1 and so on until bit 31. 
The bit in bh_active is cleared as each bottom half handling routine is
called. bh_active is transient; it only has meaning between calls to the
scheduler and is a way of not calling bottom half handling routines when
there is no work for them to do. 
-->
<p>デバイスドライバやカーネルの他の部分が仕事を後回しにする必要があるときは
いつも、その仕事を、たとえばタイマーキューのような、適切なキューに置き、
カーネルにシグナルを送って、ボトムハーフ処理の実行が必要であることを伝える。
それをするには、<tt><htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/interrupt.h" 
name="bh_active"></tt> の適切なビットを設定すればよい。
たとえば、ビット 8 が設定されるのは、ドライバが何かをイミディエートキュー上に
置いて、ボトムハーフハンドラが実行されて処理されるのを望む場合である。
<tt>bh_active</tt> のビットマスクがチェックされるのは、個々のシステムコールの
終了時であり、制御が呼び出しプロセスに戻る直前である。
何らかのビットがセットされていた場合、アクティブなボトムハーフハンドラが
呼び出される。ビット 0 がまず最初にチェックされて、次に 1 へと順次進んで、
31 までチェックされる。
<newline>[see: do_bottom_half(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/kernel/softirq.c" 
name="kernel/softirq.c">]<newline>
<tt>bh_active</tt> のビットは、個々のボトムハーフハンドラが呼び出されるたびに
クリアされる。すなわち、<tt>bh_active</tt> は一時的なもので、スケジューラが
呼び出されたその時点では意味を持つが、次の呼び出しがなされる際には意味を持たな
い。したがって、この方法を使えば、処理すべき仕事がない場合、ボトムハーフ処理
ルーチンは呼び出されない。

<!--11.2  Task Queues-->
<sect1>タスクキュー(task queue)<label id="chapter_km_sect2">
<p>


<!--                  Figure 11.2: A Task Queue-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure11-2.gif">
</figure>
</#if>
<#unless output="html">
<verb>
                tq_struct               tq_struct
task_quequ   +-------------+         +-------------+
------------>| next        |-------->| next        |-------->
             |-------------|         |-------------|
             | sync        |         | sync        |
             |-------------|         |-------------|
             | *routine()  |         | *routine()  |
             |-------------|         |-------------|
             | *data       |         | *data       |
             +-------------+         +-------------+
</verb>
</#if>
<p>図表(11.2) タスクキュー

<!--
Task queues are the kernel's way of deferring work until later. Linux has a
generic mechanism for queuing work on queues and for processing them
later. Task queues are often used in conjunction with bottom half handlers; the
timer task queue is processed when the timer queue bottom half handler
runs. A task queue is a simple data structure, see figure  11.2 which
consists of a singly linked list of tq_struct data structures each of which
contains the address of a routine and a pointer to some data. 
The routine will be called when the element on the task queue is processed
and it will be passed a pointer to the data. 
-->
<p>タスクキューは、カーネルが仕事を後回しにする方法である。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/tqueue.h" 
name="include/linux/tqueue.h">]<newline>
Linux には、仕事をキュー上に置いて、後で処理をする汎用的なメカニズムがある。
タスクキューはしばしばボトムハーフハンドラと一緒に使用される。タイマータスク
キュー(timer task queue)は、タイマーキューボトムハーフハンドラ(timer queue 
bottom half handler)が実行されるときに処理される。
タスクキューはシンプルなデータ構造体であり、図表(11.2)に示されるように、<tt>
<ref id="tq_struct" name="tq_struct"></tt> データ構造体の単純な連結リストであ
る。その個々の構造体には、ルーチンのアドレスとデータへのポインタが含まれてい
る。タスクキュー上の要素が処理されるとき、ルーチンが呼び出され、その際、ルーチ
ンへはデータへのポインタが渡される。

<!--
Anything in the kernel, for example a device driver, can create and use task
queues but there are three task queues created and managed by the kernel: 
-->
<p>カーネル内の何らかのルーチン、たとえばデバイスドライバは、タスクキューを
作成し利用することができるが、次の 3 つのタスクキューは、カーネルによって
作成され管理されている。

<!--
timer This queue is used to queue work that will be done as soon after the
      next system clock tick as is possible. Each clock tick, this queue is
      checked to see if it contains any entries and, if it does, the timer
      queue bottom half handler is made active. The timer queue bottom
      half handler is processed, along with all the other bottom half
      handlers, when the scheduler next runs. This queue should not be
      confused with system timers, which are a much more sophisticated
      mechanism. 
-->
<descrip>
<tag>timer</tag>
このキューは、次のシステムクロックティック(clock tick)の出来るだけ直後に実行さ
れるべき仕事をキューイングするために使用される。
クロックティックごとにこのキューがチェックされ、エントリが含まれているかどうか
確認される。エントリが含まれていた場合、タイマーキューボトムハーフハンドラが
アクティブにされる。
スケジューラが次に実行される時には、タイマーキューボトムハーフハンドラが、
その他すべてのボトムハーフハンドラと伴に処理される。
このキューとシステムタイマーを混同してはいけない。後者は、ずっと洗練された
メカニズムを持っている。

<!--
immediate
      This queue is also processed when the scheduler processes the
      active bottom half handlers. The immediate bottom half handler is
      not as high in priority as the timer queue bottom half handler and so
      these tasks will be run later. 
-->
<tag>immediate</tag>
このキューも、スケジューラがアクティブなボトムハーフハンドラを処理するときに
処理される。イミディエート(immediate)ボトムハーフハンドラは、タイマーキュー
ボトムハーフハンドラほど優先順位は高くないので、これらのタスクは後から実行
される。

<!--
scheduler
      This task queue is processed directly by the scheduler. It is used to
      support other task queues in the system and, in this case, the task
      to be run will be a routine that processes a task queue, say for a
      device driver. 
-->
<tag>scheduler</tag>
このタスクキューは、スケジューラ自身によって処理される。これは、システム上の
他のタスクキューをサポートするために使用されるので、この場合、実行されるべき
タスクは、タスクキューを処理するルーチン、たとえば、デバイスドライバである。
</descrip>

<!--
When task queues are processed, the pointer to the first element in the
queue is removed from the queue and replaced with a null pointer. In fact,
this removal is an atomic operation, one that cannot be interrupted. Then
each element in the queue has its handling routine called in turn. The
elements in the queue are often statically allocated data. However there is
no inherent mechanism for discarding allocated memory. The task queue
processing routine simply moves onto the next element in the list. It is the
job of the task itself to ensure that it properly cleans up any allocated 
kernel memory. 
-->
<p>タスクキューが処理されるとき、キューの最初の要素に対するポインタがキュー
から削除されて、ヌルポインタ(null pointer)と置き換えられる。実際、この削除
処理は、排他的な操作(atomic operation)なので、割り込みできないように
なっている。次に、キュー上の個々の要素が自分の処理ルーチンを順番に呼び出す。
キュー上の要素はしばしば静的に割り当てられたデータである。しかし、割り当て
られたメモリを破棄する固有のメカニズムは存在しない。タスクキュー処理ルーチン
は単にリスト上の次の要素の処理に移るだけである。割り当てられたカーネルメモリ
を確実に適宜再利用可能にするためには、タスク自体がその処理をしなければならな
い。

<!--11.3  Timers-->
<sect1>タイマー(timer)<label id="chapter_km_sect3">
<p>

<label id="figure11-3">
<!--                  Figure 11.3: System Timers-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure11-3.gif">
</figure>
</#if>
<#unless output="html">
<verb>
     timer_table           timer_struct
   +-------------+         +-----------+
 0 |             |-------->| expires   |
   |-------------|         |-----------|
   |             |         | *fn()     |
   |-------------|         +-----------+
   |             |
   |             |         timer_struct
   |-------------|         +-----------+
   |             |-------->| expires   |
   |-------------|         |-----------|
   |             |         | *fn()     |
   |             |         +-----------+
   |-------------|
   |             |     31       timer_active             0
   |-------------|     +----------------------------------+
31 |             |     |                                  |
   +-------------+     +----------------------------------+


     timer_head              timer_head              timer_head
   +--------------+        +--------------+        +--------------+
   | next         |------->| next         |------->| next         |
   |--------------|        |--------------|        |--------------|
   | prev         |<-------| prev         |<-------| prev         |
   |--------------|        |--------------|        |--------------|
   | expires      |        | expires      |        | expires      |
   |--------------|        |--------------|        |--------------|
   | data         |        | data         |        | data         |
   |--------------|        |--------------|        |--------------|
   | *function()  |        | *function()  |        | *function()  |
   +--------------+        +--------------+        +--------------+
</verb>
</#if>
<p>図表(11.3) システムタイマー

<!--
An operating system needs to be able to schedule an activity sometime in
the future. A mechanism is needed whereby activities can be scheduled to
run at some relatively precise time. Any microprocessor that wishes to
support an operating system must have a programmable interval timer that
periodically interrupts the processor. This periodic interrupt is known as a
system clock tick and it acts like a metronome, orchestrating the system's
activities. 
Linux has a very simple view of what time it is; it measures time in clock
ticks since the system booted. All system times are based on this
measurement, which is known as jiffies after the globally available
variable of the same name. 
-->
<p>オペレーティングシステムには、将来の特定の時間にタスクを処理できるような
スケジューリング機能が必要である。そして、スケジューリングにより、タスクを
比較的正確な時間に実行できるようなメカニズムが必要とされる。この点、オペレーテ
ィングシステムをサポートしようとするプロセッサには、必ずプログラム可能なイン
ターバルタイマーがあり、それが定期的にプロセッサに割り込みを掛けている。この
定期的な割り込みは、システムクロックティックと呼ばれる。それは、メトロノームに
似た働きをして、システムの活動を指揮している。
Linux は時刻管理に対して非常にシンプルな見方をしている。
Linux は、時間を起動時からのクロックティック(clock tick)によって計る。すべての
システムタイマーはその計測を基にしており、その計測方法は、広く利用されている
変数名にちなんで <tt>jiffies</tt> と呼ばれている。

<!--
Linux has two types of system timers, both queue routines to be called at
 some system time but they are slightly different in their implementations.
Figure  11.3 shows both mechanisms. 
The first, the old timer mechanism, has a static array of 32 pointers to
timer_struct data structures and a mask of active timers,
timer_active. 
Where the timers go in the timer table is statically defined (rather like the
bottom half handler table bh_base). Entries are added into this table
mostly at system initialization time. The second, newer, mechanism uses a
linked list of timer_list data structures held in ascending expiry time
order. 
-->
<p>Linux には二種類のシステムタイマーがある。どちらのキュールーチンも、ある
システム時間に呼び出されるのだが、それらは実装においてやや異なっている。
<ref id="figure11-3" name="図表(11.3)"> では、両方のメカニズムが示されている。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/timer.h" 
name="include/linux/timer.h">]<newline>
ひとつめは、古いタイマーメカニズムであり、<tt><ref id="timer_struct" 
name="timer_struct"></tt> データ構造体への 32 個のポインタによる静的配列と
アクティブタイマーのマスク <tt><ref id="timer_struct" name="timer_active">
</tt> から構成されている。
タイマーがタイマーテーブル内のどこに置かれるかは、静的に定義されている。
(これは、ボトムハーフハンドラのテーブル <tt>bh_base</tt> にやや似ている。)
エントリがこのテーブルに付け加えられるのは、大抵の場合システム起動時である。
ふたつめは、それより新しいメカニズムであり、<tt><ref id="timer_list" 
name="timer_list"></tt> データ構造体の連結リストを使用する。リストの要素は、
タイマー終了までの残り時間(expire time)の長さの順番で並べられている。

<!--
Both methods use the time in jiffies as an expiry time so that a timer
that wished to run in 5s would have to convert 5s to units of jiffies and
add that to the current system time to get the system time in jiffies
when the timer should expire. Every system clock tick the timer bottom half
handler is marked as active so that the when the scheduler next runs, the
timer queues will be processed. The timer bottom half handler processes
both types of system timer. For the old system timers the timer_active
bit mask is check for bits that are set. 
If the expiry time for an active timer has expired (expiry time is less than
the current system jiffies), its timer routine is called and its active bit is
cleared. For new system timers, the entries in the linked list of
timer_list data structures are checked. 
Every expired timer is removed from the list and its routine is called. The
new timer mechanism has the advantage of being able to pass an argument
to the timer routine. 
-->
<p>どちらの方法の場合でも、タイマーの残り時間を計る際の指標として <tt>jiffies
</tt> を使用する。
それゆえ、5 秒間だけ実行されるタイマーは、まず 5 秒という時間を <tt>jiffies
</tt> の単位に変換して、それを現在のシステム時間に加算することで、タイマーが
終了すべき時刻を <tt>jiffies</tt> 形式のシステム時間として獲得する。
システムクロックティッごとに、タイマーボトムハーフハンドラはアクティブとマーク
され、それによって、スケジューラが次に起動されるときに、タイマーキューが処理
される。タイマーボトムハーフハンドラは、両方のタイプのシステムタイマーを処理す
る。古いほうのシステムタイマーの場合、<tt>timer_active</tt> ビットマスクがチェ
ックされ、設定ビットが確認される。
<newline>[see: timer_bh(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/kernel/sched.c" 
name="kernel/sched.c">]
<newline>[see: run_old_timers(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/kernel/sched.c" 
name="kernel/sched.c">]
<newline>[see: run_timer_list(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/kernel/sched.c" 
name="kernel/sched.c">]<newline>
アクティブタイマーの終了時間が経過した場合
(終了時間の値がシステムの <tt>jiffies</tt> の現在値よりも小さい場合)、
そのタイマールーチンが呼び出され、アクティブビットはクリアされる。新しい
システムタイマーの場合、<tt>timer_list</tt> 構造体の連結リストのエントリが
チェックされる。すべての終了時間タイマーがリストから削除され、そのルーチンが
呼び出される。新しいタイマーのメカニズムには、タイマールーチンに引数を渡せる
という利点がある。

<!--11.4  Wait Queues-->
<sect1>待ち行列(wait queue)<label id="chapter_km_sect4">

<!--
There are many times when a process must wait for a system resource. For
example a process may need the VFS inode describing a directory in the file
system and that inode may not be in the buffer cache. In this case the
process must wait for that inode to be fetched from the physical media
containing the file system before it can carry on. 
-->
<p>プロセスは、何らかのシステムリソースを待たなければならない状態になること
がよくある。たとえば、あるプロセスがファイルシステム上のあるディレクトリを記述
する VFS inode を必要としていのだが、その inode がバッファキャッシュにない時
などである。
その場合、そのプロセスは、そのフィアルシステムを保持する物理メディアから
当該 inode が持ってこられるまで待ってから、処理を継続しなければならない。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/wait.h" 
name="include/linux/wait.h">]

<verb>
                        wait_queue 
                          *task 
                          *next

                    図表(11.4) 待ち行列

</verb>


<!--                   Figure 11.4: Wait Queue-->

<!--
The Linux kernel uses a simple data structure, a wait queue (see figure 
11.4), which consists of a pointer to the processes task_struct and a pointer 
to the next element in the wait queue. 
-->
<p>Linux カーネルはシンプルなデータ構造体である <tt><ref id="wait_queue" 
name="wait_queue"></tt> (図表(11.4)を参照)(訳注: この図表は原文においても GIF 
ファイルではありません。)を使用しているが、これは、<tt><ref id="task_struct" 
name="task_struct"></tt> のプロセスへのポインタと、待ち行列内の次の要素への
ポインタから構成されている。

<!--
When processes are added to the end of a wait queue they can either be
interruptible or uninterruptible. Interruptible processes may be interrupted by
events such as timers expiring or signals being delivered whilst they are
waiting on a wait queue. The waiting processes state will reflect this and
either be INTERRUPTIBLE or UNINTERRUPTIBLE. As this process can not
now continue to run, the scheduler is run and, when it selects a new process
to run, the waiting process will be suspended. 1 
-->
<p>プロセスが待ち行列の終端に付け加えられるとき、そのプロセスは、割り込み可能
か割り込み不可能かのいずれの場合もあり得る。割り込み可能なプロセスは、たとえば
タイマー
の終了といったイベントや、待ち行列上で待っている間に受信したシグナルによって
割り込まれるかもしれない。待ち行列上のプロセスの状態(state)はそれを反映して
いて、その状態は INTERRUPTIBLE(割り込み可能) か UNINTERRUPTIBLE(割り込み不可)
 のいずれかである。待ち行列上に置かれたプロセスは 現時点では動作させつづけられ
ず、スケジューラが次ぎのプロセスを選んだときに、その待ちプロセスはサスペンド状
態となる。(<ref id="chapter_km_fn" name="脚注 1">)

<!--
When the wait queue is processed, the state of every process in the wait
queue is set to RUNNING. If the process has been removed from the run
queue, it is put back onto the run queue. The next time the scheduler runs,
the processes that are on the wait queue are now candidates to be run as
they are now no longer waiting. When a process on the wait queue is
scheduled the first thing that it will do is remove itself from the wait queue.
Wait queues can be used to synchronize access to system resources and
they are used by Linux in its implementation of semaphores (see below). 
-->
<p>待ち行列が処理されるとき、待ち行列上のすべてのプロセスの状態(state)は、
RUNNING(実行中)にセットされる。
プロセスが実行キューから削除されていた場合は、再度実行キュー上に置かれる。
スケジューラが次に実行されるとき、待ち行列上にあるプロセスは、もう今は待ち
状態ではないので、実行されるべき候補者となっている。
待ち行列上のプロセスがスケジューラによって実行されるとき、それが最初に行う
ことは、自分を待ち行列上から削除することである。待ち行列はシステムリソースへの
アクセスを同期させるためにも使用できるので、Linux はそれらを使って、セマフォ
を実装している。

<!--11.5  Buzz Locks-->
<sect1>バズロック (Buzz Locks)<label id="chapter_km_sect5">

<!--
These are better known as spin locks and they are a primitive way of
protecting a data structure or piece of code. They only allow one process at
a time to be within a critical region of code. They are used in Linux to
restrict access to fields in data structures, using a single integer field as a
lock. Each process wishing to enter the region attempts to change the
lock's initial value from 0 to 1. If its current value is 1, the process tries
again, spinning in a tight loop of code. The access to the memory location
holding the lock must be atomic, the action of reading its value, checking
that it is 0 and then changing it to 1 cannot be interrupted by any other
process. Most CPU architectures provide support for this via special
instructions but you can also implement buzz locks using uncached main
memory. 
-->
<p>これは、スピンロック(spin locks)と呼ばれることのほうが多い仕組みであり、
データ構造やコードを保護するプリミティブな方法である。これは、一度にひとつの
プロセスしか重要なコード領域に入れないようにするものである。
Linux においては、データ構造体のフィールドへのアクセスを制限するために利用され
るのだが、その際、一つの単精度整数フィールドを使用したロックの仕組みを提供して
いる。
その領域に入ろうとする個々のプロセスは、ロックの初期値を 0 から 1 へと変更しよ
うとする。現在値が 1 の場合、タイトループ(tight loop)のコード内でスピニング
(spining)しながら、再度それを試みる。
そのロック機構を保持するメモリ領域へのアクセスは排他的(atomic)なものでなけれ
ばならず、その値の読み出し、それが 0 であることの検証、そしてその値の 1 への
変更といった処理は、他のプロセスから割り込まれることがない。大部分の CPU 
アーキテクチャでは、特別な命令によってこの仕組みをサポートしているが、
キャッシュされていないメインメモリを利用してバズロック(buzz lock)を実現する
こともできる。

<!--
When the owning process leaves the critical region of code it decrements
the buzz lock, returning its value to 0. Any processes spinning on the lock
will now read it as 0, the first one to do this will increment it to 1 and 
enter the critical region. 
-->
<p>占有中のプロセスがコードの重要領域から離れるとき、バズロックの値をデクリメン
トして、その値を 0 に戻す。ロック上でスピニングしているプロセスは、この時に
読み出しを行うと、0 を読み出す。それを最初に読み出したプロセスが、その値をイン
クリメントして 1 にし、重要領域へと入る。

<!--11.6  Semaphores-->
<sect1>セマフォ(semaphore)<label id="chapter_km_sect6">

<!--
Semaphores are used to protect critical regions of code or data structures.
Remember that each access of a critical piece of data such as a VFS inode
describing a directory is made by kernel code running on behalf of a process.
It would be very dangerous to allow one process to alter a critical data
structure that is being used by another process. One way to achieve this
would be to use a buzz lock around the critical piece of data is being
accessed but this is a simplistic approach that would not give very good
system performance. Instead Linux uses semaphores to allow just one
process at a time to access critical regions of code and data; all other
processes wishing to access this resource will be made to wait until it
becomes free. The waiting processes are suspended, other processes in the
system can continue to run as normal. 
-->
<p>セマフォは、コードやデータ構造の重要な領域を保護するために利用される。
たとえば、ディレクトリを記述する VFS inode のような重要なデータへの個々のアクセ
スは、そのプロセスに代わってカーネルコードによって実行される。あるプロセスが
使用している重要なデータ構造体に対する、他のプロセスによる変更を許すことは
非常に危険である。これを実現するひとつの方法は、アクセスされる重要なデータの
周囲でバズロックを使用することだが、これは単純なアプローチなので、良好な
システムパフォーマンスは期待できない。それに替えて、Linux はセマフォを使用
して、コードやデータの重要領域へのアクセスを一度にひとつのプロセスにしか
許さないようにしている。リソースへアクセスしようとするそれ以外のプロセス
は、領域がフリーになるまで待たされる。待ちプロセスはサスペンドされ、
システム上の他のプロセスは通常通り実行を続けることが可能である。

<!--
A Linux semaphore data structure contains the following information: 
-->
<p>Linux の <tt><ref id="semaphore" name="semaphore"></tt> データ構造体には、
次のような情報が含まれている。
<newline>[see: include/asm/semaphore.h]
(<htmlurl url="./The-Linux-Kernel-images/linux/include/asm-i386/semaphore.h" 
name="i386">, <htmlurl 
url="./The-Linux-Kernel-images/linux/include/asm-alpha/semaphore.h" 
name="alpha">)

<!--
count This field keeps track of the count of processes wishing to use this
      resource. A positive value means that the resource is available. A
      negative or zero value means that processes are waiting for it. An
      initial value of 1 means that one and only one process at a time can
      use this resource. When processes want this resource they
      decrement the count and when they have finished with this resource
      they increment the count, 
-->
<descrip>
<tag>count</tag>
このフィールドは、そのリソースを利用しようとするプロセスの数を監視するもので
ある。正の値は、リソースが利用可能であることを意味する。負または 0 の値は、
待ち状態のプロセスがあることを意味する。初期値 1 は、そのリソースを利用できる
のは一度にたったひとつのプロセスだけであることを意味する。プロセスがその
リソースを利用したいとき、プロセスはその値(count)をデクリメントし、このリソース
の利用を終了したとき、プロセスはその値をインクリメントする。

<!--
waking This is the count of processes waiting for this resource which is
      also the number of process waiting to be woken up when this
      resource becomes free, 
wait queue
      When processes are waiting for this resource they are put onto this
      wait queue, 
lock A buzz lock used when accessing the waking field. 
-->
<tag>waking</tag>
このフィールドは、そのリソースを待っているプロセス数のうち、そのリソースが
解放されたときに起こされることになっているプロセスの数を示すものである。

<tag>wait queue</tag>
プロセスがそのリソースを待っているとき、それらのプロセスはこの待ち行列上に
置かれる。

<tag>lock</tag>
waking フィールドにアクセスしているときは、バズロックが利用される。
</descrip>

<!--
Suppose the initial count for a semaphore is 1, the first process to come
along will see that the count is positive and decrement it by 1, making it 0.
The process now ``owns'' the critical piece of code or resource that is being
protected by the semaphore. When the process leaves the critical region it
increments the semphore's count. The most optimal case is where there are
no other processes contending for ownership of the critical region. Linux has
implemented semaphores to work efficiently for this, the most common,
case. 
-->
<p>セマフォの初期値が 1 であるとすると、最初にやって来たプロセスは、そのカウ
ントが正であることを確認し、そこから 1 を引いて 0 にする。これでプロセスは、
コードかリソースの重要部分を「占有」したことになり、それがセマフォによって
保護される。プロセスがその重要な領域を離れるとき、セマフォのカウントをインクリ
メントする。最善のケースは、その重要領域を所持しようとする他のプロセスが存在し
ない場合である。Linux は、この最も一般的なケースで効率よく動くようにセマフォを
実装している。

<!--
If another process wishes to enter the critical region whilst it is owned by a
process it too will decrement the count. As the count is now negative (-1)
the process cannot enter the critical region. Instead it must wait until the
owning process exits it. Linux makes the waiting process sleep until the
owning process wakes it on exiting the critical region. The waiting process
adds itself to the semaphore's wait queue and sits in a loop checking the
value of the waking field and calling the scheduler until waking is
non-zero. 
-->
<p>あるプロセスの占有中に他のプロセスが重要領域に入ろうとする場合、そのプロセス
も <tt>count</tt> をデクリメントする。その count は現在 負(-1)となるので、その
プロセスは重要領域に入れず、そのかわり占有中のプロセスが退出するまで待たなけれ
ばならない。Linux は待ちプロセスをスリープさせ、占有プロセスがその重要領域から
退出する際にそのプロセスを目覚めさせる。待ちプロセスは自分自身をセマフォの
待ち行列に登録して、waking フィールドの値をチェックしながらループ状態に
入り、waking が 0 でなくなった時にスケジューラを呼び出す。

<!--
The owner of the critical region increments the semaphore's count and if it
is less than or equal to zero then there are processes sleeping, waiting for
this resource. In the optimal case the semaphore's count would have been
returned to its initial value of 1 and no further work would be neccessary.
The owning process increments the waking counter and wakes up the
process sleeping on the semaphore's wait queue. When the waiting process
wakes up, the waking counter is now 1 and it knows that it it may now enter
the critical region. It decrements the waking counter, returning it to a value
of zero, and continues. All access to the waking field of semaphore are
protected by a buzz lock using the semaphore's lock. 
-->
<p>重要領域の占有者がセマフォの count をインクリメントして、もしその値が 0 以下
ならば、そのリソースを待ちながらスリープしているプロセスが存在する。最良のケー
スでは、セマフォの count は初期値である 1 に戻されているので、それ以上の仕事は
必要がない。
占有プロセスは waking フィールドの値をインクリメントして、セマフォの待ち行列で
スリープ状態にあるプロセスを目覚めさせる。待ちプロセスが起きると、waking 
フィールドの値は 1 なので、重要領域に入ってもよいことがわかる。プロセスは 
waking フィールドの値をデクリメントし、その値を 0 に戻し、実行を続ける。セマフ
ォの waking フィールドへのアクセスはすべて、セマフォのロックを使用したバズロッ
クにより保護されている。

<!--
Footnotes:

1 REVIEW NOTE: What is to stop a task in state INTERRUPTIBLE being
made to run the next time the scheduler runs? Processes in a wait queue
should never run until they are woken up. 
-->
<label id="chapter_km_fn">
<footnote>
(脚注 1)REVIEW NOTE: タスクを割り込み可能な状態で停止させて、次にスケジューラ
が実行される際に、そのタスクが実行されるとはどういうことか？ 待ち行列上でスリー
プ状態にあるプロセスは、目覚めさせられるまで、実行されないはずである。
</footnote>