维持对象的锁的乐观平衡同步的状态信息的方法、设备和系统的制作方法

文档序号:6579463阅读:164来源:国知局
专利名称:维持对象的锁的乐观平衡同步的状态信息的方法、设备和系统的制作方法
技术领域
本发明一般涉及计算机,尤其涉及用于受管运行时环境的线程同步方法和装置。
背景技术
支持多线程应用程序的软件环境,例如JAVA和欧洲计算机厂商协会(ECMA) 公共语言基础架构(CLI)通常包括用于在一个或多个线程可能访问一个对象时进 行协调的同步机制。如本领域的普通技术人员所理解的,线程指的是被组织成用于 处理一个或多个对象的单个执行控制流的一系列处理器指令。对象是类的实例,其 中类是数据以及对这些数据进行操作的方法的集合。在多个执行线程的情况下,必 须注意防止多个线程以可能会将对象置于出错状态的方式同时修改同一对象。具体 地,一个线程可能具有对可能同时被另一线程访问的对象进行操作的临界段。由此, 多线程系统通常提供专门的语句来保护临界段的操作不被在临界段执行期间访问 这一共享对象的一个或多个其它线程破坏。
例如,JAVA源代码可包括synchronized (同步)语句,用于保护对象不被不 同线程同时访问。使用synchronized语句允许获取由synchronized语句所标识的对 象的排他锁。由此,可防止线程在它能够获得由synchronized语句标识的特定对象 上的排他锁之前执行代码的临界段。此外, 一旦获得了这样的锁,没有任何其它线 程能够访问锁定的对象,由此防止对在代码的临界段的执行期间执行的处理的无意 破坏。这一锁定过程可用于确保多个线程不能以可能导致代码的临界段在同一时刻 的冲突执行的方式来访问共享对象。当然,对synchronized语句的应用一般是在特 定程序创建多个线程来共享对象和/或方法的情况下使用的。如果仅有一个线程访问特定对象和/或方法,则无需用synchronized语句来保护它。
JAVA源代码中的synchronized语句一般被转换成JAVA虚拟机(JVM)指令, 这是因为如本领域中已知的,JAVA源代码在由JVM执行之前首先被编译成字节 码(即,JVM语言)。例如,synchronized语句可被转换成monitorenter (监控程 序进入)JVM指令以获得/获取对象的排他锁。作为对monitorenter指令的遵循, 提供monitorexit (监控程序退出)JVM指令以解锁/释放该对象的排他锁。因此, 如果线程成功地对对象执行了 monitorenter指令,则该线程临时获得该对象的排他 锁拥有权(即,它获得了该对象上的锁以防止其它线程访问代码的临界段)。如果 在第一线程具有对象的临时排他拥有权的同时另一线程或第二线程试图在同一对 象上执行monitorenter指令,则第二线程必须等待(例如,睡眠或自旋),直到第 一线程(即,当前锁拥有者)执行了 monitorexit指令来释放其对于该对象的排他 锁。
通常使用两个状态变量来描述对象的锁状态。第一个状态变量是对应于当前 拥有该锁的线程的线程标识符的锁拥有者。对于锁未被任何线程拥有的情况,锁拥 有者可被设为NULL值或NULL线程。第二个状态变量是可用于指示锁拥有者获 取该锁的次数的锁递归计数(用于支持递归锁定)。通常,对象的锁状态被初始化 为使锁拥有者等于NULL值(对应于未锁定状态),且锁递归计数等于零。
在许多现有技术的对象锁定技术(例如,JM monitorenter和monitorexit指令 的现有技术实现)中,锁释放功能(例如,对应于monitorexit指令)确定试图释 放锁的线程是否实际上是该锁的锁拥有者。另外,锁释放功能检查锁递归计数器以 确定锁是应被解锁还是被维持(例如,由于多个递归锁获取而维持在锁定状态)。 然而,使用较高级语言(例如,JAVA)编写然后被编译成字节码的大多数形式良 好的应用程序包括匹配的锁获取和释放操作对(例如,匹配的monitorenter和 monitorexit JVM指令对),且因此展示出平衡的同步特性(即,涉及由同一线程 执行的平衡的锁获取和释放对的锁定序列)。在展示出平衡同步特性的代码中,检 査锁拥有者和锁递归计数器状态变量的额外开销可能是不必要的,且因此可能会降 低执行应用程序的总体效率。

发明内容
为了解决上述问题,在本申请中提供了一种用于受管运行时环境的线程同步 方法和装置以减少不必要的开销,并提高执行应用程序的总体效率。根据本发明的一个方面,提供了一种维持在受管运行时环境中的对象的锁的 乐观平衡同步的状态信息的方法,所述方法包括存储状态信息,所述状态信息包 括与要在所述对象的锁上执行的每个待决乐观平衡同步对应的每个待决乐观平衡 释放操作的状态,每个待决乐观平衡同步包括各自成对的获取和释放操作,在这些 操作中会出现未知数目的未成对锁定操作;以及当在所述锁上执行后续未成对锁定 操作时,修改第一待决乐观平衡释放操作的第一存储状态,但当在所述锁上执行后 续乐观平衡同步时,不修改任何待决乐观平衡释放的任何存储状态,包括第一待决 乐观平衡释放操作的第一存储状态。
根据本发明的另一个方面,提供了一种维持在受管运行时环境中的对象的锁 的乐观平衡同步的状态信息的设备,所述设备包括用于存储状态信息的存储器, 所述状态信息包括与要在所述对象的锁上执行的每个待决乐观平衡同步对应的每 个待决乐观平衡释放操作的状态,每个待决乐观平衡同步包括各自成对的获取和释 放操作,在这些操作中会出现未知数目的未成对锁定操作;以及乐观平衡同步状态 修改器,当在所述锁上执行后续未成对锁定操作时,所述乐观平衡同步状态修改器 用于修改第一待决乐观平衡释放操作的第一存储状态,但当在所述锁上执行后续乐 观平衡同步时,所述乐观平衡同步状态修改器用于不修改任何待决乐观平衡释放的 任何存储状态,包括第一待决乐观平衡释放操作的第一存储状态。
根据本发明的又一个方面,提供了一种维持在受管运行时环境中的对象的锁 的乐观平衡同步的状态信息的系统,所述系统包括用于存储状态信息的装置,所 述状态信息包括与要在所述对象的锁上执行的每个待决乐观平衡同步对应的每个 待决乐观平衡释放操作的状态,每个待决乐观平衡同步包括各自成对的获取和释放 操作,在这些操作中会出现未知数目的未成对锁定操作;以及当在所述锁上执行后 续未成对锁定操作时,用于修改第一待决乐观平衡释放操作的第一存储状态的装 置,但当在所述锁上执行后续乐观平衡同步时,用于不修改任何待决乐观平衡释放 的任何存储状态,包括第一待决乐观平衡释放操作的第一存储状态的装置。


