public static void beforeThreadStart()

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);
    }