prepareWait(current, notifyQueue, "mon-notify");
prepareWait(current, notifyQueue, waitState, "mon-notify");
    public final void Wait(long timeout) throws InterruptedException {        final VmThread current = VmMagic.currentProcessor().getCurrentThread();        // final int id = current.getId();        String exMsg = null;        if (owner != current) {            exMsg = "Current thread is not the owner of this monitor";        } else if (lockCount == 0) {            exMsg = "Monitor is not locked";        } else {            final int oldLockCount = lockCount;            lock();            try {                prepareWait(current, notifyQueue, "mon-notify");                VmMagic.currentProcessor().disableReschedule(true);            } finally {                unlock();            }            // If there is a timeout, also add the current thread to the            // sleep queue.            if (timeout > 0) {                current.wakeupTime = VmSystem.currentKernelMillis() + timeout;                VmMagic.currentProcessor().getScheduler().addToSleepQueue(current);            }            owner = null;            lockCount = 0;            wakeupWaitingThreads(enterQueue, true);            VmMagic.currentProcessor().suspend(true);            // When we return here, we have been notified or there            // was a timeout.            if (!current.isRunning()) {                Unsafe.debug("Back from wait, but state != running");                Unsafe.debug("state=");                Unsafe.debug(current.getThreadState());                Unsafe.die("Wait");            }            if (timeout > 0) {                // Screen.debug("<backfromwait-"); Screen.debug(id);                // Screen.debug("/>");                // Remove the current thread from the notifyQueue.                // There is no need to remove myself from the sleep queue,                // because this is done either by the scheduler or                // indirect by wakeupWaitingThreads.                lock();                try {                    notifyQueue.remove(current);                } finally {                    unlock();                }            }            enter();            this.lockCount = oldLockCount;        }        if (exMsg != null) {            Unsafe.debug(exMsg);            throw new IllegalMonitorStateException(exMsg);        }        // Check for InterruptedException        current.testAndClearInterruptStatus();    }