/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @summary Stress test for malloc tracking
 * @key nmt jcmd stress
 * @library /testlibrary /testlibrary/whitebox
 * @build MallocStressTest
 * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
 * @run main ClassFileInstaller sun.hotspot.WhiteBox
 * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocStressTest
 */

import java.util.concurrent.atomic.AtomicInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.oracle.java.testlibrary.*;
import sun.hotspot.WhiteBox;

public class MallocStressTest {
    private static int K = 1024;

    // The stress test runs in three phases:
    // 1. alloc: A lot of malloc with fewer free, which simulates a burst memory allocation
    //    that is usually seen during startup or class loading.
    // 2. pause: Pause the test to check accuracy of native memory tracking
    // 3. release: Release all malloc'd memory and check native memory tracking result.
    public enum TestPhase {
        alloc,
        pause,
        release
    };

    static TestPhase phase = TestPhase.alloc;

    // malloc'd memory
    static ArrayList<MallocMemory>  mallocd_memory = new ArrayList<MallocMemory>();
    static long                     mallocd_total  = 0;
    static WhiteBox                 whiteBox;
    static AtomicInteger            pause_count = new AtomicInteger();

    static boolean                  is_64_bit_system;

    private static boolean is_64_bit_system() { return is_64_bit_system; }

    public static void main(String args[]) throws Exception {
        is_64_bit_system = (Platform.is64bit());

        OutputAnalyzer output;
        whiteBox = WhiteBox.getWhiteBox();

        // Grab my own PID
        String pid = Integer.toString(ProcessTools.getProcessId());
        ProcessBuilder pb = new ProcessBuilder();

        AllocThread[]   alloc_threads = new AllocThread[256];
        ReleaseThread[] release_threads = new ReleaseThread[64];

        int index;
        // Create many allocation threads
        for (index = 0; index < alloc_threads.length; index ++) {
            alloc_threads[index] = new AllocThread();
        }

        // Fewer release threads
        for (index = 0; index < release_threads.length; index ++) {
            release_threads[index] = new ReleaseThread();
        }

        if (is_64_bit_system()) {
            sleep_wait(2*60*1000);
        } else {
            sleep_wait(60*1000);
        }
        // pause the stress test
        phase = TestPhase.pause;
        while (pause_count.intValue() <  alloc_threads.length + release_threads.length) {
            sleep_wait(10);
        }

        long mallocd_total_in_KB = (mallocd_total + K / 2) / K;

        // Now check if the result from NMT matches the total memory allocated.
        String expected_test_summary = "Test (reserved=" + mallocd_total_in_KB +"KB, committed=" + mallocd_total_in_KB + "KB)";
        // Run 'jcmd <pid> VM.native_memory summary'
        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
        output = new OutputAnalyzer(pb.start());
        output.shouldContain(expected_test_summary);

        // Release all allocated memory
        phase = TestPhase.release;
        synchronized(mallocd_memory) {
            mallocd_memory.notifyAll();
        }

        // Join all threads
        for (index = 0; index < alloc_threads.length; index ++) {
            try {
                alloc_threads[index].join();
            } catch (InterruptedException e) {
            }
        }

        for (index = 0; index < release_threads.length; index ++) {
            try {
                release_threads[index].join();
            } catch (InterruptedException e) {
            }
        }

        // All test memory allocated should be released
        output = new OutputAnalyzer(pb.start());
        output.shouldNotContain("Test (reserved=");

        // Verify that tracking level has not been downgraded
        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
        output = new OutputAnalyzer(pb.start());
        output.shouldNotContain("Tracking level has been downgraded due to lack of resources");
    }

    private static void sleep_wait(int n) {
        try {
            Thread.sleep(n);
        } catch (InterruptedException e) {
        }
    }


    static class MallocMemory {
        private long  addr;
        private int   size;

        MallocMemory(long addr, int size) {
            this.addr = addr;
            this.size = size;
        }

        long addr()  { return this.addr; }
        int  size()  { return this.size; }
    }

    static class AllocThread extends Thread {
        AllocThread() {
            this.setName("MallocThread");
            this.start();
        }

        // AllocThread only runs "Alloc" phase
        public void run() {
            Random random = new Random();
            while (MallocStressTest.phase == TestPhase.alloc) {
                int r = Math.abs(random.nextInt());
                // Only malloc small amount to avoid OOM
                int size = r % 32;
                if (is_64_bit_system()) {
                    r = r % 32 * K;
                } else {
                    r = r % 64;
                }
                if (size == 0) size = 1;
                long addr = MallocStressTest.whiteBox.NMTMallocWithPseudoStack(size, r);
                if (addr != 0) {
                    MallocMemory mem = new MallocMemory(addr, size);
                    synchronized(MallocStressTest.mallocd_memory) {
                        MallocStressTest.mallocd_memory.add(mem);
                        MallocStressTest.mallocd_total += size;
                    }
                } else {
                    System.out.println("Out of malloc memory");
                    break;
                }
            }
            MallocStressTest.pause_count.incrementAndGet();
        }
    }

    static class ReleaseThread extends Thread {
        private Random random = new Random();
        ReleaseThread() {
            this.setName("ReleaseThread");
            this.start();
        }

        public void run() {
            while(true) {
                switch(MallocStressTest.phase) {
                case alloc:
                    slow_release();
                    break;
                case pause:
                    enter_pause();
                    break;
                case release:
                    quick_release();
                    return;
                }
            }
        }

        private void enter_pause() {
            MallocStressTest.pause_count.incrementAndGet();
            while (MallocStressTest.phase != MallocStressTest.TestPhase.release) {
                try {
                    synchronized(MallocStressTest.mallocd_memory) {
                        MallocStressTest.mallocd_memory.wait(10);
                    }
                } catch (InterruptedException e) {
                }
            }
        }

        private void quick_release() {
            List<MallocMemory> free_list;
            while (true) {
                synchronized(MallocStressTest.mallocd_memory) {
                    if (MallocStressTest.mallocd_memory.isEmpty()) return;
                    int size =  Math.min(MallocStressTest.mallocd_memory.size(), 5000);
                    List<MallocMemory> subList = MallocStressTest.mallocd_memory.subList(0, size);
                    free_list = new ArrayList<MallocMemory>(subList);
                    subList.clear();
                }
                for (int index = 0; index < free_list.size(); index ++) {
                    MallocMemory mem = free_list.get(index);
                    MallocStressTest.whiteBox.NMTFree(mem.addr());
                }
            }
        }

        private void slow_release() {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
            synchronized(MallocStressTest.mallocd_memory) {
                if (MallocStressTest.mallocd_memory.isEmpty()) return;
                int n = Math.abs(random.nextInt()) % MallocStressTest.mallocd_memory.size();
                MallocMemory mem = mallocd_memory.remove(n);
                MallocStressTest.whiteBox.NMTFree(mem.addr());
                MallocStressTest.mallocd_total -= mem.size();
            }
        }
    }
}
