diff options
Diffstat (limited to 'zh_CN.GB2312/books/arch-handbook/smp/chapter.xml')
-rw-r--r-- | zh_CN.GB2312/books/arch-handbook/smp/chapter.xml | 122 |
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> |