in bootstrap/src/sun/nio/ch/lincheck/Injections.java [374:417]
public static void beforeThreadStart(Thread startingThread) {
// TestThread is handled separately
if (startingThread instanceof TestThread) return;
// If thread is started return immediately, as in this case, JVM will throw an `IllegalThreadStateException`
if (startingThread.getState() != Thread.State.NEW) return;
ThreadDescriptor descriptor = getCurrentThreadDescriptorIfInAnalyzedCode();
EventTracker eventTracker = getEventTracker(descriptor);
if (eventTracker == null || descriptor == null) return;
/* We need to prepare a thread descriptor for the starting thread.
* We create it here and store it into the global thread descriptor map
* via `ThreadDescriptor.setThreadDescriptor`.
*
* Later, when the thread starts its execution and enters its `run()` method
* (see `beforeThreadRun` method below),
* it will retrieve its thread descriptor from the global map
* and save it as its own thread-local descriptor (for faster subsequent accesses).
*/
ThreadDescriptor startingThreadDescriptor = new ThreadDescriptor(startingThread);
if (eventTrackingMode == EventTrackingMode.THREAD_LOCAL) {
startingThreadDescriptor.setEventTracker(eventTracker);
}
/* Method `setThreadDescriptor` calls methods of `ConcurrentHashMap` (instrumented class),
* and at this point the calling thread can have the event tracker set,
* so we need to wrap the call into an ignored section.
*
* Note that other thread events tracking methods don't need to wrap anything
* into an ignored section, because when they are called, either
* (1) thread descriptor (and thus event tracker) of the thread is not installed yet, or
* (2) they do not call any instrumented methods themselves.
*/
descriptor.enterIgnoredSection();
ThreadDescriptor.setThreadDescriptor(startingThread, startingThreadDescriptor);
descriptor.leaveIgnoredSection();
/*
* End of the ignored section, the rest should be
* wrapped into an ignored section by the event tracker itself, if necessary.
*/
eventTracker.beforeThreadStart(descriptor, startingThread, startingThreadDescriptor);
}