用于受管运行时环境的线程同步方法和装置的制作方法

文档序号:6508343阅读:171来源:国知局
专利名称:用于受管运行时环境的线程同步方法和装置的制作方法
技术领域
本发明一般涉及计算机,尤其涉及用于受管运行时环境的线程同步方法和装置。
背景支持多线程应用程序的软件环境,例如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值(对应于未锁定状态),且锁递归计数等于零。
在许多现有技术的对象锁定技术(例如,JVM 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的框图。有用的示例环境100可例如经由如下所述图11的示例处理器系统1100等一个或多个处理器系统来实现。尽管图1的示例对应于基于JAVA的受管运行时环境(MRTE),但本领域的普通技术人员可以理解,此处所描述的示例方法、装置和制品可应用于有用的任何类似的MRTE环境,诸如,例如CLI和相关联的语言C#。
有用的示例环境100包括被描绘为图1中的JAVA虚拟机(JVM)110的MRTE。示例JVM 110动态地将由机器不相关指令表示的程序或字节码114转换成机器相关或本机指令,然后在一个或多个处理器120(诸如以下描述的处理器1112)上执行这些本机指令。JVM 110可通过专用于一个或多个处理器120的操作系统(OS)130,诸如Microsoft Windows OS、UNIX OS、Linux OS等来执行这些本机指令。
在图1的示例中,JVM 110处理储存在多个类文件114中的字节码114。通常,类文件114储存对应于单个JAVA类的字节码114,包括定义类的接口、字段和方法。类文件114可由JAVA编译器134从例如由软件开发员编写的JAVA程序源代码138中创建。JAVA编译器134、相关联的JAVA源代码138和所得的类文件114(或字节码114)在本领域中是公知的,且因此此处不再进一步讨论。
为处理类文件114,示例JVM 110包括类加载器142,用于定位对应于一个或多个特定类的一个或多个特定类文件114,并例如通过将所加载的类文件114的本地映象储存到本地存储器146中来将这些类文件114加载到JVM 110的执行引擎144中。在将加载的类文件114储存在存储器146之前,类加载器142可调用字节码验证器150来验证所加载的类文件114的结构是正确且符合JAVA语言的构造的。在任一情况下,JVM 110的执行引擎144然后使用例如解释器154和/或一个或多个即时(Just-In-Time,JIT)编译器158将所加载的机器不相关字节码转换成机器相关指令。
解释器154将字节码114转换成在目标处理器120上实现字节码114的功能的一组机器相关指令。换言之,解释器154提供仿真层以允许字节码114如同处理器120直接支持JAVA指令集那样在目标处理器120上执行。另一方面,JIT编译器158将一组字节码114编译成一组机器相关指令用于在目标处理器120上执行。各个字节码114的具体功能可能不被确切地转换成机器相关指令,但是所得的一组机器相关指令的总体功能将等效于原始的一组字节码114。由此,JIT编译器158可产生比解释器154更优的代码。然而,解释器154可能比JIT编译器158更易于实现。
为执行优解释器154和/或一个或多个JIT编译器158提供的程序代码,JVM110的执行引擎144可在本地存储器146中定义一个或多个存储区。例如,为支持多个同时线程的执行,JVM 110可在存储器146中为每一线程分配一单独的虚拟程序计数器(pc)寄存器和一单独的JVM栈帧。JVM栈帧可用于储存例如对应于相关联的执行线程的局部变量和部分结果。另外,JVM 110可在本地存储器146中定义对所有线程公用的存储区。例如,这一存储区可包括储存在程序执行期间创建的对象的堆、储存例如用于实现特定类的方法的数据和代码的方法区、以及储存与特定类相关联的常量的运行时常量池。为有效地管理存储器146的运行时部分,JVM110可包括无用信息收集器162,例如用于自动从堆解除对象的分配以释放存储器供随后的程序执行使用。
为支持多个同时线程的执行,JVM 110的执行引擎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的示例中,由每一流程图表示的进程可由一组机器可读指令实现,该组指令可包括供诸如以下结合图11讨论的示例计算机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然后试图通过首先确定任何线程是否已拥有了要锁定的对象的锁(即,关于对象是否存在锁拥有者或者锁拥有者是否被设为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然后确定一线程是否已经拥有了要锁定的对象的锁(即,对于该对象是否存在锁拥有者或者锁拥有者是否被设为NULL值)(框512)。如果不存在任何线程拥有者(框512),且因此对象的锁未锁定且锁拥有者被设为NULL值,则进程500通过将锁拥有者设为表示线程的值(例如,唯一线程标识符值)来为线程获取对象的锁(框516)。然而,如果进程500确定锁拥有者已存在(框512),则进程500维持锁拥有者不变。
为防止第二线程在第一线程已处于变为锁拥有者的过程中的同时试图获取该锁,通常使用单个原子操作(诸如属于Intel Itanium处理器家族的处理器上的cmpxchg指令)来实现框504、512和516。如上所述,原子操作向线程(和/或多处理器系统中的处理器)提供了在原子操作的执行期间对共享存储器的排他访问。因此,没有任何其它线程能够在原子操作执行期间修改由该原子操作访问的存储器位置。例如,在框504、512和516处执行的处理可基于以下指令序列在属于IntelItanium处理器家族的处理器上实现ar.ccv=mov 0r1=cmpxch2.acq[r3],r2在以上指令中,寄存器r1可用于表示前一所拥有者,寄存器r2可用于表示当前线程,而寄存器r3可持有对应于当前锁拥有者的地址。第一条指令(ar.ccv=mov0)将ar.ccv寄存器设为0(即,NULL值)。第二条指令(r1=cmpxchg2.acq[r3],r2)是可用于进行以下步骤的原子指令1)将前一锁拥有者设为等于当前锁拥有者(即,r1=[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值,因为在框528的锁竞争过程完成之后将没有前一锁拥有者。控制然后前进到框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。锁递归计数器(或类似的指示符)可用于指示未被未平衡锁释放偏移的活动的未平衡锁获取的个数。如果锁递归计数器等于0(框624),且因此没有任何其它活动的未平衡锁获取,则进程600确定框604处执行的处理是否返回了非零的待决有效乐观平衡释放的个数(框628)。如果待决的有效乐观平衡释放的个数不为零(框628),且因此有至少一个待决的有效乐观平衡释放,则进程600将最外面的(即,最旧的)待决有效乐观平衡释放的状态从解锁操作改为维持锁操作(框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)。如果锁递归计数器等于1,则有一个活动的未平衡锁获取和至少一个活动的乐观平衡锁获取(以及相应的有效乐观平衡释放)。由此,如果锁递归计数器等于1,则进程700将最外面(即,最旧的)待决有效乐观平衡释放的状态从维持锁操作改为解锁操作(框732)。要求这一修改是因为未平衡锁释放对先前引起将最外面的待决有效乐观平衡锁改为对应于维持锁状态的未平衡锁获取进行计数。由此,进程700必须使最外面的待决有效乐观平衡释放返回到其原始的解锁状态。用于实现框732处执行的处理的示例过程在图9中示出,且在下文中详细讨论。
然而,如果锁递归计数器不等于1(框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递增对应于待决的有效乐观平衡释放的个数的计数器(框828)。
在框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产生。在锁定序列中的每一阶段,图10A-10B示出了在相应的锁定操作完成时对象锁1010的状态以及同步映射图1020的内容。对象锁1010包括锁拥有者和锁递归计数器。同步映射图1020的每一条目包括前一锁拥有者和有效性标志以及其它可能的信息。
该示例操作在图10A的阶段1030处开始,其中对象被解锁(即,对应于等于NULL值的锁拥有者和等于零的递归计数器),且方法A使得在锁上执行乐观平衡锁同步。根据示例进程550,更新对象锁以将锁拥有者分配给当前线程并且递归计数器维持为零。同步映射图包括对应于第一个乐观平衡释放且具有等于NULL值的前一锁拥有者和等于TRUE(即,对应于解锁状态)的有效性标志的一个条目。
接着,在阶段1035处,方法B使得在对象的锁上执行另一乐观平衡锁同步(对应于递归锁定情形)。根据示例进程550,对象锁的状态维持不变,且将另一条目添加到对应于该第二个乐观平衡释放的同步映射图中。该新条目的锁的前一拥有者被设为等于表示线程的值(因为锁已由该线程拥有),且有效性标志被设为TRUE(即,对应于维持锁状态)。
接着,在阶段1040处,方法C使得在对象锁上执行未平衡锁获取。根据示例进程600,将锁递归计数器递增到值1。另外,通过将前一锁拥有者设为表示当前线程的值,并将有效性标志设为TRUE,将最外面的待决的有效乐观平衡释放从解锁状态改为维持锁状态。
接着,在阶段1045处,方法D使得在对象的锁上执行另一乐观平衡锁同步(对应于递归锁定情形)。根据示例进程550,对象锁的状态维持不变,且将另一条目添加到对应于该第三个乐观平衡释放的同步映射图中。该新条目的锁的前一拥有者被设为等于表示线程的值(因为锁已被该线程拥有),且有效性标志被设为TRUE(即,对应于维持锁状态)。
接着,在阶段1050处,方法E使得在对象锁上执行未平衡锁释放。根据示例进程700,实际的递归计数器被确定为具有值3(对应于3个待决的有效乐观平衡释放以及等于1的递归计数器)。由此,通过将前一锁拥有者设为NULL值,并将有效性标志设为TRUE,将最外面的待决的有效乐观平衡释放从维持锁状态改为解锁状态。另外,锁递归计数器递减到值0。
接着,在图10B的阶段1055处,方法F使得在对象锁上执行另一未平衡锁释放。根据示例进程700,实际的递归计数器被确定为具有值2(对应于三个待决的有效乐观平衡释放以及等于零的递归计数器)。由此,通过将前一锁拥有者设为NULL值并将有效性标志设为TRUE,将下一最外面的待决的有效乐观平衡释放从维持锁状态改为解锁状态。另外,通过将有效性标志设为FALSE,将最外面的待决的有效乐观平衡释放从解锁状态改为抛出异常状态。
接着,在框1060处,方法D的临界段完成执行,导致处理三个待决的乐观平衡释放中最里面的一个。乐观平衡释放进程始于图10B所示由当前线程拥有的锁。然后,根据示例进程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和900。
处理器1112经由总线1118与包括易失性存储器1114和非易失性存储器1116的主存储器通信。易失性存储器1114可以由静态随机存取存储器(SRAM)、同步动态随机存取存储器(SDRAM)、动态随机存取存储器(DRAM)、RAMBUS动态随机存取存储器(RDRAM)和/或任何其它类型的随机存取存储器设备来实现。非易失性存储器1116可以由闪存和/或任何其它期望类型的存储器设备来实现。对主存储器1114、1116的访问通常由存储器控制器(未示出)以常规的方式来控制。
计算机1110还包括常规的接口电路1120。接口电路1120可由任何类型的公知接口标准,诸如以太网接口、通用串行总线(USB)、和/或第三代输入/输出(3GIO)接口来实现。
一个或多个输入设备1122连接到接口电路1120。输入设备1122允许用户将数据和命令输入到处理器1122中。输入设备可由例如键盘、鼠标、触摸屏、跟踪垫、跟踪球、Isopoint和/或语音识别系统来实现。
一个或多个输出设备1124也连接到接口电路1120。输出设备1124可例如由显示设备(例如,液晶显示器、阴极射线管显示器(CRT))、由打印机和/或由扬声器来实现。接口电路1120由此通常包括图形驱动卡。
接口电路1120还包括诸如调制解调器或网络接口卡等通信设备以便于经由网络1126(例如,以太网连接、数字用户线(DSL)、电话线、同轴电缆、蜂窝电话系统等)与外部计算机交换数据。
计算机1100还包括用于储存软件和数据的一个或多个大量存储设备1128。这一大容量存储设备1128的示例包括软盘驱动器、硬盘驱动器、光盘驱动器和数字多功能盘(DVD)驱动器。大容量存储设备1128和/或易失性存储器1114可用于例如储存由分别在图5A、5B、6A-6B和7中的进程500、550、600和700维护和修改的同步映射图。
作为诸如图11的设备等系统中对实现此处描述的方法和/或装置的替换,此处描述的方法和/或装置可替换地嵌入在诸如处理器和/或ASIC(专用集成电路)等结构中。
从以上内容中,本领域的普通技术人员可以理解,以上公开的方法和装置可以在静态编译器、受管运行时环境即时(JIT)编译器、和/或直接在微处理器的硬件中以在执行各种程序时实现性能优化。
尽管此处描述了某些特定示例方法、装置和制品,但本发明的覆盖范围不限于此。相反,本专利覆盖在文字上或在等效技术方案的原则下清楚地落入所附权利要求书的范围之内的所有方法、装置和制品。
权利要求
1.一种在受管运行时环境中为线程锁定对象的方法,包括确定要在对应于所述对象的锁上执行的一组锁定操作;执行初始锁定操作,所述初始锁定操作包括对锁的平衡同步和在所述初始锁定操作未被平衡的情况下对锁的乐观平衡同步中的至少一个;以及如果所述初始锁定操作是活动的且包括乐观平衡同步,则所述方法还包括,如果后续的锁定操作未被平衡,则修改对应于所述乐观平衡同步的待决的乐观平衡释放的状态。
2.如权利要求1所述的方法,其特征在于,所述平衡同步和所述乐观平衡同步的至少一个包括执行原子操作以获取锁,其中所述原子操作包括将所述锁的前一锁拥有者设为等于所述锁的锁拥有者;以及如果所述前一锁拥有者是所述线程和空线程之一,则将所述锁的锁拥有者设为表示所述线程的值;以及将所述锁拥有者复位成等于所述前一锁拥有者以及抛出异常以释放锁中的至少一个。
3.如权利要求1所述的方法,其特征在于,所述乐观平衡同步包括设置一有效性标志以指示所述待决的乐观平衡释放是有效的。
4.如权利要求1所述的方法,其特征在于,所述待决的乐观平衡释放的状态包括有效性标志和所述锁的前一锁拥有者中的至少一个,并且其中,所述执行乐观平衡同步包括基于所述待决的乐观平衡释放的状态释放所述锁。
5.如权利要求4所述的方法,其特征在于,释放所述锁包括如果所述有效性标志指示所述待决的乐观平衡释放是有效的,则将所述锁的锁拥有者复位成所述锁的前一锁拥有者。
6.如权利要求5所述的方法,其特征在于,如果所述前一锁拥有者是空线程则将所述锁解锁,且如果所述前一锁拥有者是所述线程,则为所述线程维持所述锁。
7.如权利要求4所述的方法,其特征在于,释放所述锁包括如果所述有效性标志指示所述待决的乐观平衡释放是无效的,则抛出异常。
8.如权利要求1所述的方法,其特征在于,所述乐观平衡同步包括维护一同步映射图以跟踪要在所述锁上执行的一组待决的乐观平衡释放,且其中,所述一组待决的乐观平衡释放对应于所述锁的一组乐观平衡同步。
9.如权利要求8所述的方法,其特征在于,所述一组待决的乐观平衡释放包括一组有效的乐观平衡释放和一组无效的乐观平衡释放。
10.如权利要求9所述的方法,其特征在于,所述一组有效的乐观平衡释放中的一有效的乐观平衡释放对应于等于TRUE的有效性标志、解锁状态和维持锁状态中的至少一个。
11.如权利要求9所述的方法,其特征在于,所述一组无效的乐观平衡释放中的一无效的乐观平衡释放对应于等于FALSE的有效性标志和抛出异常状态中的至少一个。
12.如权利要求9所述的方法,其特征在于,还包括如果所述锁上的后续的锁定操作未被平衡,则执行所述锁的未平衡获取和所述锁的未平衡释放中的至少一个,且其中,执行所述未平衡获取和所述未平衡释放中的至少一个包括确定所述同步映射图中的有效的乐观平衡释放的个数以及所述同步映射图是否包括至少一个无效的乐观平衡释放中的至少一个。
13.如权利要求1所述的方法,其特征在于,修改所述待决的乐观平衡释放的状态包括将所述待决的乐观平衡释放改为对应于解锁状态、维持锁状态和抛出异常状态中的至少一个。
14.如权利要求13所述的方法,其特征在于,所述解锁状态、维持锁状态和抛出异常状态中的至少一个是由所述锁的前一锁拥有者和有效性标志来确定的。
15.如权利要求1所述的方法,其特征在于,确定要在所述锁上执行的一组锁定操作包括确定所述锁上的初始锁定操作是否为所述锁的平衡同步、所述锁的乐观平衡同步、所述锁的未平衡获取和所述锁的未平衡释放中的一个。
16.一种储存机器可读指令的制品,当所述指令被执行时,使得机器确定要在对应于对象的锁上执行的一组锁定操作;执行初始锁定操作,所述初始锁定操作包括所述锁的平衡同步和在所述初始锁定操作未被平衡的情况下所述锁的乐观平衡同步中的至少一个;以及如果所述初始锁定操作是活动的且包括所述乐观平衡同步,则所述指令还使机器在后续锁定操作未被平衡的情况下修改对应于所述乐观平衡同步的待决的乐观平衡释放的状态。
17.如权利要求16所述的制品,其特征在于,所述机器可读指令使机器维护一同步映射图以跟踪要在所述锁上执行的一组待决的乐观平衡释放,并且其中,所述一组待决的乐观平衡释放对应于所述锁的一组乐观平衡同步。
18.如权利要求17所述的制品,其特征在于,所述机器可读指令使机器在所述锁上的后续锁定操作未被平衡的情况下执行所述锁的未平衡获取和所述锁的未平衡释放中的至少一个,并且其中,为执行所述未平衡获取和所述未平衡释放中的至少一个,所述机器可读指令使机器确定所述同步映射图中的有效的待决乐观平衡释放的个数和所述同步映射图是否包括至少一个无效的待决乐观平衡释放中的至少一个。
19.如权利要求17所述的制品,其特征在于,所述机器可读指令使机器在所述锁上的后续锁定操作未被平衡的情况下执行所述锁的未平衡获取和所述锁的未平衡释放中的至少一个,且其中,为执行所述未平衡获取和所述未平衡释放中的至少一个,所述机器可读指令使机器修改所述待决的乐观平衡释放的状态和锁递归计数器中的至少一个。
20.一种用于在受管运行时环境中为线程锁定对象的装置,包括执行对应于所述对象的锁的平衡同步的平衡锁同步单元和执行对应于所述对象的锁的乐观平衡同步的乐观平衡锁同步单元中的至少一个;以及如果所述装置包括所述乐观平衡锁同步单元,则所述装置还包括基于所述锁的未平衡获取和所述锁的未平衡释放中的至少一个的出现修改所述乐观平衡同步单元的状态的乐观平衡同步状态修改器。
21.如权利要求20所述的装置,其特征在于,所述平衡锁同步单元和所述乐观平衡锁同步单元中的至少一个被配置成通过基于所述锁的前一锁拥有者为所述线程和空线程中的一个,将所述锁的前一锁拥有者设为所述锁的锁拥有者,并将所述锁的锁拥有者设为表示所述线程的值,来获取所述锁;以及通过将所述锁拥有者复位成等于所述前一锁拥有者和抛出异常中的至少一个来释放所述锁。
22.如权利要求20所述的装置,其特征在于,所述乐观平衡锁同步单元被配置成基于对应于所述锁的乐观平衡同步的待决的乐观平衡释放的状态进行将所述锁解锁、维持所述锁和抛出异常中的至少一个。
23.如权利要求20所述的装置,其特征在于,所述乐观平衡锁同步单元包括一同步映射图,用于跟踪要在所述锁上执行的一组待决的乐观平衡释放,并且其中,所述一组待决的乐观平衡释放对应于所述锁的一组乐观平衡同步。
24.如权利要求23所述的装置,其特征在于,所述一组待决的乐观平衡释放包括一组有效的乐观平衡释放和一组无效的乐观平衡释放。
25.如权利要求24所述的装置,其特征在于,还包括一乐观平衡释放跟踪器,用于确定所述同步映射图中有效的乐观平衡释放的个数和所述同步映射图是否包括至少一个无效的乐观平衡释放中的至少一个。
26.如权利要求20所述的装置,其特征在于,所述乐观平衡同步包括所述锁的乐观平衡获取和所述锁的待决的乐观平衡释放,并且其中,所述乐观平衡同步状态修改器被配置成将所述待决的乐观平衡释放的状态改为解锁状态、维持锁状态和抛出异常状态中的一个。
27.如权利要求20所述的装置,其特征在于,还包括执行所述锁的未平衡获取的未平衡锁获取单元和执行所述锁的未平衡释放的未平衡释放单元中的至少一个。
28.一种用于在受管运行时环境中为线程锁定对象的系统,包括处理器,所述处理器被配置成确定要在对应于所述对象的锁上执行的一组锁定操作;执行初始锁定操作,所述初始锁定操作包括所述锁的平衡同步和在所述初始锁定操作未被平衡的情况下所述锁的乐观平衡同步中的至少一个;以及如果所述初始锁定操作是活动的且包括所述乐观平衡同步,则所述处理器还被配置成在后续锁定操作未被平衡的情况下修改对应于所述乐观平衡同步的待决的乐观平衡释放的状态;以及存储器,用于储存所述锁的锁拥有者、所述锁的前一锁拥有者和有效性标志中的至少一个。
29.如权利要求28所述的系统,其特征在于,所述存储器被配置成储存一同步映射图,以跟踪要在所述锁上执行的一组待决的乐观平衡释放,并且其中,所述一组待决的乐观平衡释放对应于所述锁的一组乐观平衡同步。
30.如权利要求28所述的系统,其特征在于,为修改所述待决的乐观平衡释放的状态,所述处理器被配置成基于所述锁的前一锁拥有者和所述有效性标志中的至少一个将所述状态改为对应于解锁状态、维持锁状态和抛出异常状态中的至少一个。
全文摘要
公开了用于受管运行时环境的线程同步方法和装置。此处公开的一个示例方法包括确定要在对应于对象的锁上执行的一组锁定操作;执行初始锁定操作,该初始锁定操作包括锁的平衡同步和在初始锁定操作未被平衡的情况下锁的乐观平衡同步中的至少一个;以及如果初始锁定操作是活动的且包括乐观平衡同步,则该方法还包括在如果后续锁定操作未被平衡,则修改对应于乐观平衡同步的待决的乐观平衡释放的状态。
文档编号G06F9/46GK1961292SQ200480043225
公开日2007年5月9日 申请日期2004年8月13日 优先权日2004年6月3日
发明者A-R·阿德-塔巴塔拜, T·什佩斯曼, B·默菲 申请人:英特尔公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1