This is blog 8 in the OpenJ9 locking/synchronization series (blog 1). This blog covers an OpenJ9 feature which allows spin control parameters to be varied on a per-class basis. Before reading this blog, one needs to know about the system-monitors (blog 2), object-monitors (blog 3), three-tier spinning (blog 4) and adaptive spinning (blog 5). Please read the aforementioned blogs before reading this blog.
An object-monitor is associated with all the critical sections of a class. Critical sections may vary in size. Using the same spin parameters for all monitors is inefficient. For some critical sections, default spin parameters may not provide sufficient spin time, and we may end up preempting threads. In such cases, extra spin time is cheaper than preemption.
CSSP allows an OpenJ9 user to specify custom spin parameters for three-tier spinning and enable/disable adaptive spinning for known classes where extra spin time is beneficial.
How to identify classes that may benefit from extra spin time?
OpenJ9 provides the Java Lock Monitor (JLM) tool to study the contention statistics on the monitors used in the Java application and JVM itself. In a JLM report, %MISS represents the total number of acquires where the requesting thread is blocked waiting on the object-monitor, and AVER_HTM is the average amount of time the monitor was held. %MISS and AVER_HTM can indicate if a class will benefit from extra spin time. More details on the JLM tool can be found here.

Applying CSSP:
Command line syntax:
-Xthr:customSpinOptions=className:spin1:spin2:yield:tryEnterSpin1:tryEnterSpin2:tryEnterYield:threeTierSpinCount1:threeTierSpinCount2:threeTierSpinCount3:adaptSpin
Example:
java -Xthr:customSpinOptions=org/apache/spark/broadcast/TorrentBroadcast:256:10000:270:256:10000:270:256:10000:270:0 -version
For the TorrentBroadcast class in the Spark framework, the spin parameters were increased by a factor of 2 with adaptive spinning disabled. The following improvements were observed:
Spark Benchmark | Improvement in average run-time [%] | Improvement in minimum run-time [%] |
scala-count-w-fltr | 21.68 | 19.71 |
scala-agg-by-key-int | 13.49 | 4.26 |
scala-count | 13.33 | 5.00 |
scala-agg-by-key | 6.72 | 4.03 |
scala-agg-by-key-naive | 2.80 | 1.22 |
Drawbacks of CSSP:
- It is not user friendly; identifying a class is time consuming and depends upon user’s judgement; and a user needs to be familiar with JLM.
- Determining optimal spin parameters is tedious due to the hit and trial method of selecting new spin parameters.
- There is no simple approach to estimate performance improvements; benchmarking is required which is time consuming.
Code
Places where CSSP are used:
- spinOnFlatLock (object-monitor; control parameters: spin1, spin2, yield, [n/noN]estedSpinning.)
- spinOnTryEnter (object-monitor; control parameters: tryEnterSpin1, tryEnterSpin2, tryEnterYield, [t/noT]ryEnterNestedSpinning.)
- omrthread_spinlock_acquire (system-monitor; control parameters: threeTierSpinCount1, threeTierSpinCount2, threeTierSpinCount3; non-nested spinning is unavailable.)
- To initialize a system-monitor for an object-monitor.
- customAdaptSpin is used in threaddef.h (OMR) to enable/disable spinning on a per-class basis.
Suggested Readings
Currently, this is the last blog in the OpenJ9 locking/synchronization series. More blogs will be released in the future for this series, and they will cover new data-structures, features and profiling tools for OpenJ9 locking.
If you missed the previous blog in this series, it covers OpenJ9’s lock reservation (blog 7) feature, which selectively removes the need for the atomic compare-and-swap operations in order to acquire an object-monitor.
[Note] Not all the command line options, mentioned above, may have customer support. Some options are only available for experimental work.