This is blog 2 in the OpenJ9 locking/synchronization series (blog 1). It covers two data structures: system-monitor and GC-spinlock, which are used to enforce synchronization in OpenJ9.
A system-monitor (omrthread_monitor_t) has two phases: spinlock and fallback to the operating system (OS). In the spinlock (first) phase, the system-monitor spins in a loop while performing atomic compare and swap (CAS) operations on a lock-word that stores the lock state. If a thread cannot acquire a system-monitor using spinning, then it fallbacks to the OS structures, such as mutexes, condition variables and semaphores, for enforcing synchronization (second phase).
System-monitors are similar to the monitors introduced in the MESA programming language. They provide mutual exclusion in addition to wait and notify functionality. On the other hand, a mutex only provides mutual exclusion.
For a system-monitor, the lightweight and heavyweight operations are as follows:
LOCK TYPE | DESCRIPTION |
Lightweight | Lock-word; CAS operation; spinlock (first) phase. |
Heavyweight | Blocking enter using the operating system (OS) specific synchronization primitives; second phase. |
When a thread attempts to acquire a system-monitor, it will spin using the lightweight lock-word until spinning is exhausted, and then block using the OS specific synchronization primitives. When a thread releases a system-monitor, the blocked threads are woken up using the OS specific synchronization primitives. Then, the threads compete using the lightweight lock-word to acquire the system-monitor before falling back to the OS specific synchronization primitives in order to block/wait until the system-monitor is released.
- In the first phase, three-tier spinning (blog 4) is used to make acquiring locks more efficient with the help of incrementally larger wait-interval between the attempts to acquire the lock. The spin control parameters can be changed using command line options. Refer to blog 4 to learn about three-tier spinning and spin control parameters.
- In the second phase, a condition variable is used for blocking/waiting.
OpenJ9 provides the Java Lock Monitor (JLM) tool to study the lock and contention statistics for the system-monitors. The JLM tool outputs a report, which contains the self-diagnostic information to evaluate the behaviour of all the system-monitors used in OpenJ9. More details on the JLM tool can be found here.

GC-spinlocks (J9GCSpinlock) are a simplified version of system-monitors, with the following differences:
- Wait and notify is not supported.
- Self-diagnostic information (JLM support) is unavailable.
- In the first phase, three tier spinning is used. But, the spin control parameters cannot be changed via command line options.
- In the second phase, a semaphore is used for blocking/waiting instead of a condition variable.
Code
System-monitor functionality:
- monitor_init
- monitor_free
- omrthread_monitor_enter
- omrthread_monitor_exit
- omrthread_monitor_wait
- omrthread_monitor_notify
- omrthread_monitor_notify_all
- omrthread_spinlock_acquire
- Other omrthread_monitor_* functions are in omrthread.c (OMR).
GC-spinlock functionality:
Thread functionality:
- omrthread_create
- omrthread_abort
- omrthread_interrupt
- omrthread_sleep
- Other omrthread_* functions are in omrthread.c (OMR).
Suggested Readings
The next blog in the OpenJ9 locking/synchronization series covers a data structure named object-monitor (blog 3) which is used to enforce synchronization for the Java objects.
3 Replies to “System-Monitor and GC-Spinlock Implementation”