public ExecutionScenario nextExecution()

in src/jvm/main/org/jetbrains/kotlinx/lincheck/execution/RandomExecutionGenerator.java [34:100]


    public ExecutionScenario nextExecution() {
        // Create init execution part
        List<ActorGenerator> validActorGeneratorsForInit = testStructure.actorGenerators.stream()
            .filter(ag -> !ag.getUseOnce() && !ag.isSuspendable()).collect(Collectors.toList());
        List<Actor> initExecution = new ArrayList<>();
        for (int i = 0; i < testConfiguration.getActorsBefore() && !validActorGeneratorsForInit.isEmpty(); i++) {
            ActorGenerator ag = validActorGeneratorsForInit.get(random.nextInt(validActorGeneratorsForInit.size()));
            initExecution.add(ag.generate(0, random));
        }
        // Create parallel execution part
        // Construct non-parallel groups and parallel one
        List<CTestStructure.OperationGroup> nonParallelGroups = testStructure.operationGroups.stream()
            .filter(g -> g.nonParallel)
            .collect(Collectors.toList());
        Collections.shuffle(nonParallelGroups, random);
        List<ActorGenerator> parallelGroup = new ArrayList<>(testStructure.actorGenerators);
        nonParallelGroups.forEach(g -> parallelGroup.removeAll(g.actors));

        List<List<Actor>> parallelExecution = new ArrayList<>();
        List<ThreadGen> threadGens = new ArrayList<>();
        for (int t = 0; t < testConfiguration.getThreads(); t++) {
            parallelExecution.add(new ArrayList<>());
            threadGens.add(new ThreadGen(t, testConfiguration.getActorsPerThread()));
        }
        for (int i = 0; i < nonParallelGroups.size(); i++) {
            threadGens.get(i % threadGens.size()).nonParallelActorGenerators
                .addAll(nonParallelGroups.get(i).actors);
        }
        List<ThreadGen> tgs2 = new ArrayList<>(threadGens);
        while (!threadGens.isEmpty()) {
            for (Iterator<ThreadGen> it = threadGens.iterator(); it.hasNext(); ) {
                ThreadGen threadGen = it.next();
                int aGenIndexBound = threadGen.nonParallelActorGenerators.size() + parallelGroup.size();
                if (aGenIndexBound == 0) {
                    it.remove();
                    continue;
                }
                int aGenIndex = random.nextInt(aGenIndexBound);
                ActorGenerator agen;
                if (aGenIndex < threadGen.nonParallelActorGenerators.size()) {
                    agen = getActorGenFromGroup(threadGen.nonParallelActorGenerators, aGenIndex);
                } else {
                    agen = getActorGenFromGroup(parallelGroup,
                        aGenIndex - threadGen.nonParallelActorGenerators.size());
                }
                parallelExecution.get(threadGen.iThread).add(agen.generate(threadGen.iThread + 1, random));
                if (--threadGen.left == 0)
                    it.remove();
            }
        }
        parallelExecution = parallelExecution.stream().filter(actors -> !actors.isEmpty()).collect(Collectors.toList());
        // Create post execution part if the parallel part does not have suspendable actors
        List<Actor> postExecution;
        if (parallelExecution.stream().noneMatch(actors -> actors.stream().anyMatch(Actor::isSuspendable))) {
            postExecution = new ArrayList<>();
            List<ActorGenerator> leftActorGenerators = new ArrayList<>(parallelGroup);
            for (ThreadGen threadGen : tgs2)
                leftActorGenerators.addAll(threadGen.nonParallelActorGenerators);
            for (int i = 0; i < testConfiguration.getActorsAfter() && !leftActorGenerators.isEmpty(); i++) {
                ActorGenerator agen = getActorGenFromGroup(leftActorGenerators, random.nextInt(leftActorGenerators.size()));
                postExecution.add(agen.generate(testConfiguration.getThreads() + 1, random));
            }
        } else {
            postExecution = Collections.emptyList();
        }
        return new ExecutionScenario(initExecution, parallelExecution, postExecution, testStructure.validationFunction);
    }