/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Test synchronization primitives.
 *
 * TODO: this should be re-written to be a little more rigorous and/or
 * useful.  Also, the ThreadDeathHandler stuff should be exposed or
 * split out.
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("Sleep Test");
        sleepTest();

        System.out.println("\nCount Test");
        countTest();

        System.out.println("\nInterrupt Test");
        interruptTest();
    }

    static void sleepTest() {
        System.out.println("GOING");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) {
            System.out.println("INTERRUPT!");
            ie.printStackTrace();
        }
        System.out.println("GONE");
    }

    static void countTest() {
        CpuThread one, two;

        one = new CpuThread(1);
        two = new CpuThread(2);

        one.start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException ie) {
            System.out.println("INTERRUPT!");
            ie.printStackTrace();
        }

        two.start();

        //System.out.println("main: off and running");

        try {
            one.join();
            two.join();
        } catch (InterruptedException ie) {
            System.out.println("INTERRUPT!");
            ie.printStackTrace();
        }
        System.out.println("main: all done");
    }

    static void interruptTest() {
        SleepyThread sleepy, pesky;

        sleepy = new SleepyThread(null);
        pesky = new SleepyThread(sleepy);

        sleepy.setPriority(4);
        sleepy.start();
        pesky.start();
        pesky.setPriority(3);
    }
}

class CpuThread extends Thread {
    static Object mSyncable = new Object();
    static int mCount = 0;
    int mNumber;

    CpuThread(int num) {
        super("CpuThread " + num);
        mNumber = num;
    }

    public void run() {
        //System.out.print("thread running -- ");
        //System.out.println(Thread.currentThread().getName());

        synchronized (mSyncable) {
            for (int i = 0; i < 10; i++) {
                output(mNumber);
            }

            System.out.print("Final result: ");
            System.out.println(mCount);
        }
    }

    void output(int num) {
        int count = mCount;

        System.out.print("going: ");
        System.out.println(num);

        /* burn CPU; adjust end value so we exceed scheduler quantum */
        for (int j = 0; j < 5000; j++) {
            ;
        }

        count++;
        mCount = count;
    }
}

class SleepyThread extends Thread {
    private SleepyThread mOther;
    private Integer[] mWaitOnMe;      // any type of object will do

    private static int count = 0;

    SleepyThread(SleepyThread other) {
        mOther = other;
        mWaitOnMe = new Integer[] { 1, 2 };

        setName("thread#" + count);
        count++;
    }

    public void run() {
        System.out.println("SleepyThread.run starting");

        if (false) {
            ThreadDeathHandler threadHandler =
                new ThreadDeathHandler("SYNC THREAD");
            Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
            throw new NullPointerException("die");
        }

        if (mOther == null) {
            boolean intr = false;

            try {
                synchronized (mWaitOnMe) {
                    mWaitOnMe.wait(9000);
                }
            } catch (InterruptedException ie) {
                // Expecting this; interrupted should be false.
                System.out.println(Thread.currentThread().getName() +
                        " interrupted, flag=" + Thread.interrupted());
                intr = true;
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            if (!intr)
                System.out.println("NOT INTERRUPTED");
        } else {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ie) {
                System.out.println("PESKY INTERRUPTED?");
            }

            System.out.println("interrupting other (isAlive="
                + mOther.isAlive() + ")");
            mOther.interrupt();
        }
    }
}
