This disclosure relates generally to computers and, more particularly, to lock reservation methods and apparatus for multi-threaded environments.
Software environments that support multi-threaded applications, for example, JAVA and the European Computer Manufacturers Association (ECMA) Common Language Infrastructure (CLI), typically include a synchronization mechanism for coordinating when one or more threads may access an object. As will be appreciated by those of ordinary skill in the art, a thread refers to a series of processor instructions organized into a single control flow of execution for processing one or more objects. An object is an instance of a class, where a class is a collection of data and methods to operate on such data. In the case of multiple threads of execution, care must be taken to prevent the multiple threads from modifying the same object simultaneously in a way that might place the object in an erroneous state. In particular, a thread may have critical sections that operate on objects that could be accessed simultaneously by another thread. Thus, multi-threaded systems typically provide specialized statements to protect the operation of a thread's critical section from being corrupted by one or more other threads accessing such a shared object during critical section execution.
For example, JAVA source code may include a synchronized statement to protect objects from being accessed simultaneously by different threads. Use of the synchronized statement enables acquisition of an exclusive lock of an object identified by the synchronized statement. Thus, a thread may be prevented from executing a critical section of code until it can obtain an exclusive lock on a particular object identified by a synchronized statement. Moreover, once such a lock is obtained, no other thread can access the locked object, thereby preventing inadvertent corruption of the processing being performed during execution of a critical section of code. Such a locking procedure may be used to ensure that multiple threads cannot access shared objects in a manner that could cause conflicting execution of critical sections of code at the same time. Of course, application of the synchronized statement is generally used in cases where a particular program creates multiple threads to share objects and/or methods. If only one thread ever accesses a particular object and/or method, there is no need to protect it with a synchronized statement.
A synchronized statement in JAVA source code is normally converted to JAVA virtual machine (JVM) instructions, because, as is known in the art, JAVA source code is first compiled into bytecodes (i.e., JVM language) prior to being executed by the JVM. For example, a synchronized statement may be converted to a monitorenter JVM instruction to gain/acquire an exclusive lock on an object. As a complement to the monitorenter instruction, a monitorexit JVM instruction is provided to unlock/release the exclusive lock on the object. Accordingly, if a thread successfully executes the monitorenter instruction upon an object, that thread gains temporary exclusive lock ownership of the object (i.e., it has gained a lock on the object to prevent other threads from accessing the critical sections of code). If another thread, or second thread, attempts to execute the monitorenter instruction upon the same object while the first thread has temporary exclusive ownership of the object, the second thread must wait (e.g., sleep or spin) until the first thread (i.e., the current lock owner) executes the monitorexit instruction to release its exclusive lock of the object.
Two state variables are often used to describe the lock state of an object. The first state variable is a lock owner that corresponds to the thread identifier of the thread that currently owns the lock. The lock owner may be set to a NULL value or a NULL thread for the case in which the lock is not owned by any thread. The second state variable is a lock recursion counter that may be used to indicate the number of times that the lock owner has acquired the lock (to support recursive locking). Typically, the lock state of an object is initialized to have a lock owner equal to a NULL value (corresponding to an unlocked state) and a lock recursion counter equal to zero.
Typically, a lockword is used to represent the lock state of an object. An example, known technique for object locking/synchronization is defined by Kawachiya, et al. in, Lock Reservation: JAVA Locks can mostly do without Atomic Operations,” Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA), 2002, pp. 130-141. Kawachiya, et al. define a technique based on a lockword that may have two modes, namely, a reservation-mode and a base-mode, as indicated by a lockword mode bit. Additionally, a reservation-mode lockword may include the thread identifier state variable and the lock recursion counter state variable. Due to its relatively small size, the reservation-mode lockword may be stored inside a header of the object. In contrast, a base-mode lockword may include a number of data structures to support object locking/synchronization for scenarios in which a reservation-mode lockword may not be sufficient (e.g., in the case of lock contention during which a list of threads waiting to acquire the object lock may be needed). According to Kawachiya, et al., an object is initialized to have a reservation-mode lockword. The locking/synchronization procedure then converts the lockword to the base-mode, for example, when it becomes too large to fit in the object header (e.g., if there is lock contention and a list of waiting threads is required, if the lock recursion counter exceeds the maximum value that may be represented by the reservation-mode lockword, etc.). However, the locking/synchronization procedure does not convert a base-mode lockword back to a reservation-mode lockword (i.e., once the object lockword is converted to a base-mode it remains a base-mode lockword for the remainder of program execution).
In the locking/synchronization technique of Kawachiya, et al., the first thread to acquire the lock of an object is called the lock reservation owner of the object. The lock reservation owner may employ a simpler procedure for acquiring and releasing the object lock than a thread that is not the lock reservation owner. Additionally, if a thread that is not the lock reservation owner attempts to acquire the lock, the corresponding lockword will be converted to a base-mode lockword prior to lock acquisition by the thread: Subsequent lock acquisitions and releases will be based on the base-mode lockword as a base-mode lockword is not converted back to a reservation-mode lockword. During program execution, it is possible that two or more threads may attempt to lock an object at substantially the same time. For example, a thread that is not the lock reservation owner may attempt to acquire the lock of the object while a thread that is the lock reservation owner is in the process of performing its own lock acquisition or release of the same object. To prevent erroneous program behavior, Kawachiya, et al. require that threads are able to determine if the lock reservation owner is performing a lock acquisition or release and, if necessary, roll-back the execution of the lock reservation owner to an execution point prior to the start of the lock acquisition or release, respectively. Such a procedure may be difficult to implement and, moreover, reduce the execution efficiency of the overall program code.
A block diagram of an example environment of use 100 in which the example methods, apparatus and articles of manufacture described herein may be employed is illustrated in
The example environment of use 100 includes an MRTE depicted as a JAVA virtual machine (JVM) 110 in
In the example of
To process a classfile 114, the example JVM 110 includes a classloader 142 to locate one or more specific classfiles 114 corresponding to one or more specific classes and to load such classfiles 114 into an execution engine 144 of the JVM 110, for example, by storing a local image of a loaded classfile 114 into a local memory 146. Prior to storing the loaded classfile 114 to memory 146, the classloader 142 may invoke a bytecode verifier 150 to verify that the structure of the loaded classfile 114 is correct and conforms to the constructs of the JAVA language. In either case, the execution engine 144 of the JVM 110 then converts the loaded, machine-independent bytecodes into machine-dependent instructions using, for example, an interpreter 154 and/or one or more Just-In-Time (JIT) compilers 158.
The interpreter 154 converts the bytecode 114 into a set of machine-dependent instructions that implement the functionality of the bytecode 114 on the target processor(s) 120. In other words, the interpreter 154 provides an emulation layer to allow a bytecode 114 to be executed on the target processor(s) 120 as if the processor(s) 120 directly supported the JAVA instruction set. On the other hand, the JIT compiler 158 compiles a set of bytecodes 114 into a set of machine-dependent instructions for execution on the target processor(s) 120. The specific functionality of an individual bytecode 114 may not be exactly translated into machine-dependent instructions, but the overall functionality of the resulting set of machine-dependent instructions will be equivalent to the original set of bytecodes 114. Thus, the JIT compiler 158 may produce more optimal code than the interpreter 154. However, the interpreter 154 may be easier to implement than the JIT compiler 158.
To execute program code provided by the interpreter 154 and/or one or more JIT compilers 158, the execution engine 144 of the JVM 110 may define one or more storage areas in the local memory 146. For example, to support the execution of multiple, simultaneous threads, the JVM 110 may allocate a separate virtual program counter (pc) register and a separate JVM stack frame for each thread in the memory 146. The JVM stack frame may be used to store, for example, local variables and partial results corresponding to the associated execution thread. Additionally, the JVM 110 may define storage areas in the local memory 146 common to all threads. For example, such storage areas may include a heap to store objects that are created during program execution, a method area to store, for example, data and code used to implement the methods for a particular class, and a runtime constant pool to store constants associated with a particular class. To manage the runtime portion of the memory 146 efficiently, the JVM 110 may include a garbage collector 162, for example, to automatically deallocate objects from the heap to free memory for subsequent program execution.
To support the execution of multiple simultaneous threads, the execution engine 144 of the JVM 110 includes a thread support module 166. The thread support module 166 supports the creation of a thread by creating a thread object and executing the thread by invoking a start method of the thread. Additionally, the thread support module 166 may support preferential execution of threads through the use of various priority levels. Of particular interest in this disclosure, the execution engine 144 of the JVM 110 also includes a lock manager 170 to resolve conflicts that may occur as two or more threads attempt to access a same shared object.
The industry-standard specification corresponding to the example JVM 110 (as well as specifications for other managed run-time environments) defines procedures to support synchronization of objects between multiple threads. The JVM 110 provides a synchronization lock for each object. A thread may acquire ownership of an object by acquiring ownership of the lock associated with the object. Similarly, the thread may release ownership of the object by releasing ownership of the lock associated with the object. In the JAVA programming language, synchronization of objects and methods is implemented through the synchronized keyword. The specification for the JVM 110 defines the lock acquisition and release operations via the monitorenter and monitorexit bytecodes, respectively. However, the implementation of the monitorenter and monitorexit bytecodes is not defined.
A block diagram of an example lock manager 200 that may be used to implement the example lock manager 170 of
As shown in
Additionally, the lock synchronization controller 204 invokes a particular lock operation unit based on the type of locking operation to be performed on the lock of the object identified by the object identifier input 208. Example types of locking operations include a lock acquisition and a lock release. The lock synchronization controller 204 may determine the type of locking operation based on information provided via the thread context input 212. Such information may be determined, for example, by the interpreter 154 and/or JIT compiler 158 of
To acquire the lock of an object, the example lock manager 200 includes a lock acquisition unit 220. If the lock synchronization controller 204 determines that a lock of an object should be acquired (e.g., based on the object identifier input 208 and the thread context input 212), then the lock acquisition unit 220 may determine whether the current mode of the lockword associated with the object supports reservation-based lock acquisition. For example, the lock acquisition unit 220 may be configured to perform reservation-based lock acquisition of an object only if the associated object has a reservation-mode lockword. Conversely, the lock acquisition unit 220 may be configured to employ to a base lock acquisition procedure if a base-mode lockword is associated with the object (e.g., due to previous contention of the object lock, a previous locking operation performed on the lock by a thread that was not the lock reservation owner, etc.).
If, for example, a reservation-mode lockword is associated with the object to be locked, then the lock acquisition unit 220 may determine whether the lock reservation owner is unassigned or the lock reservation owner is attempting to acquire the lock of the object. If the lock reservation owner of the lock is not assigned (e.g., as may be the case during the first lock acquisition of an object), the lock acquisition unit 220 may assign the thread identified by the thread context input 212 to be the lock reservation owner of the object. If, on the other hand, the lock reservation owner thread is attempting to acquire the lock, the lock acquisition unit 220 may, for example, simply increment a lock recursion count field/value of the reservation-mode lockword to indicate that the lock reservation owner has acquired the lock of the object (possibly recursively). If, however, a thread that is not the lock reservation owner is attempting to acquire the lock (and, thus, the lock may not be currently available) or if a base-mode lockword is associated with the object, the lock acquisition unit 220 may invoke a known base-mode lock acquisition procedure to obtain the lock for the thread (potentially after waiting for the lock to become available and/or converting the lockword from a reservation-mode to a base-mode). In either case, the lock acquisition unit 220 may then cause the lock synchronization controller 204 to update the lock state output 216 to indicate that the object lock has been acquired.
After the thread finishes executing code that required the locked object (e.g., as indicated by the thread context input 212), the lock synchronization controller 204 may invoke a lock release unit 224 to release the lock of the object. If a reservation-mode lockword is associated with the object and the lock reservation owner is attempting to release the lock, then the lock release unit 224 may, for example, simply decrement a lock recursion count field/value associated with the reservation-mode lockword. In this case, the value of the lock recursion count field indicates the number of times the lock reservation owner has recursively locked the object, with a value of zero corresponding to the case in which the object is unlocked. If, however, a base-mode lockword is associated with the object, the lock release unit 224 may invoke a known base-mode lock release procedure to release the lock for the thread. After the object lock is released, the lock release unit 224 may cause/signal the lock synchronization controller 204 to update the object lock state output 216 accordingly.
As indicated by the block diagram of
To better understand the operation of the example lock manager 200 of
To determine the type of lock acquisition procedure to invoke to acquire the object lock, the example lock acquisition unit 304 includes a lock acquisition controller 320. The lock acquisition controller 320 may be configured to invoke a reservation-mode acquisition unit 324 if the lock mode comparator 312 determines that a reservation-mode lockword is associated with the object and the lock owner comparator 316 determines that the lock reservation owner (or a potential lock reservation owner) is attempting to acquire the object lock. Conversely, the lock acquisition controller 320 may be configured to invoke a base-mode acquisition unit 332 if, for example, the lock mode comparator 312 determines that a base-mode lockword is associated with the object to be locked, the lock owner comparator 316 determines that a thread that is not the lock reservation owner is attempting to acquire a reservation-mode lockword associated with the object, etc. To acquire the object lock, the reservation-mode acquisition unit 324 may increment a recursion counter field/value associated with the reservation-mode lockword. Additionally, the reservation-mode acquisition unit 324 may assign a thread to be the lock reservation owner of the object by setting a lock reservation owner thread identifier (ID) field of the reservation-mode lockword to correspond to the current thread attempting to acquire the object lock. In contrast, the base-mode acquisition unit 328 may employ a known acquisition procedure to acquire the object lock, while possibly resolving lock acquisition contention between multiple threads during the acquisition process.
Additionally, the example lock acquisition unit 304 may include a lock unreserve controller 332. The lock unreserve controller 332 may determine whether an object lock should be unreserved, that is, whether the lockword associated with the object should be converted from a reservation-mode to a base-mode. The lock unreserve controller 332 may make such a determination if, for example, a thread that is not the lock reservation owner attempts to acquire a reservation-mode lockword associated with the object. In such a case, the lock unreserve controller 332 may, for example, signal the lock acquisition controller 320 to cause the reservation-mode acquisition unit 324 to unreserve the object lock (i.e., convert the associated reservation-mode lockword to the corresponding base-mode lockword) after it has acquired the lock for the current thread (i.e., the thread that was previously the lock reservation owner of the object and whose lock acquisition was affected by the lock unreserve controller 332)
The example lock release unit 308 of
Additionally, the lock release controller 344 (or, more generally, the example lock release unit 308) may be coupled to the lock unreserve controller 332 of the example lock acquisition unit 304. As discussed above, the lock unreserve controller 332 may determine whether an object lock should be unreserved, that is, whether the lockword associated with the object should be converted from a reservation-mode to a base-mode. The lock unreserve controller 332 may make such a determination if, for example, a thread that is not the lock reservation owner attempts to acquire a reservation-mode lockword associated with the object. In such a case, the lock unreserve controller 332 may, for example, signal the lock release controller 344 to cause the reservation-mode release unit 348 to unreserve the object lock (i.e., convert the associated reservation-mode lockword to the corresponding base-mode lockword) after it has released the lock for the current thread (i.e., the thread that was previously the lock reservation owner of the object and whose lock release was affected by the lock unreserve controller 332).
In addition to the lockword mode bit 412, the reservation-mode lockword 404 (e.g., with a lockword mode bit 412 equal to 1), includes a thread identifier (ID) field 416 and a recursion count field 420. The thread ID field 416 is used to store a value that corresponds to and may uniquely identify the thread that is the lock reservation owner of the object associated with the reservation-mode lockword 404. The recursion count field 420 is used to indicate the number of times the thread referenced by the thread ID field 416 has recursively acquired the object lock. For example, the recursion count field 420 may be incremented when the object lock is acquired and decremented when the object lock is released. The base-mode lockword 408, in contrast, includes a procedure-specific field 424 that is specific to the known base lock synchronization procedure employed to process the base-mode lockword 408. For example, the procedure-specific field 424 may include a pointer to a set of data structures to store locking information corresponding to the object lock. Such information may include a lock owner ID, a lock recursion counter, a list of threads waiting to acquire the lock associated with the object, etc.
Turning to
Flowcharts representative of known machine readable instructions for implementing the lock manager 170 of
To better appreciate the properties and characteristics of the example lock manager 200 of
Turning to
If, however, a lock reservation owner already exists for the lock (block 512), then the process 500 determines whether the calling thread that invoked the prior-art lock acquisition process 500 is the lock reservation owner (block 520). If the calling thread is the lock reservation owner (block 520), then the process 500 acquires (possibly recursively) the lock for the thread by, for example, incrementing a lock recursion count/field included in the lockword of the object (block 524). The process 500 then ends.
However, if the lock has a reservation owner but it is not the calling thread (block 520), then the process 500 suspends the lock reservation owner thread in preparation for converting the reservation-mode lockword to a base-mode lockword (block 528 of
After the process 500 unreserves the lock of the object (block 540), the process 500 then gets the execution context of the previous lock reservation owner thread that was suspended at block 528 (block 544). Based on this execution context, the process 500 determines whether a roll-back of the previous reservation owner thread is required (block 548). Specifically, the process 500 determines whether the previous lock reservation owner was already attempting to acquire the same object lock and causing any of the blocks in the critical region 552 of
After the process 500 finishes rolling-back the execution context of the previous lock reservation owner (block 556), or if a reservation-mode lockword is not associated with the object (block 536), the process 500 then resumes the previous lock reservation owner thread (block 560). One having ordinary skill in the art will recognize that, if a reservation-mode lockword is no longer associated with the object at block 536, then another thread must have interceded and already unreserved the lock and converted the lockword to a base-mode lockword (indicated by the processing comment in block 564). In either case, after execution of the previous lock reservation owner thread is resumed (block 560), or if a base-mode lockword was originally associated with the object to be locked (block 508), the process 500 then invokes a known base-mode lock acquisition procedure to acquire the lock of the object based on the base-mode lockword (block 568). The process 500 then ends.
Turning to
If, however, the calling thread is not the lock reservation owner or had not previously acquired the object lock (block 612), then the process 600 throws an exception (block 620). At block 620, the process 600 may use any known exception handling technique to throw an exception indicating that an invalid release attempt was performed (because a thread that did not own the lock attempted to unlock the associated object). The process 600 then ends. However, if the process 600 determines that a reservation-mode lockword is not associated with the object to be locked (block 608), the process 600 then invokes a known base-mode lock release procedure to release the lock of the object based on the base-mode lockword (block 624). The process 600 then ends.
As discussed previously, the prior-art lock acquisition process 500 of
Based on the understanding provided by the prior-art processes 500 and 600 of
The example lock manager process 700 begins by determining which type of locking operation to perform for the current (calling) thread on the lock of the object (block 704). Valid locking operations may include a lock acquisition and a lock release. For example, a JIT compiler, such as the JIT compiler 158 of
Based on the locking procedure determination made at block 704, control then proceeds to one of blocks 708 and 712. At block 708, the lock manager process 700 performs a lock acquisition operation on the lock of the object. At block 712, the lock manager process 700 performs a lock release operation on the lock of the object. The processing performed at blocks 708 and 712 is discussed in greater detail through the descriptions of
After the processing at blocks 708 or 712 completes, the process 700 determines whether at least one locked object is still pending that will require a subsequent release at a future thread execution point (block 716). If any locked objects are pending (block 716), then control returns to block 704 and blocks subsequent thereto to allow the locks of such objects to be processed (as well as the locks of any additional objects to be locked). If, however, no locked objects are pending (block 716), the process 700 determines whether there are any additional objects to lock (block 720). If there are additional objects to lock (block 720), then control returns to block 704 and blocks subsequent thereto to allow the locks of such objects to be processed. If, however, there are no additional objects to lock (block 720), then the example process 700 ends. One having ordinary skill in the art will recognize that the conditional operations performed at blocks 716 and/or 720 may be replaced, for example, by an explicit or implicit determination regarding whether the program (or any thread of the program) is still executing. If the process 700 is still executing, control could then return to block 704 and subsequent blocks 708 and/or 712. Such a cycle could repeat until the process 700 (or all thread execution) terminates.
An example lock acquisition process 800 that may be used to perform the processing at block 708 of
After the processing at block 802 completes, the process 800 reads the mode of the lockword associated with the object to be locked (such as a lockword based on the lockword format illustrated in
To prevent a second thread from attempting to acquire the lock while a first thread is already in the process of becoming the lock reservation owner and acquiring the object lock, block 816 may be implemented based on a single atomic operation (such as a cmpxchg.acq instruction on a processor belonging to the Intel Itanium processor family or a lock cmpxchg instruction on a processor belonging to the Intel IA-32 processor family). As discussed previously, an atomic operation provides a thread (and/or a processor in a multi-processor system) with exclusive access to shared memory during the execution of the atomic operation. Thus, no other thread can modify the memory locations accessed by the atomic operation during its execution. (In
If, however, a lock reservation owner already exists for the lock (e.g., corresponding to either the second example state 458 or the third example state 462 of
After the processing at either block 816 or block 824 completes, the process 800 then sets the variable r1 to a NULL value to indicate that the lock acquisition process for the lock reservation owner is complete (block 828 of
However, if the lock has a reservation owner but it is not the calling thread (block 820), then the process 800 suspends the lock reservation owner thread in preparation for converting the reservation-mode lockword to a base-mode lockword (block 844 of
If, however, the lock reservation owner thread context variable r1 does not point to the object to be locked (block 852), then the process 800 unreserves the object lock by converting the associated lockword to a base-mode lockword (block 868). To prevent possible race conditions and/or other erroneous behavior, block 868 may include a test of the lockword mode prior to conversion and/or employ an atomic operation during the conversion procedure. The process 800 then resumes the lock reservation owner thread that was suspended at block 844 (block 872). After execution of the previous lock reservation owner thread is resumed (block 872) or after the lock reservation owner thread resets its unreserving thread context variable to FALSE and the process 800 resumes (block 864), the process 800 invokes a known base-mode lock acquisition procedure to acquire the lock of the object based on the base-mode lockword (block 876 of
An example lock release process 900 that may be used to perform the processing at block 712 of
After the processing at block 902 completes, the process 900 reads the mode of the lockword associated with the object lock to be released (such as a lockword based on the lockword format illustrated in
After the process 900 releases the object lock at block 916, the process 900 then sets the variable r1 to a NULL value to indicate that the lock release process for the lock reservation owner is complete (block 920). The process 900 then determines whether another thread has invoked a process similar or identical to the process 800 of
If, however, the calling thread is not the lock reservation owner or had not previously acquired the object lock (block 912), then the process 900 resets the variable r1 to a NULL value (block 936) and throws an exception (block 940). At block 940, the process 900 may use any known exception handling technique to throw an exception indicating that an invalid release attempt was performed (because a thread that did not own the lock attempted to unlock the associated object). The example process 900 then ends. However, if the process 900 determines that a reservation-mode lockword is not associated with the object to be locked (block 908), the process 900 then invokes a known base-mode lock release procedure to release the lock of the object based on the base-mode lockword (block 944). After the base-mode lock release procedure completes (block 944), the example process 900 resets the variable r1 to a NULL value (block 948) and then ends.
To assist in understanding the methods, apparatus and articles of manufacture described herein, two example operations of the example lock manager of
Next, a thread ‘A’ acquires the object lock, which corresponds to the next lockword state 1008. According to the example process 800 of
The following two lockword state 1024 and 1028 correspond to a lock acquisition scenario in which thread ‘A’ attempts to acquire the object lock again and at a slightly later time another thread (e.g., thread ‘B’) attempts to acquire the same object lock. According to the process 800, because thread ‘A’ is the lock reservation owner and acquires the object lock first, the lockword state 1024 indicates that the lockword is still in the reservation-mode (e.g., the lockword mode bit is equal to one) and that thread ‘A’ has acquired the lock (e.g., the recursion count field is equal to one). However, the subsequent lock acquisition attempt by thread ‘B’ causes the lockword to be converted to a base-mode, as indicated by the lockword state 1028 (e.g., the lockword mode bit is set to zero). According to the example process 800, the lock will still be owned by thread ‘A’ and thread ‘B’ will wait to acquire the lock via a base-mode lock acquisition procedure.
Turning to
Next, a thread ‘A’ acquires the object lock, which corresponds to the next lockword state 1058. According to the example process 800, the lockword state 1058 has a thread ID set equal to ‘A’ (to indicate that thread ‘A’ is the lock reservation owner) and a recursion count field equal to 1 to indicate that thread ‘A’ has acquired the object lock. Next, thread ‘A’ acquires the object lock again, which corresponds to lockword state 1062. According to the process 800, the lockword state 1062 still has a thread ID equal to ‘A’, but with a recursion count field now equal to two to indicate that the thread ‘A’ has recursively acquired the object lock a total of two times. Subsequently, the thread ‘A’ releases the object lock, which corresponds to lockword state 1066. According to the example process 900, the recursion count fields of lockword state 1016 is decremented due to the lock release operation.
The following two lockword state 1070 and 1074 correspond to a lock release scenario in which thread ‘A’ attempts to release the object lock again and at a slightly later time another thread (e.g., thread ‘B’) attempts to acquire the same object lock. According to the process 900, because thread ‘A’ is the lock reservation owner and releases the object lock first, the lockword state 1070 indicates that the lockword is still in the reservation-mode (e.g., the lockword mode bit is equal to one) and the thread ‘A’ has unlocked the lock (e.g., the recursion count field is equal to zero). However, the subsequent lock acquisition attempt by thread ‘B’ causes the lockword to be converted to a base-mode, as indicated by the lockword state 1074 (e.g., the lockword mode bit is set to zero). According to the example process 800, thread ‘B’ will then acquire the lock via a base-mode lock acquisition procedure. 100731
The system 1100 of the instant example includes a processor 1112. For example, the processor 1112 can be implemented by one or more Intel® microprocessors from the Pentium® family, the Itanium® family or the XScale® family. Of course, other processors from other families are also appropriate. A processor 1112 including one or more microprocessors may be used to implement the example environment of use 100 of
The processor 1112 is in communication with a main memory including a volatile memory 1114 and a non-volatile memory 1116 via a bus 1118. The volatile memory 1114 may be implemented by Static Random Access Memory (SRAM), Synchronous Dynamic Random Access Memory (SDRAM), Dynamic Random Access Memory (DRAM), RAMBUS Dynamic Random Access Memory (RDRAM) and/or any other type of random access memory device. The non-volatile memory 1116 may be implemented by flash memory and/or any other desired type of memory device. Access to the main memory 1114, 1116 is typically controlled by a memory controller (not shown) in a conventional manner.
The computer 1100 also includes a conventional interface circuit 1120. The interface circuit 1120 may be implemented by any type of well known interface standard, such as an Ethernet interface, a universal serial bus (USB), and/or a third generation input/output (3GIO) interface.
One or more input devices 1122 are connected to the interface circuit 1120. The input device(s) 1122 permit a user to enter data and commands into the processor 1112. The input device(s) can be implemented by, for example, a keyboard, a mouse, a touchscreen, a track-pad, a trackball, an isopoint and/or a voice recognition system.
One or more output devices 1124 are also connected to the interface circuit 1120. The output devices 1124 can be implemented, for example, by display devices (e.g., a liquid crystal display, a cathode ray tube display (CRT)), by a printer and/or by speakers. The interface circuit 1120, thus, typically includes a graphics driver card.
The interface circuit 1120 also includes a communication device such as a modem or network interface card to facilitate exchange of data with external computers via a network 1126 (e.g., an Ethernet connection, a digital subscriber line (DSL), a telephone line, coaxial cable, a cellular telephone system, etc.).
The computer 1100 also includes one or more mass storage devices 1128 for storing software and data. Examples of such mass storage devices 1128 include floppy disk drives, hard drive disks, compact disk drives and digital versatile disk (DVD) drives. The mass storage device 1128 and/or the volatile memory 1114 may be used to store, for example, the lockwords maintained and modified by processes 700, 800 and 900 of FIGS. 7, 8A-8C and 9, respectively.
As an alternative to implementing the methods and/or apparatus described herein in a system such as the device of
From the foregoing, persons of ordinary skill in the art will appreciate that the above disclosed methods and apparatus may be implemented in a static compiler, a managed run-time environment just-in-time (JIT) compiler, and/or directly in the hardware of a microprocessor to achieve performance optimization in executing various programs.
Although certain example methods, apparatus and articles of manufacture have been described herein, the scope of coverage of this patent is not limited thereto. On the contrary, this patent covers all methods, apparatus and articles of manufacture fairly falling within the scope of the appended claims either literally or under the doctrine of equivalents.