图1是其中可采用此处所描述的示例方法、装置和制品的示例受管运行时环 境的框图。
图2是可在图1的受管运行时环境中使用的示例锁管理器的框图。
图3A-3B是表示可由机器执行以实现可在图1的受管运行时环境中使用的示例现有技术锁管理器的示例机器可读指令的流程图。
图4是表示可由机器执行以实现图2的示例锁管理器的示例机器可读指令的
流程图。
图5A-5B是表示可由机器执行以分别实现图2的示例性平衡锁同步单元和示 例性乐观平衡锁同步单元的示例机器可读指令的流程图。
图6A-6B是表示可由机器执行以实现图2的示例未平衡锁获取单元的示例机 器可读指令的流程图。
图7是表示可由机器执行以实现图2的示例未平衡锁释放单元的示例机器可 读指令的流程图。
图8是表示可由机器执行以确定供图6A-6B和7的进程使用的待决平衡释放 的状态的示例机器可读指令的流程图。
图9是可由机器执行以修改供图6A-6B和7的进程使用的待决平衡释放的状 态的示例机器可读指令的流程图。
图10A-10B示出了图2的锁管理器的示例操作。
图11是可执行图4-9的进程以实现图2的锁管理器的示例处理器系统的图示。
具体实施例方式
图1中示出了其中可采用如此处所描述的示例方法、装置和制品的有用的示 例环境100的框图。示例使用环境IOO可例如经由如下所述图11的示例处理器系 统IIOO等一个或多个处理器系统来实现。尽管图1的示例对应于基于JAVA的受 管运行时环境(MRTE),但本领域的普通技术人员可以理解,此处所描述的示例 方法、装置和制品可应用于任何类似的MRTE使用环境,举例来说比如CLI和相 关联的语言C弁。
示例使用环境IOO包括被描绘为图1中的JAVA虚拟机(JVM)110的MRTE。 示例JVM 110动态地将由机器不相关指令表示的程序或字节码114转换成机器相 关或本机指令,然后在一个或多个处理器120 (诸如以下描述的处理器1112)上执 行这些本机指令。JVM IIO可通过专用于一个或多个处理器120的操作系统(OS) 130,诸如Microsoft Windows OS、 UNIXOS、 Linux OS等来执行这些本机指令。
在图1的示例中,JVM110处理储存在多个类文件114中的字节码114。通常, 类文件114储存对应于单个JAVA类的字节码114,包括定义类的接口、字段和方 法。类文件114可由JAVA编译器134从例如由软件开发员编写的JAVA程序源代码138中创建。JAVA编译器134、相关联的JAVA源代码138和所得的类文件 114 (或字节码114)在本领域中是公知的,且因此此处不再进一步讨论。
为处理类文件114,示例JVM110包括类加载器142,用于定位对应于一个或 多个特定类的一个或多个特定类文件114,并例如通过将所加载的类文件114的本 地映象储存到本地存储器146中来将这些类文件114加载到JVM 110的执行引擎 144中。在将加载的类文件114储存在存储器146之前,类加载器142可调用字节 码验证器150来验证所加载的类文件114的结构是正确且符合JAVA语言的构造 的。在任一情况下,JM 110的执行引擎144然后使用例如解释器154和/或一个 或多个即时(Just-In-Time, JIT)编译器158将所加载的机器不相关字节码转换成 机器相关指令。
解释器154将字节码114转换成在目标处理器120上实现字节码114的功能 的一组机器相关指令。换言之,解释器154提供仿真层以允许字节码114如同处理 器120直接支持JAVA指令集那样在目标处理器120上执行。另一方面,JIT编译 器158将一组字节码U4编译成一组机器相关指令用于在目标处理器120上执行。 各个字节码114的具体功能可能不被确切地转换成机器相关指令,但是所得的一组 机器相关指令的总体功能将等效于原始的一组字节码114。由此,JIT编译器158 可产生比解释器154更优的代码。然而,解释器154可能比JIT编译器158更易于 实现。
为执行由解释器154和/或一个或多个JIT编译器158提供的程序代码,JVM 110的执行引擎144可在本地存储器146中定义一个或多个存储区。例如,为支持 多个同时线程的执行,JVM 110可在存储器146中为每一线程分配一单独的虚拟程 序计数器(pc)寄存器和一单独的JVM栈帧。JVM栈帧可用于储存例如对应于相 关联的执行线程的局部变量和部分结果。另外,JVM 110可在本地存储器146中定 义对所有线程公用的存储区。例如,这一存储区可包括储存在程序执行期间创建的 对象的堆、储存例如用于实现特定类的方法的数据和代码的方法区、以及储存与特 定类相关联的常量的运行时常量池。为有效地管理存储器146的运行时部分,JVM 110可包括无用信息收集器162,例如用于自动从堆解除对象的分配以释放存储器 供随后的程序执行使用。
为支持多个同时线程的执行,JVM110的执行引擎144包括线程支持模块166。 线程支持模块166支持通过创建线程对象来创建线程并通过调用该线程的开始方 法来执行线程。另外,线程支持模块166可支持通过使用各种优先级来对线程进行优选执行。本发明所令人特别感兴趣的是,JVM 110的执行引擎144还包括锁管理 器170,以解决当两个或更多线程试图访问同一共享对象时发生的冲突。
对应于示例JVM 110的行业标准规范(以及用于其它受管运行时环境的规范) 定义了支持多个线程之间的对象同步的过程。JVM 110为每一对象提供一同步锁。 线程可通过获取与对象相关联的锁的拥有权来获取对象的拥有权。类似地,线程可 通过释放与对象相关联的锁的拥有权来释放对象的拥有权。在JAVA编程语言中, 对象和方法的同步是通过synchronized语句来实现的。JVM 110的规范定义了分别 经由monitorenter和monitorexit字节码的锁获取和释放操作。然而,未定义 monitorenter和monitorexit字节码的实现。
可用于实现图1的示例锁管理器170的示例锁管理器200的框图在图2中示 出。示例锁管理器200基于大多数锁获取和锁释放将被平衡或乐观平衡的假设为线 程获取和释放对象的锁。例如,锁管理器200可确定如果锁上的一组获取和释放操 作在同一嵌套级上发生则这些操作被平衡,并且位于操作之间的代码的临界段要么 不包含同步操作,要么仅包含锁上的其它平衡的同步操作(例如,线程获取对象的 锁,执行程序代码的临界段,然后释放对象的锁)。类似地,锁管理器200可确定 如果锁上的一组获取和释放操作在同一嵌套级上发生则这些操作被乐观平衡,但是 锁管理器200无法确信地确定所有操作都被平衡(例如,在代码的临界段包含方法 调用的情况下)。大多数使用较高级语言(例如,JAVA)编写然后被编译成字节 码(例如,字节码114)的形式良好的程序展示出平衡的同步特性(即,包括先前 提到的平衡的获取和释放对的同步)。然而,在少数情况下,锁获取或释放可能未 被平衡(例如,如使用手写字节码实现的程序的情况)。因此,除平衡及乐观平衡 的锁处理过程之外,锁管理器200可能采用未平衡的获取和释放过程来分别获取和 释放对象的锁。
如图2所示,锁管理器200包括接受来自执行线程的对象标识符输入208和
线程上下文输入212的锁同步控制器204。对象标识符输入208用于将对象标识为
已同步,且可包括唯一对象实例标识符、对象的锁字等。线程上下文输入212用于
指示试图锁定或解锁由对象标识符输入208标识的对象的线程的身份、该线程的操
作状态以及要在对象的锁上执行的相关联操作(例如,用于获取锁或释放锁,以及
获取和/或释放是否被平衡、乐观平衡或未平衡)。锁同步控制器204提供对象锁
状态输出216以指示对象的锁的状态(例如,初始获取、递归获取、释放/解锁、 抛出异常等)。另外,锁同步控制器204基于要在由对象标识符输入208标识的对象的锁上 执行的锁定操作的类型调用特定的锁操作单元。锁定操作的示例类型包括平衡的锁 同步、乐观平衡的锁同步、未平衡的锁获取和未平衡的锁释放。锁同步控制器204 可基于经由线程上下文输入212提供的信息确定锁定操作的类型。这一信息可例如 由图1的解释器154和/或JIT编译器158确定,作为从字节码114到由线程上下 文输入212所标识的线程执行的一组机器相关指令的转换的一部分。
为执行对象的平衡的锁同步(即,平衡的锁获取之后相应的平衡的锁释放), 示例锁管理器200包括平衡锁同步单元218。如果锁同步控制器204确定应当在对 象上执行平衡同步(例如,基于对象标识符输入208和线程上下文输入212),则 平衡锁同步单元218确定线程是否已经获取了对象的锁。如果所需对象的锁可用 (或已经被请求线程拥有),则平衡锁同步单元218储存锁的当前状态,并为线程 获取该锁。如果锁不可用,则平衡锁同步218调用已知的锁竞争过程以在锁变得可 用之后为线程获得该锁(在已知锁竞争过程不改变锁的表示/格式或在竞争进程终 止之后将锁返回到其原始表示/格式的约束下)。在任一情况下,平衡锁同步单元 218然后可使锁同步控制器204更新锁状态输出216以指示对象锁已被获取。在线 程执行完了需要锁定对象的代码之后(例如,如由线程上下文输入212所指示的), 则可发信号通知平衡锁同步单元218通过将锁还原到其前一状态来释放对象的锁, 由此使锁同步控制器204相应地更新对象锁状态输出216。
为执行对象的乐观平衡锁同步,示例锁管理器200包括乐观平衡锁同步单元 220。乐观平衡锁同步单元220以类似于平衡锁同步单元218的方式操作。如下结 合图5B所描述的,乐观平衡锁同步单元220采用回退机制来从在执行了乐观平衡 锁获取之后可能发生的未平衡锁获取和/或释放中恢复。示例回退机制可以基于指 示未平衡锁操作是否在乐观平衡锁获取之后但在相应的乐观平衡锁释放之前(即, 在乐观平衡锁获取活动的同时)发生的标志或其它指示符。这一标志或其它指示符 允许乐观平衡锁同步单元220相应地修改对应的乐观平衡释放操作。为支持单个线 程的递归锁获取,乐观平衡锁同步单元220包括同步映射图以跟踪给定对象的所有 待决的乐观平衡锁释放的状态。
为执行未平衡锁获取或未平衡锁释放,锁管理器200分别包括未平衡锁获取 单元224和未平衡锁释放单元228。如果锁同步控制器204确定应在对象上执行未 平衡锁获取(例如,基于线程上下文输入212),则如果锁可用(或已被线程拥有), 未平衡锁获取单元224为线程获取对象的锁,或者如果锁不可用,则调用已知的锁竞争过程(在已知锁竞争过程不改变锁的表示/格式或者在竞争进程终止之后将锁
返回到其原始表示/格式的约束下)。如果锁同步控制器204确定应当在对象上执 行未平衡释放,则如果锁当前被线程拥有,则未平衡锁释放单元228释放/解锁对 象的锁。如果锁未被线程拥有,则未平衡锁释放单元228抛出指示尝试了无效锁释 放的异常。然后,取决于是执行锁获取还是锁释放,未平衡锁获取单元224或未平 衡锁释放单元228分别可使锁同步控制器204更新锁状态输出216以指示对象锁的 适当状态。
未平衡锁获取单元224和未平衡锁释放单元228两者都可能需要修改由乐观 平衡锁同步单元220储存的待决释放的同步映射图。例如,在乐观平衡锁获取之后 执行的未平衡锁获取可能要求后续的乐观平衡释放实际维持该锁(由于额外的锁获 取)。在另一示例中,在乐观平衡锁获取之后但在后续的乐观平衡锁释放之前执行 的未平衡锁释放可能要求乐观平衡锁释放抛出异常而非释放锁(由于在已被未平衡 锁释放释放之后在锁上执行了额外的锁释放)。由此,为更新由乐观平衡锁同步单
元220维护的同步映射图,示例锁管理器200包括乐观平衡同步状态修改器236。 乐观平衡同步状态修改器236可被配置成将待决的乐观平衡释放的状态修改成有 效状态(例如,解锁状态或维持锁状态)或无效状态(例如,无效释放/抛出异常 状态)。乐观平衡同步状态修改器236可取决于执行的锁操作(即,分别为未平衡 获取或未平衡释放)和前续的未平衡锁操作的历史由未平衡锁获取单元224或未平 衡锁释放单元228的任一个调用。例如,未平衡锁释放可与未平衡锁获取联合,以 使可能无需修改同步映射图中的乐观平衡释放。
示例锁管理器200还包括乐观平衡释放跟踪器232,以处理由乐观平衡锁同步 单元220储存的同步映射图。乐观平衡释放跟踪器232可被配置成例如确定储存在 同步映射图中的有效乐观平衡释放(例如,在递归锁获取的情况下,对应于对解锁 或维持锁的释放)的个数。乐观平衡释放跟踪器232还可确定储存在同步映射图中 的任何无效乐观平衡释放(例如,对应于将导致抛出异常的无效(额外)释放的平 衡释放)的存在。乐观平衡释放跟踪器232向未平衡锁获取单元224和/或未平衡 锁释放单元228提供关于同步映射图的这些统计量,以使它们可适当地调用乐观平 衡同步状态修改器236。
表示用于实现图1的锁管理器170的已知机器可读指令的流程图在图3A-3B 中示出。表示用于实现图1的锁管理器170和/或图2的锁管理器200的公开的示 例机器可读指令的流程图在图4-9中示出。在图4-9的示例中,由每一流程图表示的进程可由一组机器可读指令实现,该组指令可包括供诸如以下结合图ll讨论的
示例计算机1100中所示的处理器1112等处理器执行的一个或多个程序。这一个或 多个程序可具体化为储存在诸如CD-ROM、软盘、硬盘驱动器、DVD或与处理器 1112相关联的存储器等有形介质上的软件。然而,本领域的普通技术人员能容易 地理解,全部程序和/或其一部分或者可由除处理器1112之外的装置来执行和/或 以公知方式包含在固件或专用硬件中。例如,锁管理器170和/或锁管理器200可 由软件、硬件和/或固件的任一组合来实现。此外,尽管示例程序是参考图4-9所 示的流程图来描述的,但本领域的普通技术人员可以容易地理解,或者可使用实现 此处所描述的示例方法和装置的许多其它方法。例如,参考图4-9所示的流程图, 框的执行顺序可改变,和/或所描述的某些框可改变、消除、组合和/或细分成多个 框。
为更好地理解图2的示例锁管理器200的属性和特性,并更好地理解以下图 4-9的流程图所示的各种进程的操作,实现图1的锁管理器170的示例性现有技术 进程在图3A-3B中示出。具体地,图3A示出了获取对象的锁的示例性现有技术进 程300,而图3B示出了释放对象的锁的示例性现有技术进程350。尽管未示出, 但可使用控制进程来基于执行程序线程的状态确定应调用锁获取和锁释放过程中 的哪一个。
转向图3A,示例性现有技术锁获取进程300始于将对应于与要锁定的对象相 关联的锁的前一锁拥有者的变量/寄存器设为等于锁的当前锁拥有者(框302)。进 程300然后试图通过首先确定任何线程是否已拥有了要锁定的对象的锁(g卩,关于 对象是否存在锁拥有者或者锁拥有者是否被设为NULL值)来试图为当前线程(即, 请求锁的线程)锁定对象(框304)。如果进程300确定不存在任何线程拥有者(框 304),且因此对象的锁是未锁定的,则进程300通过将锁拥有者设为表示线程的 值(例如,唯一线程标识符值)来为线程获取锁(框308)。然而,如果进程300 确定锁拥有者已存在(框304),则进程300维持锁拥有者不变。为防止在第一线 程已处于变为锁拥有者的过程中的同时第二线程试图获取锁,通常使用单个原子操 作(诸如属于Intel Itanium处理器家族的处理器上的cmpxchg指令)来实现框302、 304和308。原子操作向线程(和/或多处理器系统中的处理器)提供了在原子操作 的执行期间对共享存储器的排他访问。由此,没有任何其它线程能够修改在其执行 期间由原子操作访问的存储器位置。
在确定了锁拥有者不是NULL (框304)或锁拥有者被定位为当前线程(框308)之后,进程300确定对象的前一锁拥有者是否为NULL值(对应于当前线程 在框308处获取锁的情况)(框312)。如果前一锁拥有者是NULL值(框312), 则示例进程300结束。然而,如果进程300确定前一锁拥有者不是NULL值(框 312),则该迸程确定前一锁拥有者是否为当前线程(对应于当前线程先前已获取 了锁的情况)(框314)。如果前一锁拥有者是当前线程(框314),则进程300 可例如递增与该锁相关联的锁递归计数器,以指示当前线程已经多次获取了对象锁 (框316)。该示例进程300然后结束。
然而,如果进程300确定前一锁拥有者不是当前线程(框314),且因此另一 线程已拥有了该锁,则进程300调用已知的锁竞争过程以允许当前线程在目前的锁 拥有者释放了该锁之后获取该锁(框320)。例如,进程300可使当前线程在执行 循环中自旋或中止执行,直到目前的锁拥有者释放/解锁了对象的锁。在对象锁变 得可用之后,进程300然后可为当前线程获取锁,并且示例进程300然后结束。
转向图3B,示例性现有技术锁释放进程350始于试图通过首先确定当前线程 是否为对象的锁拥有者来为当前线程(即,请求释放的线程)释放对象(框354)。 如果当前线程不是锁拥有者,且因此另一线程目前拥有该锁(框354),则进程350 抛出异常(框358)。在框358处,进程350可使用任何已知的异常处理技术来抛
出指示执行了无效释放尝试(因为不拥有锁的线程试图解锁相关联的对象)的异常。 示例进程350然后结束。
然而,如果当前线程是对象的锁拥有者(框354),则进程350确定与该锁相 关联的锁递归计数器(或类似的递归锁定指示符)是否等于零(或等效地,指示该 锁仅有一个获取当前是活动的)(框362)。如果锁递归计数器等于零(框362), 则进程350例如通过将锁拥有者设为NULL值来为对象的锁解锁(框366)。然而, 如果锁递归计数器不等于零(框362),则进程350递减锁递归计数器(例如,指 示目前锁释放计数到一活动的锁获取)(框370)。在框366或370处的处理完成 之后,示例进程350然后结束。
基于图3A-3B的由示例性现有技术进程300和350提供的理解,可用于实现 图2的示例锁管理器200的示例锁管理器迸程400在图4中示出。示例锁管理器进 程400例如可在当一个或多个线程在同步对象上操作时在这些线程的各种执行阶 段期间调用。例如,示例进程400可被调用以获取或释放对象的锁。
示例锁管理器进程400始于确定要为当前线程在对象的锁上执行的锁定操作 的类型(框404)。有效的锁定操作可包括平衡锁同步(包括平衡锁获取和释放对)、乐观平衡锁同步(包括乐观平衡锁获取和释放对)、未平衡锁获取和未平衡锁释放。
例如,诸如图1的JIT编译器158等JIT编译器可使用控制流图和/或数据流分析来 确定要在程序执行期间的适当点处在对象的锁上执行的锁定操作的类型。JIT编译 器158然后可在框404处输出可由锁管理器200或锁管理器进程400用于作出适当 的锁操作确定的已编译代码。示例进程400可采用任何已知的用于确定锁定操作是 被平衡、乐观平衡还是未平衡的技术,且因此此处不再进一步讨论这些技术。
基于在框404处作出的锁定过程确定,控制然后前进到框406、 408、 412和 416之一。在框406处,锁管理器200对于对象的锁执行平衡同步操作。在框408 处,锁管理器200对于对象的锁执行乐观平衡同步操作。在框412处,锁管理器 200对于对象的锁执行未平衡锁获取操作。在框416处,锁管理器200对于对象的 锁执行未平衡锁释放操作。框406、 408、 412和416处执行的处理分别通过以下提 供的图5A、 5B、 6和7的描述来详细讨论。
在框406、 408、 412或426的处理完成之后,进程400确定需要未来的线程 执行点处的后续释放的至少一个锁定对象是否在待决中(框420)。如果任何锁定 对象为待决(框420),则控制返回到框404并阻止对其的后续操作以允许处理这 些对象的锁(以及要锁定的任何其它对象的锁)。然而,如果没有任何锁定对象为 待决(框420),则进程400确定是否有任何其它对象要锁定(框424)。如果有 其它对象要锁定(框424),则控制返回到框404并阻止对其的后续操作以允许处 理这些对象的锁。然而,如果没有任何其它对象要锁定(框424),则示例进程400 结束。本领域的普通技术人员可以认识到,在框420和/或424处执行的条件操作 可由例如关于程序(或程序的任何线程)是否仍在执行的显式或隐式判断来替换。 如果进程400仍在执行,则控制然后返回到框404以及后续的框406、 408、 412 和416。这一循环可重复,直到进程400 (或所有线程执行)终止。
可用于执行图4的框406处的处理和/或实现图2的平衡锁同步单元218的一 个示例平衡锁同步进程500在图5A中示出。该示例平衡锁同步进程500始于将对 应于锁的前一拥有者的变量/寄存器设为等于当前锁拥有者(框504)。进程500 然后确定一线程是否已经拥有了要锁定的对象的锁(g卩,对于该对象是否存在锁拥 有者或者锁拥有者是否被设为NULL值)(框512)。如果不存 任何线程拥有者 (框512),且因此对象的锁未锁定且锁拥有者被设为NULL值,则进程500通过 将锁拥有者设为表示线程的值(例如,唯一线程标识符值)来为线程获取对象的锁 (框516)。然而,如果进程500确定锁拥有者已存在(框512),则进程500维持锁拥有者不变。
为防止第二线程在第一线程已处于变为锁拥有者的过程中的同时试图获取该
锁,通常使用单个原子操作(诸如属于Intel Itanium处理器家族的处理器上的 cmpxchg指令)来实现框504、 512和516。如上所述,原子操作向线程(和/或多 处理器系统中的处理器)提供了在原子操作的执行期间对共享存储器的排他访问。 因此,没有任何其它线程能够在原子操作执行期间修改由该原子操作访问的存储器 位置。例如,在框504、 512和516处执行的处理可基于以下指令序列在属于Intel Itanium处理器家族的处理器上实现
ar.ccv = mov 0
rl = cmpxch2.acq[r3], r2
在以上指令中,寄存器rl可用于表示前一所拥有者,寄存器r2可用于表示当 前线程,而寄存器r3可持有对应于当前锁拥有者的地址。第一条指令(ar.ccv:mov O)将ar.ccv寄存器设为O(即,NULL值)。第二条指令(rl = cmpxchg2.acq[r3], r2) 是可用于进行以下步骤的原子指令l)将前一锁拥有者设为等于当前锁拥有者(即, rl = [r3]) ; 2)检査当前锁拥有者是否为NULL值(即,[r3]是否等于ar.ccv) ; 3) 如果当前锁拥有者为NULL值(即,如果[r3]等于ar.ccv),则将锁拥有者设为表 示当前线程的值(即,[r3]=r2);以及4)如果当前锁拥有者不是NULL值(即, 如果[r3]不等于ar.ccv),则维持锁拥有者不变(即,维銜r3]不变)。
转向图5A,在确定锁拥有者不为NULL (框512)或锁拥有者被定义为当前 线程(框516)之后,进程500确定对象的前一锁拥有者是否为NULL值(对应于 当前线程在框516处获取了锁的情况)(框520)。如果前一锁拥有者为NULL值 (框520),则控制前进到框524。然而,如果进程500确定前一锁拥有者不是NULL 值(框520),则该进程确定前一锁拥有者是否为当前线程(对应于当前线程先前 已获取了锁的情况)(框526)。如果前一锁拥有者是当前线程(框526),则控 制前进到框524。然而,如果进程500确定前一锁拥有者不是当前线程(框526), 且因此另一线程已拥有该锁,则进程500调用已知的锁竞争过程以允许当前线程在 目前的锁拥有者释放该锁之后获取该锁(框528)。已知的锁竞争过程应当在对象 锁上操作,以使锁的表示/格式在框528的处理完成之后不被更改。另外,进程500 可使当前线程在执行循环中自旋或中止执行,直到目前的锁拥有者释放/解锁该对 象的锁。在对象的锁变为可用之后,进程500然后可为当前线程获取该锁。另外, 控制前进到框532,在该处,进程500将前一锁拥有者复位到NULL值,因为在框
17528的锁竞争过程完成之后将没有前一锁拥有者。控制然后前进到框524。
在框524处,当前线程执行对应于锁定对象的代码的临界段。在代码的该临 界段的执行完成之后,进程500将锁的锁拥有者复位到前一锁拥有者(框540)。 通过将锁拥有者复位到等于前一锁拥有者,进程500要么在前一拥有者为NULL 值的情况下将锁解锁,要么在前一锁拥有者是当前线程的情况下为当前线程维持该 锁。示例进程500然后结束。
可用于执行图4的框408处执行的处理和/或实现图2的乐观平衡锁同步单元 220的示例乐观平衡锁同步进程550在图5B中示出。因为在图5A和5B的流程图 之间有许多重叠,因此具有基本相同的功能的框此处不再描述。相反,感兴趣的读 者可以参考图5A中相应的框以及上文其相关联的描述。为在该参照行动中帮助读 者,具有基本相似功能的框在图5A和5B中用相同的参考标号来标记。
图5B的示例乐观平衡锁同步进程550始于将有效性标志初始化为TRUE(真) (框558)。如将从下文中清楚的,该有效性标志用于指示待决的乐观平衡锁释放 的有效性状态。控制然后前进到框504,并阻止对其的进程500可用于为当前线程 获取锁的后续操作。框504、 512、 516、 520、 526、 528和532的详细描述在上文 中作为图5A的示例进程500的详细描述的一部分提供。在进程550为当前线程获 取锁之后,控制前进到框524。
在框524处,当前线程执行要求锁定对象的代码的临界段。在代码的该临界 段的执行完成之后,控制前进到框562,此处进程550试图通过首先确定相应的待 决乐观释放的有效性标志是否指示释放是有效的,来释放对象的锁的最近一次乐观 平衡锁获取。如果有效性标志为TRUE (框562),且因此待决的乐观平衡释放对 应于解锁或维持锁(在递归锁定的情况下),则进程550将锁的锁拥有者复位成前 一锁拥有者(框540)。然而,如果有效性标志为FALSE (假)(框562),且因 此对应于无效的乐观平衡释放,则进程550使用任何已知的异常处理技术抛出异常 (框566)。然后,在框540或566处的处理完成之后,示例进程550结束。
为支持递归乐观平衡锁同步(以及以下讨论的未平衡锁获取和释放过程), 锁管理器200和/或锁管理器400利用一个或多个同步映射图来为调用乐观平衡锁 同步的方法(例如,JAVA方法)的每一实例跟踪待决的乐观平衡同步操作。在该 方法中, 一个示例同步映射图可包括锁地址、前一锁拥有者值和每一乐观平衡同步 操作的有效性标志。另外,同步映射图可包括对应于要求锁定对象的代码的临界段 的地址范围。同步映射图的每一条目可被储存在对应于引起乐观平衡锁同步(由此支持由对同一方法的嵌套调用引起的递归锁获取)的方法的特定实例的调用帧内的 调用栈中。如以下详细讨论的,未平衡锁获取和释放操作可以遍历同步映射图以确 定在调用栈上待决的乐观平衡同步操作(特别是乐观平衡释放操作)的个数和类型 并按需修改这些操作。
可用于执行图4的框412处的处理和/或实现图2的未平衡锁获取单元224的 一个示例未平衡锁获取进程600在图6A-6B中示出。示例未平衡锁获取进程600 始于遍历例如由图5B的示例乐观平衡锁同步进程550或图2的乐观平衡锁同步单 元220维护的同步映射图以对待决的有效乐观平衡释放的个数进行计数,并确定是 否有任何无效的乐观平衡释放正处于待决(图6A的框604)。用于实现框604处 执行的处理的一个示例过程在图8中示出,且在下文中详细讨论。
在框604处的处理完成之后,进程600将对应于锁的前一锁拥有者的变量/寄 存器设为等于当前锁拥有者(框608)。进程600然后确定是否有一线程已经拥有 要锁定对象的锁(即,对该对象是否存在锁拥有者或者锁拥有者是否被设为NULL 值)(框612)。如果没有任何线程拥有者存在(框612),且因此对象的锁未被 锁定且锁拥有者被设为NULL值,则进程600通过将锁拥有者设为表示线程的值 (例如,唯一线程标识符值)来为线程获取对象的锁(框616)。然而,如果进程 600确定已经存在锁拥有者(框612),则进程600维持锁拥有者不变。
如上所述,为防止第二线程在第一线程已处于变为锁拥有者的过程中的同时 试图获取该锁,通常使用单个原子操作(诸如属于Intel处理器家族的处理器上的 cmpxchg指令)来实现框608、 612和616。原子操作向线程(和/或多处理器系统 中的处理器)提供在原子操作的执行期间对共享存储器的排他访问。由此,没有任 何其它线程能够修改在原子操作执行期间由该原子操作访问的存储器位置。
返回到图6A,在确定锁拥有者不为NULL (框612)或锁拥有者被定义为当 前线程(框616)后,则进程600确定对象的前一锁拥有者是否为NULL值(对应 于当前线程已在框616处获取了锁的情况)(框620)。如果前一锁拥有者是NULL 值(框620),则控制前进到图6B的框624。然而,如果进程600确定前一锁拥 有者不是NULL值(框620),则该进程确定前一锁拥有者是否为当前线程(对应 于当前线程先前已获取了锁的情况)(框625)。如果前一锁拥有者是当前线程(框 625),则控制前进到图6B的框624。然而,如果进程600确定前一锁拥有者不是 当前线程(框625),且因此另一线程已拥有该锁,则进程600调用已知的锁竞争 过程以允许当前线程在目前的锁拥有者释放锁之后获取该锁(框626)。已知的锁竞争过程应当在对象锁上操作,以使锁的表示/格式在框626的处理完成之后不被 更改。另外,进程600可使当前线程在执行循环中自旋或中止执行,直到目前的锁 拥有者释放/解锁该对象的锁。在对象的锁变为可用之后,进程600然后可为当前 线程获取锁。另外,控制前进到框627,此处进程600将前一锁拥有者复位到NULL 值,因为在框626的锁竞争过程完成之后将没有前一锁拥有者。控制然后前进到图 6B的框624。
在图6B的框624处,进程600确定锁递归计数器是否被设为等于0。锁递归 计数器(或类似的指示符)可用于指示未被未平衡锁释放抵消的活动的未平衡锁获 取的个数。如果锁递归计数器等于O (框624),且因此没有任何其它活动的未平 衡锁获取,则进程600确定框604处执行的处理是否返回了非零的待决有效乐观平 衡释放的个数(框62S)。如果待决的有效乐观平衡释放的个数不为零(框62S), 且因此有至少一个待决的有效乐观平衡释放,则进程600将最外面的(S卩,最旧的) 待决有效乐观平衡释放的状态从解锁操作改为维持锁操作(框632)。要求该修改 是因为其它的未平衡锁获取会导致在执行最后一个待决的乐观平衡锁释放时存在 剩余的活动锁获取。由此,进程600现在必须使得锁要被维持以与剩余的活动锁获 取相对应。用于实现框632处执行的处理的一个示例过程在图9中示出,并在下文 详细讨论。
如果锁递归计数器不为零(框624),且因此其它未平衡锁获取是活动的,或 者如果同步映射图中没有有效的乐观平衡释放(框628),或者如果框632处的处 理完成,则控制然后前进到框636。在框636处,进程600确定框604处执行的处 理是否指示了有任何待决的无效乐观平衡释放的存在。如果有任何无效乐观平衡释 放待决(框636),则进程600将最里面(即,最新近的)待决无效乐观平衡释放 的状态从抛出异常操作改为将锁解锁操作(框640)。无效乐观平衡释放将总是在 所有的待决有效乐观平衡释放已被执行之后发生。由此,要求这一修改是因为其它 未平衡锁获取将抵消第一个无效乐观平衡锁释放。由此,进程600现在必须使得要 对第 一个无效乐观平衡释放将锁解锁以与其它活动锁获取相对应。用于实现框640 处执行的处理的示例过程在图9中示出,并在下文中详细讨论。
然而,如果没有任何待决的无效乐观平衡释放(框636),则进 600递增锁 递归计数器以指示已执行了未平衡锁获取(且因此是活动的),且它没有被前一未 平衡锁释放抵消(框644)。(如果已执行了前一未平衡释放,则有至少一个待决 的无效乐观平衡释放,且控制将前进到框640。)在框640或644处的处理完成之后,图6的示例进程结束。
可用于执行图4的框416处的处理和/或实现图2的未平衡锁释放单元228的 示例未平衡锁释放进程700在图7中示出。示例未平衡锁释放进程700始于确定当 前线程是否为要释放的对象的锁拥有者(框704)。如果当前线程不是锁拥有者(框 704),则进程700可使用任何已知的异常处理技术来抛出指示线程不适当地试图 释放它不拥有的锁的异常(框708)。示例进程700然后结束。
然而,如果当前线程是锁拥有者(框704),则对于对象的锁执行至少一个乐 观平衡锁同步或未平衡锁获取。由此,进程700遍历例如由图5A的示例乐观平衡 锁同步进程550或图2的乐观平衡锁同步单元220维护的同步映射图以对待决的有 效乐观平衡释放的个数计数(框712)。用于实现框712处执行的处理的一个示例 过程在图8中示出,且在下文详细讨论。进程700然后通过将框712处返回的待决 的有效乐观平衡释放的个数(对应于活动的乐观平衡锁获取的个数)和锁递归计数 器(例如,由图6A-6B的示例未平衡锁获取进程600更新以指示没有被未平衡锁 释放抵消的活动未平衡锁获取的个数)相加,然后减去1来确定实际的递归计数器 (对应于比在锁上仍活动的乐观平衡和未平衡获取的总数少1的值)(框716)。
接着,进程700确定实际递归计数器是否等于零,且因此,仅有一个活动的 乐观平衡获取或一个活动的未平衡获取(框720)。由此,如果实际递归计数器等 于零(框720),则进程700将对象的锁解锁,作为在单个活动的锁获取之后执行 未平衡释放操作的结果(框724)。然而,如果实际递归计数器大于零(框720), 则进程700确定锁递归计数器是否等于1 (框728)。如果锁递归计数器等于l, 则有一个活动的未平衡锁获取和至少一个活动的乐观平衡锁获取(以及相应的有效 乐观平衡释放)。由此,如果锁递归计数器等于l,则进程700将最外面(即,最 旧的)待决有效乐观平衡释放的状态从维持锁操作改为解锁操作(框732)。要求 这一修改是因为未平衡锁释放对先前引起将最外面的待决有效乐观平衡锁改为对 应于维持锁状态的未平衡锁获取进行计数。由此,进程700必须使最外面的待决有 效乐观平衡释放返回到其原始的解锁状态。用于实现框732处执行的处理的示例过 程在图9中示出,且在下文中详细讨论。
然而,如果锁递归计数器不等于l (框728),则进程700确定锁递归计数器 是否等于零(框736)。如果锁递归计数器等于零(框736),则有至少两个待决 的有效乐观平衡释放(因为实际递归计数器在框720处被确定为大于零)。由此, 如果递归计数器等于零,则进程700将下一个最外面(即,次旧)的待决有效乐观平衡释放的状态从维持锁操作改为解锁操作(框740)。要求这一修改是因为未平
衡锁释放会导致在对所有的活动锁获取计数之后存在将会将对象的锁解锁的一个
额外的锁释放。由此,进程700必须将下一个最外面的待决有效乐观平衡释放改为 解锁状态,因为此时所有的活动获取都由该释放来计数。用于实现框740处执行的 处理的示例过程在图9中示出,且在下文中详细讨论。
在框724、 732或740处的处理完成之后,控制前进到框744,此处进程700 确定锁递归计数器是否等于零。如果锁递归计数器等于零(框744),则有至少一 个待决的乐观平衡释放。由此,如果锁递归计数器等于零,则进程700将最外面(即, 最旧)的待决有效乐观平衡释放的状态从解锁操作改为抛出异常操作。要求这一修 改是因为额外的未平衡锁释放会导致在对所有的活动获取计数之后有一个额外的 释放。由此,进程700必须将最外面的待决有效乐观平衡释放改为抛出异常状态, 因为此时所有的活动获取都将由释放计数,且然后另一释放将由不是对象的锁拥有 者的线程来执行。用于实现框748处执行的处理的一个示例过程在图9中示出,且 在下文详细讨论。
然而,如果锁递归计数器大于零(框744),则进程700递减锁递归计数器以 指示活动的未平衡锁获取之一已由未平衡锁释放计数(框752)。在框748或752 处的处理完成之后,示例进程700然后结束。
用于对同步映射图(例如,由图5A的乐观平衡锁同步进程550或图2的乐观 平衡锁同步单元220维护的同步映射图)中的待决有效乐观平衡释放的数目计数并 确定是否有任何无效的乐观平衡释放处于待决的示例进程800在图8中示出。示例 进程800可由例如分别在图6和7中的示例未平衡锁获取进程600和/或未平衡锁 释放进程700使用。具体地,示例进程800可由示例进程600和/或700调用以实 现图6的框604和/或图7的框712执行的处理。示例进程800也可用于实现图2 的乐观平衡释放跟踪器232。
转向图8,示例进程800始于例如通过获得与正被处理的对象相关联的锁 字的 地址来获得对应于该对象的锁(框804)。进程800然后将对应于待决有效乐观平 衡释放的个数的计数器初始化为零,并将对应于任何待决的无效乐观平衡释放的存 在的标志初始化为FALSE (框808)。在该初始化完成之后,进程800开始迭代 通过调用栈中的每一调用帧以确定对应于在框804处选择的对象锁的乐观平衡释 放的存在。
进程800始于通过获得调用栈上的下一调用帧来迭代通过调用栈的调用帧(框812)。进程800然后获得储存在正被处理的调用帧中的下一待决乐观平衡释放(框 816)。接着,进程800确定待决的乐观平衡释放是否对应于正被处理的对象锁(框 820)。如果待决的乐观平衡释放不对应于正被处理的对象锁(框820),则进程 800确定对应于正被处理的待决的乐观平衡释放的有效性标志是否被设为TRUE (框824)。如果该有效性标志为TRUE (框824),则进程800递增对应于待决 的有效乐观平衡释放的个数的计数器(框82S)。
在框828处的处理完成之后,或者如果乐观平衡释放不对应于正被处理的对 象锁(框820),则进程800确定正被处理的乐观平衡释放是否为正被处理的调用 帧中的最后一个释放(框832)。如果该乐观平衡释放不是最后一个释放(框832), 则控制然后返回到框816,此处进程800获得调用帧中要处理的下一个乐观平衡释 放。然而,如果该乐观平衡释放是最后一个释放(框832),则进程800确定正被 处理的调用帧是否为调用栈中的最后一个调用帧(且因此是否到达了同步映射图的 结尾)(框836)。如果该调用帧不是最后一个调用帧(框836),则控制返回到 框812,此处进程800获取要处理的下一个调用帧。
如果在框824处,正被处理的乐观平衡释放的有效性标志被确定为FALSE, 则进程800中断迭代通过调用栈的每一调用帧的控制流程,并分支到框840。在框 840处,进程800将对应于任何待决的无效乐观平衡释放的存在的标志设为 FALSE。然后,在框840处的处理完成之后,或者如果正被处理的调用帧是调用 栈中的最后一个调用帧(框836),则进程800返回待决的有效乐观平衡释放的个 数以及指示任何待决的无效乐观平衡释放的存在与否的标志。示例进程800然后结 束。
修改同步映射图(例如,由图5A的乐观平衡锁同步进程550或图2的乐观平 衡锁同步单元220维护的同步映射图)中待决的乐观平衡释放的状态的示例进程 900在图9中示出。示例进程900可由例如分别在图6和7中的示例未平衡锁获取 进程600和/或未平衡锁释放进程700使用。具体地,示例进程900可由示例进程 600和/或700调用以实现由图6的框632和634以及图7的框732、 740和748中 的任一个或所有执行的处理。示例进程900也可用于实现图2的乐观平衡同步状态 修改器236。
转向图9,示例进程900始于例如通过获得与正被处理的对象相关联的锁字的 地址来获得对应于该对象的锁(框904)。进程900还获得到同步映射图中要处理 的待决的乐观平衡释放的索引以及要在索引的释放上执行的动作(框904)。对象锁、待决的乐观平衡释放索引和期望的动作可例如由调用示例进程900的调用进程
来提供。控制然后前进到框908,此处进程900开始在对应于对象锁的索引的乐观 平衡释放上执行期望的动作。
在框908处,进程900确定期望的动作是否对应于索引的平衡释放的维持锁 状态。如果期望的动作对应于维持锁状态(框908),则进程900将索引的乐观平 衡释放的前一锁拥有者设为等于当前线程(框912)。由此,当索引的乐观平衡释 放执行时,锁拥有者将被设为前一锁拥有者,这仍将是当前线程,由此维持了锁。 进程900还将索引的乐观平衡释放的有效性标志设为TRUE (框916),且示例进 程900结束。
如果在框908处,期望的动作不对应于维持锁状态,则进程900确定期望的 动作是否对应于索引的乐观平衡释放的解锁状态(框920)。如果期望的动作对应 于解锁状态(框920),则进程900将索引的乐观平衡释放的前一锁拥有者设为 NULL值(指示没有线程拥有者)(框924)。由此,当索引的平衡释放执行时, 锁拥有者将被设为前一锁拥有者,这将为NULL值,由此将该锁解锁。进程900 还将索引的乐观平衡释放的有效性标志设为TRUE (框928),且示例进程900结 束。
如果在框920处,期望的动作不对应于解锁状态(且基于框908处的处理, 也不对应于维持锁状态),则进程900将索引的乐观平衡释放的有效性标志设为 FALSE (框932),因为期望的动作对应于抛出异常状态。示例进程900然后结束。
为帮助理解此处所描述的方法、装置和制品,图2的示例锁管理器和/或图5A、 5B、 6A-6B、 7、 8和9的示例进程500、 550、 600、 700、 800和900的示例操作 分别在图10A-10B中示出。图10A-10B的示例操作对应于单个线程在单个对象的 锁上执行的一系列锁获取和释放。锁定序列由要求为方法执行锁定对象的所调用的 各种方法A到F产生。在锁定序列中的每一阶段,图IOA-IOB示出了在相应的锁 定操作完成时对象锁1010的状态以及同步映射图1020的内容。对象锁1010包括 锁拥有者和锁递归计数器。同步映射图1020的每一条目包括前一锁拥有者和有效 性标志以及其它可能的信息。
该示例操作在图10A的阶段1030处开始,其中对象被解锁(即,对应于等于 NULL值的锁拥有者和等于零的递归计数器),且方法A使得在锁上执行乐观平 衡锁同步。根据示例进程550,更新对象锁以将锁拥有者分 给当前线程并且递归 计数器维持为零。同步映射图包括对应于第一个乐观平衡释放且具有等于NULL值的前一锁拥有者和等于TRUE(g卩,对应于解锁状态)的有效性标志的一个条目。
接着,在阶段1035处,方法B使得在对象的锁上执行另一乐观平衡锁同步(对 应于递归锁定情形)。根据示例进程550,对象锁的状态维持不变,且将另一条目 添加到对应于该第二个乐观平衡释放的同步映射图中。该新条目的锁的前一拥有者 被设为等于表示线程的值(因为锁已由该线程拥有),且有效性标志被设为TRUE (即,对应于维持锁状态)。
接着,在阶段1040处,方法C使得在对象锁上执行未平衡锁获取。根据示例 进程600,将锁递归计数器递增到值1。另外,通过将前一锁拥有者设为表示当前 线程的值,并将有效性标志设为TRUE,将最外面的待决的有效乐观平衡释放从解 锁状态改为维持锁状态。
接着,在阶段1045处,方法D使得在对象的锁上执行另一乐观平衡锁同步(对 应于递归锁定情形)。根据示例进程550,对象锁的状态维持不变,且将另一条目 添加到对应于该第三个乐观平衡释放的同步映射图中。该新条目的锁的前一拥有者 被设为等于表示线程的值(因为锁已被该线程拥有),且有效性标志被设为TRUE (即,对应于维持锁状态)。
接着,在阶段1050处,方法E使得在对象锁上执行未平衡锁释放。根据示例 进程700,实际的递归计数器被确定为具有值3 (对应于3个待决的有效乐观平衡 释放以及等于1的递归计数器)。由此,通过将前一锁拥有者设为NULL值,并 将有效性标志设为TRUE,将最外面的待决的有效乐观平衡释放从维持锁状态改为 解锁状态。另外,锁递归计数器递减到值O。
接着,在图10B的阶段1055处,方法F使得在对象锁上执行另一未平衡锁释 放。根据示例进程700,实际的递归计数器被确定为具有值2 (对应于三个待决的 有效乐观平衡释放以及等于零的递归计数器)。由此,通过将前一锁拥有者设为 NULL值并将有效性标志设为TRUE,将下一最外面的待决的有效乐观平衡释放从 维持锁状态改为解锁状态。另外,通过将有效性标志设为FALSE,将最外面的待 决的有效乐观平衡释放从解锁状态改为抛出异常状态。
接着,在框1060处,方法D的临界段完成执行,导致处理三个待决的乐观平 衡释放中最里面的一个。乐观平衡释放进程始于图IOB所示由当前线程拥有的锁。 然后,根据示例进程550,处理具有维持锁状态的最里面的乐观待决平衡释放。
接着,在框1065处,方法B的临界段完成执行,导致处理两个待决的乐观平 衡释放的最里面的一个。作为在阶段1060处处理前一平衡释放的结果,对象锁仍由当前线程拥有。然后,根据示例进程550,处理具有解锁状态的最里面的待决平
衡释放。
最后,在框1070处,方法A的临界段完成执行,导致处理剩余的待决乐观平 衡释放。作为在阶段1065处处理前一平衡释放的结果,对象锁不被拥有(例如, 被设为NULL值)。然后,根据示例进程550,处理具有抛出异常状态的剩余的待 决平衡释放,由此导致抛出异常。
图11是能够实现此处所公开的装置和方法的示例计算机或处理系统1100的 框图。计算机1100可以是例如服务器、个人计算机、个人数字助理(PDA)、因 特网设备、或任何其它类型的计算设备。
当前示例的系统1100包括处理器1112。例如,处理器1112可以由来自 Pentium⑧家族、Itanium⑧家族或XScale⑧家族的一个或多个Intel⑧微处理器来实现。 当然,来自其它家族的其它处理器也是合适的。包括一个或多个微处理器的处理器 1112可用于实现图1的示例使用环境100、图2的示例锁管理器200和/或分别在 图5A、 5B、 6A-6B、 7、 8和9中的示例进程500、 550、 600、 700、 800和卯0。
处理器1112经由总线1118与包括易失性存储器1114和非易失性存储器1116 的主存储器通信。易失性存储器1114可以由静态随机存取存储器(SRAM)、同 步动态随机存取存储器(SDRAM)、动态随机存取存储器(DRAM) 、 RAMBUS 动态随机存取存储器(RDRAM)和/或任何其它类型的随机存取存储器设备来实现。 非易失性存储器1116可以由闪存和/或任何其它期望类型的存储器设备来实现。对 主存储器1114、 1116的访问通常由存储器控制器(未示出)以常规的方式来控制。
计算机1110还包括常规的接口电路1120。接口电路1120可由任何类型的公 知接口标准,诸如以太网接口、通用串行总线(USB)、和/或第三代输入/输出(3GI0) 接口来实现。
一个或多个输入设备1122连接到接口电路1120。输入设备1122允许用户将 数据和命令输入到处理器1122中。输入设备可由例如键盘、鼠标、触摸屏、跟踪 垫、跟踪球、Isopoint和/或语音识别系统来实现。
一个或多个输出设备1124也连接到接口电路1120。输出设备1124可例如由 显示设备(例如,液晶显示器、阴极射线管显示器(CRT))、由打印机和/或由 扬声器来实现。接口电路1120由此通常包括图形驱动卡。
接口电路1120还包括诸如调制解调器或网络接口卡等通信设备以便于经由网 络1126 (例如,以太网连接、数字用户线(DSL)、电话线、同轴电缆、蜂窝电
26话系统等)与外部计算机交换数据。
计算机1100还包括用于储存软件和数据的一个或多个大容量存储设备1128。 这一大容量存储设备1128的示例包括软盘驱动器、硬盘驱动器、光盘驱动器和数 字多功能盘(DVD)驱动器。大容量存储设备1128和/或易失性存储器1114可用 于例如储存由分别在图5A、 5B、 6A-6B和7中的进程500、 550、 600和700维护 和修改的同步映射图。
作为诸如图11的设备等系统中对实现此处描述的方法和/或装置的替换,此处 描述的方法和/或装置可替换地嵌入在诸如处理器和/或ASIC (专用集成电路)等 结构中。
从以上内容中,本领域的普通技术人员可以理解,以上公开的方法和装置可 以在静态编译器、受管运行时环境即时(JIT)编译器、和/或直接在微处理器的硬 件中实现以在执行各种程序时实现性能优化。
尽管此处描述了某些特定示例方法、装置和制品,但本发明的覆盖范围不限 于此。相反,本专利覆盖在文字上或在等效技术方案的原则下清楚地落入所附权利 要求书的范围之内的所有方法、装置和制品。
权利要求
1.一种维持在受管运行时环境中的对象的锁的乐观平衡同步的状态信息的方法,所述方法包括存储状态信息,所述状态信息包括与要在所述对象的锁上执行的每个待决乐观平衡同步对应的每个待决乐观平衡释放操作的状态,每个待决乐观平衡同步包括各自成对的获取和释放操作,在这些操作中会出现未知数目的未成对锁定操作;以及当在所述锁上执行后续未成对锁定操作时,修改第一待决乐观平衡释放操作的第一存储状态,但当在所述锁上执行后续乐观平衡同步时,不修改任何待决乐观平衡释放的任何存储状态,包括第一待决乐观平衡释放操作的第一存储状态。
2. 如权利要求l所述的方法,其特征在于,所述未成对锁定操作的未知数目 大于或等于0。
3. 如权利要求1所述的方法,其特征在于,进一步包括使用存储的状态信息 来跟踪所述锁的后续递归的乐观平衡同步,而不需要对所述锁的先前递归的乐观平 衡同步计数。
4. 如权利要求3所述的方法,其特征在于,进一步包括处理存储的状态信息以便仅当所述后续未成对锁定操作在所述锁上执行时才对先前递归乐观平衡同步计数。
5. 如权利要求1所述的方法,其特征在于,每个待决乐观平衡释放操作的每个存储状态包括所述锁的先前锁拥有者和指示所述各自的待决乐观平衡释放操作 是有效还是无效的有效性标志。
6. 如权利要求5所述的方法,其特征在于,进一步包括估计包括在所述第一 待决乐观平衡释放操作的第一存储状态中的所述有效性标志以执行所述第一待决 乐观平衡释放操作。
7. 如权利要求6所述的方法,其特征在于,进一步包括通过下述步骤执行所 述第一待决乐观平衡释放操作当所述有效性标志设定为有效指示时,复位所述锁的当前锁拥有者为所述锁的先前锁拥有者;以及当所述有效性标志设定为无效指示时,抛出异常。
8. 如权利要求5所述的方法,其特征在于,当在所述锁上执行后续未成对锁 定操作时,修改第一待决乐观平衡释放操作的第一存储状态包括当由所述存储的 状态信息表示的有效待决乐观平衡释放操作的数目大于0且所述未成对锁定操作是未成对锁获取操作时,将所述第一存储状态中包括的先前锁拥有者改为对应于执 行所述未成对锁定操作的当前线程。
9. 如权利要求5所述的方法,其特征在于,当在所述锁上执行后续未成对锁 定操作时,修改第一待决乐观平衡释放操作的第一存储状态包括当所述有效性标志预先被设定为无效指示且所述未成对锁定操作是未成对锁获取操作时,设定包括 在所述第一存储状态中的有效性标志为有效指示。
10. 如权利要求5所述的方法,其特征在于,当在所述锁上执行后续未成对锁 定操作时,修改第一待决乐观平衡释放操作的第一存储状态包括当所述未成对锁 定操作是未成对锁释放操作时,将所述第一存储状态中包括的至少一个先前锁拥有 者改为NULL值,或将所述第一存储状态中包括的所述有效性标志设定为无效指示。
11. 如权利要求5所述的方法,其特征在于,所述第一待决乐观平衡释放操作 与第一待决乐观获取操作成对,且进一步包括通过设定所述第一待决乐观平衡释 放操作的第一存储状态中的有效性标志为有效指示来执行所述第一待决乐观获取 操作。
12. —种维持在受管运行时环境中的对象的锁的乐观平衡同步的状态信息的 设备,所述设备包括用于存储状态信息的存储器,所述状态信息包括与要在所述对象的锁上执行 的每个待决乐观平衡同步对应的每个待决乐观平衡释放操作的状态,每个待决乐观平衡同步包括各自成对的获取和释放操作,在这些操作中会出现未知数目的未成对 锁定操作;以及乐观平衡同步状态修改器,当在所述锁上执行后续未成对锁定操作时,所述乐 观平衡同步状态修改器用于修改第一待决乐观平衡释放操作的第一存储状态,但当 在所述锁上执行后续乐观平衡同步时,所述乐观平衡同步状态修改器用于不修改任 何待决乐观平衡释放的任何存储状态,包括第一待决乐观平衡释放操作的第一存储 状态。
13. 如权利要求12所述的设备,其特征在于,所述未成对锁定操作的未知数 目大于或等于0。
14. 如权利要求12所述的设备,其特征在于,进一步包括乐观平衡锁同步单 元,来跟踪所述锁的后续递归的乐观平衡同步,而不需要对所述锁的先前递归的乐 观平衡同步计数。
15. 如权利要求12所述的设备,其特征在于,每个待决乐观平衡释放操作的 每个存储状态包括所述锁的先前锁拥有者和指示所述各自的待决乐观平衡释放操 作是有效还是无效的有效性标志。
16. 如权利要求15所述的设备,其特征在于,当在所述锁上执行后续未成对 锁定操作时,所述乐观平衡同步状态修改器修改第一待决乐观平衡释放操作的第一 存储状态包括当由所述存储的状态信息表示的有效待决乐观平衡释放操作的数目 大于0且所述未成对锁定操作是未成对锁获取操作时,所述乐观平衡同步状态修改 器将所述第一存储状态中包括的先前锁拥有者改为对应于执行所述未成对锁定操 作的当前线程。
17. 如权利要求15所述的设备,其特征在于,当在所述锁上执行后续未成对 锁定操作时,所述乐观平衡同步状态修改器修改第一待决乐观平衡释放操作的第一 存储状态包括当所述有效性标志预先被设定为无效指示且所述未成对锁定操作是 未成对锁获取操作时,所述乐观平衡同步状态修改器设定包括在所述第一存储状态 中的有效性标志为有效指示。
18. 如权利要求15所述的设备,其特征在于,当在所述锁上执行后续未成对 锁定操作时,所述乐观平衡同步状态修改器修改第一待决乐观平衡释放操作的第一 存储状态包括当所述未成对锁定操作是未成对锁释放操作时,所述乐观平衡同步 状态修改器将所述第一存储状态中包括的至少一个先前锁拥有者改为NULL值, 或将所述第一存储状态中包括的所述有效性标志设定为无效指示。
19. 一种维持在受管运行时环境中的对象的锁的乐观平衡同步的状态信息的系 统,所述系统包括用于存储状态信息的装置,所述状态信息包括与要在所述对象的锁上执行的 每个待决乐观平衡同步对应的每个待决乐观平衡释放操作的状态,每个待决乐观平 衡同步包括各自成对的获取和释放操作,在这些操作中会出现未知数目的未成对锁定操作;以及当在所述锁上执行后续未成对锁定操作时,用于修改第一待决乐观平衡释放 操作的第一存储状态的装置,但当在所述锁上执行后续乐观平衡同步时,用于不修 改任何待决乐观平衡释放的任何存储状态,包括第一待决乐观平衡释放操作的第一存储状态的装置。
20.如权利要求19所述的系统,其特征在于,进一步包括用于使用存储的状态信息来跟踪所述锁的后续递归的乐观平衡同步,而不需要对所述锁的先前递归的 乐观平衡同步计数的装置。
全文摘要
公开了用于受管运行时环境的线程同步方法和装置。此处公开的一个示例方法包括确定要在对应于对象的锁上执行的一组锁定操作;执行初始锁定操作,该初始锁定操作包括锁的平衡同步和在初始锁定操作不是未平衡的情况下锁的乐观平衡同步中的至少一个;以及如果初始锁定操作是活动的且包括乐观平衡同步,则该方法还包括在如果后续锁定操作未被平衡,则修改对应于乐观平衡同步的待决的乐观平衡释放的状态。
文档编号G06F9/46GK101615138SQ20091016054
公开日2009年12月30日 申请日期2004年8月13日 优先权日2004年6月3日
发明者A-R·阿德-塔巴塔拜, B·默菲, T·什佩斯曼 申请人:英特尔公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1