aboutsummaryrefslogtreecommitdiff
path: root/zh_CN.GB2312/books/arch-handbook/smp/chapter.xml
diff options
context:
space:
mode:
Diffstat (limited to 'zh_CN.GB2312/books/arch-handbook/smp/chapter.xml')
-rw-r--r--zh_CN.GB2312/books/arch-handbook/smp/chapter.xml122
1 files changed, 56 insertions, 66 deletions
diff --git a/zh_CN.GB2312/books/arch-handbook/smp/chapter.xml b/zh_CN.GB2312/books/arch-handbook/smp/chapter.xml
index c2369c60a9..1815559700 100644
--- a/zh_CN.GB2312/books/arch-handbook/smp/chapter.xml
+++ b/zh_CN.GB2312/books/arch-handbook/smp/chapter.xml
@@ -6,18 +6,11 @@
Original Revision: 1.26
$FreeBSD$
-->
-<chapter id="smp">
- <chapterinfo>
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="smp">
+ <info><title>SMPng 设计文档</title>
<authorgroup>
- <author>
- <firstname>John</firstname>
- <surname>Baldwin</surname>
- <contrib>&cnproj.written.by;</contrib>
- </author>
- <author>
- <firstname>Robert</firstname>
- <surname>Watson</surname>
- </author>
+ <author><personname><firstname>John</firstname><surname>Baldwin</surname></personname><contrib>&cnproj.written.by;</contrib></author>
+ <author><personname><firstname>Robert</firstname><surname>Watson</surname></personname></author>
</authorgroup>
<copyright>
@@ -29,17 +22,14 @@
</copyright>
<authorgroup>
- <author>
- &author.cn.delphij;
- <contrib>&cnproj.translated.by;</contrib>
- </author>
+ <author><personname/><contrib>&cnproj.translated.by;</contrib></author>
</authorgroup>
- </chapterinfo>
+ </info>
- <title>SMPng 设计文档</title>
+
- <sect1 id="smp-intro">
+ <sect1 xml:id="smp-intro">
<title>绪论</title>
<indexterm><primary>SMP Next Generation Project(下一代对称多处理工程)</primary></indexterm>
@@ -67,7 +57,7 @@
请参阅本文的 <xref linkend="smp-glossary"/> 一节。</para>
</sect1>
- <sect1 id="smp-lock-fundamentals">
+ <sect1 xml:id="smp-lock-fundamentals">
<title>基本工具与上锁的基础知识</title>
<sect2>
@@ -97,7 +87,7 @@
<function>atomic_cmpset</function> 而不是
<function>atomic_set</function> 来打开
<constant>MTX_CONTESTED</constant> 位。 这样做的原因是,
- 我们需要把 <structfield>mtx_lock</structfield> 的值读到某个变量,
+ 我们需要把 <varname remap="structfield">mtx_lock</varname> 的值读到某个变量,
并据此进行决策。 然而, 我们读到的值可能是过时的,
也可能在我们进行决策的过程中发生变化。 因此, 当执行
<function>atomic_set</function> 时, 最终可能会对另一值进行置位,
@@ -148,7 +138,7 @@
</sect2>
</sect1>
- <sect1 id="smp-design">
+ <sect1 xml:id="smp-design">
<title>架构与设计概览</title>
<sect2>
@@ -390,7 +380,7 @@
</sect2>
</sect1>
- <sect1 id="smp-lock-strategies">
+ <sect1 xml:id="smp-lock-strategies">
<title>特定数据的锁策略</title>
<sect2>
@@ -398,7 +388,7 @@
<indexterm><primary>credentials(凭据)</primary></indexterm>
- <para><structname>struct ucred</structname> 是内核内部的凭据结构体,
+ <para><varname remap="structname">struct ucred</varname> 是内核内部的凭据结构体,
它通常作为内核中以进程为导向的访问控制的依据。
BSD-派生的系统采用一种 <quote>写时复制</quote> 的模型来处理凭据数据:
同一凭据结构体可能存在多个引用, 如果需要对其进行修改,
@@ -410,25 +400,25 @@
<para>凭据结构体只有一个引用时, 被认为是可变的;
不允许改变共享的凭据结构体, 否则将可能导致发生竞态条件。
- <structfield>cr_mtxp</structfield> mutex 用于保护
- <structname>struct ucred</structname> 的引用计数,
+ <varname remap="structfield">cr_mtxp</varname> mutex 用于保护
+ <varname remap="structname">struct ucred</varname> 的引用计数,
以维护其一致性。 使用凭据结构体时, 必须在使用过程中保持有效的引用,
否则它就可能在这个不合理的消费者使用过程中被释放。</para>
- <para><structname>struct ucred</structname> mutex 是一种叶
+ <para><varname remap="structname">struct ucred</varname> mutex 是一种叶
mutex, 出于性能考虑, 它通过 mutex 池实现。</para>
<para>由于多用于访问控制决策, 凭据通常情况下是以只读方式访问的, 此时一般应使用
- <structfield>td_ucred</structfield>, 因为它不需要上锁。
+ <varname remap="structfield">td_ucred</varname>, 因为它不需要上锁。
当更新进程凭据时, 检查和更新过程中必须持有 <literal>proc</literal>
- 锁。 检查和更新操作必须使用 <structfield>p_ucred</structfield>,
+ 锁。 检查和更新操作必须使用 <varname remap="structfield">p_ucred</varname>,
以避免检查时和使用时的竞态条件。</para>
<para>如果所调系统调用将在更新进程凭据之后进行访问控制检查, 则
- <structfield>td_ucred</structfield> 也必须刷新为当前进程的值。
+ <varname remap="structfield">td_ucred</varname> 也必须刷新为当前进程的值。
这样做能够避免修改后使用过时的凭据。 内核会自动在进程进入内核时,
- 将线程结构体的 <structfield>td_ucred</structfield> 指针刷新为进程的
- <structfield>p_ucred</structfield>, 以保证内核访问控制能用到新的凭据。</para>
+ 将线程结构体的 <varname remap="structfield">td_ucred</varname> 指针刷新为进程的
+ <varname remap="structfield">p_ucred</varname>, 以保证内核访问控制能用到新的凭据。</para>
</sect2>
<sect2>
@@ -442,14 +432,14 @@
<indexterm><primary>Jail(囚禁)</primary></indexterm>
- <para><structname>struct prison</structname> 保存了用于维护那些通过
+ <para><varname remap="structname">struct prison</varname> 保存了用于维护那些通过
&man.jail.2; API 创建的 jail 所用到的管理信息。 这包括 jail
的主机名、 IP 地址, 以及一些相关的设置。 这个结构体包含引用计数,
因为指向这一结构体实例的指针会在多种凭据结构之间共享。
- 用了一个 mutex, <structfield>pr_mtx</structfield>
+ 用了一个 mutex, <varname remap="structfield">pr_mtx</varname>
来保护对引用计数以及所有 jail 结构体中可变变量的读写访问。
有一些变量只会在创建 jail 的时刻发生变化, 只需持有有效的
- <structname>struct prison</structname> 就可以开始读这些值了。
+ <varname remap="structname">struct prison</varname> 就可以开始读这些值了。
关于每个项目具体的上锁操作的文档,
可以在 <filename>sys/jail.h</filename> 的注释中找到。</para>
</sect2>
@@ -459,11 +449,11 @@
<indexterm><primary>MAC(强制访问控制)</primary></indexterm>
- <para>TrustedBSD MAC 框架会以 <structname>struct
- label</structname> 的形式维护一系列内核对象的数据。
+ <para>TrustedBSD MAC 框架会以 <varname remap="structname">struct
+ label</varname> 的形式维护一系列内核对象的数据。
一般来说, 内核中的 label (标签) 是由与其对应的内核对象同样的锁保护的。
- 例如, <structname>struct vnode</structname> 上的
- <structfield>v_label</structfield> 标签是由其所在 vnode 上的
+ 例如, <varname remap="structname">struct vnode</varname> 上的
+ <varname remap="structfield">v_label</varname> 标签是由其所在 vnode 上的
vnode 锁保护的。</para>
<para>除了嵌入到标准内核对象中的标签之外, MAC
@@ -495,8 +485,8 @@
因此我们提供了几个方便使用的宏来简化对这个锁的访问,
这些宏可以在 <filename>sys/module.h</filename> 中找到,
其用法都非常简单明了。 这个锁保护的主要是
- <structname>module_t</structname> (当以共享方式上锁)
- 和全局的 <structname>modulelist_t</structname> 这两个结构体,
+ <varname remap="structname">module_t</varname> (当以共享方式上锁)
+ 和全局的 <varname remap="structname">modulelist_t</varname> 这两个结构体,
以及模块。 要更进一步理解这些锁策略, 需要仔细阅读
<filename>kern/kern_module.c</filename> 的源代码。</para>
</sect2>
@@ -560,23 +550,23 @@
只允许一进程或进程组注册 SIGIO, 这个进程或进程组称为属主 (owner)。
每一支持 SIGIO 注册的对象, 都包含一指针字段, 如果对象未注册则为
<constant>NULL</constant>,
- 否则是一指向描述这一注册的 <structname>struct sigio</structname> 的指针。
+ 否则是一指向描述这一注册的 <varname remap="structname">struct sigio</varname> 的指针。
这一字段由一全局 mutex,
<varname>sigio_lock</varname> 保护。 调用 SIGIO 维护函数时,
必须以 <quote>传引用</quote> 方式传递这一字段,
以确保本地注册副本的中这个字段不脱离锁的保护。</para>
<para>每个关联到进程或进程组的注册对象, 都会分配一
- <structname>struct sigio</structname> 结构, 并包括指回该对象的指针、
+ <varname remap="structname">struct sigio</varname> 结构, 并包括指回该对象的指针、
属主、 信号信息、 凭据, 以及关于这一注册的一般信息。
- 每个进程或进程组都包含一个已注册 <structname>struct sigio</structname>
+ 每个进程或进程组都包含一个已注册 <varname remap="structname">struct sigio</varname>
结构体的列表, 对进程来说是
- <structfield>p_sigiolst</structfield>, 而对进程组则是
- <structfield>pg_sigiolst</structfield>。 这些表由相应的进程或进程组锁保护。
+ <varname remap="structfield">p_sigiolst</varname>, 而对进程组则是
+ <varname remap="structfield">pg_sigiolst</varname>。 这些表由相应的进程或进程组锁保护。
除了用以将
- <structname>struct sigio</structname> 连接到进程组上的
- <structfield>sio_pgsigio</structfield> 字段之外, 在 <structname>struct
- sigio</structname> 中的多数字段在注册过程中都是不变量。
+ <varname remap="structname">struct sigio</varname> 连接到进程组上的
+ <varname remap="structfield">sio_pgsigio</varname> 字段之外, 在 <varname remap="structname">struct
+ sigio</varname> 中的多数字段在注册过程中都是不变量。
一般而言, 开发人员在实现新的支持 SIGIO 的内核对象时,
会希望避免在调用 SIGIO 支持函数, 例如 <function>fsetown</function>
或 <function>funsetown</function> 持有结构体锁,
@@ -619,16 +609,16 @@
<varname>taskqueue_queues_mutex</varname> 是用于保护
<varname>taskqueue_queues</varname> TAILQ 的锁。
与这个系统关联的另一个 mutex 锁是位于
- <structname>struct taskqueue</structname> 结构体上。
- 在此处使用同步原语的目的在于保护 <structname>struct
- taskqueue</structname> 中数据的完整性。 应注意的是,
+ <varname remap="structname">struct taskqueue</varname> 结构体上。
+ 在此处使用同步原语的目的在于保护 <varname remap="structname">struct
+ taskqueue</varname> 中数据的完整性。 应注意的是,
并没有单独的、 帮助用户对其自身的工作进行锁的细化用的宏,
因为这些锁基本上不会在
<filename>kern/subr_taskqueue.c</filename> 以外的地方用到。</para>
</sect2>
</sect1>
- <sect1 id="smp-implementation-notes">
+ <sect1 xml:id="smp-implementation-notes">
<title>实现说明</title>
<sect2>
@@ -793,7 +783,7 @@
</sect2>
</sect1>
- <sect1 id="smp-misc">
+ <sect1 xml:id="smp-misc">
<title>其它话题</title>
<sect2>
@@ -816,10 +806,10 @@
</sect2>
</sect1>
- <glossary id="smp-glossary">
+ <glossary xml:id="smp-glossary">
<title>术语表</title>
- <glossentry id="smp-glossary-atomic">
+ <glossentry xml:id="smp-glossary-atomic">
<glossterm>原子</glossterm>
<glossdef>
<para>当遵循适当的访问协议时, 如果一操作的效果对其它所有 CPU
@@ -832,7 +822,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-block">
+ <glossentry xml:id="smp-glossary-block">
<glossterm>阻塞</glossterm>
<glossdef>
<para>线程等待锁、 资源或条件时被阻塞。
@@ -842,7 +832,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-critical-section">
+ <glossentry xml:id="smp-glossary-critical-section">
<glossterm>临界区</glossterm>
<glossdef>
<para>不允许发生抢占的代码段。 使用
@@ -850,7 +840,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-MD">
+ <glossentry xml:id="smp-glossary-MD">
<glossterm>MD</glossterm>
<glossdef>
<para>表示与机器/平台有关。</para>
@@ -859,14 +849,14 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-memory-operation">
+ <glossentry xml:id="smp-glossary-memory-operation">
<glossterm>内存操作</glossterm>
<glossdef>
<para>内存操作包括读或写内存中的指定位置。</para>
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-MI">
+ <glossentry xml:id="smp-glossary-MI">
<glossterm>MI</glossterm>
<glossdef>
<para>表示与机器/平台无关。</para>
@@ -875,12 +865,12 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-operation">
+ <glossentry xml:id="smp-glossary-operation">
<glossterm>操作</glossterm>
<glosssee>内存操作</glosssee>
</glossentry>
- <glossentry id="smp-glossary-primary-interrupt-context">
+ <glossentry xml:id="smp-glossary-primary-interrupt-context">
<glossterm>主中断上下文</glossterm>
<glossdef>
<para>主中断上下文表示当发生中断时所执行的那段代码。
@@ -899,7 +889,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-sleep">
+ <glossentry xml:id="smp-glossary-sleep">
<glossterm>休眠</glossterm>
<glossdef>
<para>当进程由条件变量或通过 <function>msleep</function> 或
@@ -909,7 +899,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-sleepable-lock">
+ <glossentry xml:id="smp-glossary-sleepable-lock">
<glossterm>可休眠锁</glossterm>
<glossdef>
<para>可休眠锁是一种在进程休眠时仍可持有的锁。
@@ -921,7 +911,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-thread">
+ <glossentry xml:id="smp-glossary-thread">
<glossterm>线程</glossterm>
<glossdef>
<para>由 struct thread 所表达的内核线程。 线程可以持有锁,
@@ -929,7 +919,7 @@
</glossdef>
</glossentry>
- <glossentry id="smp-glossary-wait-channel">
+ <glossentry xml:id="smp-glossary-wait-channel">
<glossterm>等待通道</glossterm>
<glossdef>
<para>线程可以在其上休眠的内核虚拟地址。</para>