void CPU_Sleep( SLEEP_LEVEL level, UINT64 wakeEvents )
{
    ASSERT_IRQ_MUST_BE_OFF();
    SleepLevel = level;
    WakeEvents = wakeEvents;
    ENABLE_INTERRUPTS();
    {
        InSleep = true;
#ifdef PLATFORM_ARM_OS_PORT
        // if no events are already pending - use OS Signal to wait for
        // one. The OS will atomically clear the signal whenever this
        // thread is rescheduled.
        if( Events_MaskedRead( wakeEvents ) == 0 )
            osSignalWait( ClrEventSignal, osWaitForever );
#else
        HAL_CPU_Sleep( level, wakeEvents );
#endif
        InSleep = false;
    }
    DISABLE_INTERRUPTS();
}
UINT32 Events_WaitForEvents( UINT32 sleepLevel, UINT32 WakeupSystemEvents, UINT32 Timeout_Milliseconds )
{
    NATIVE_PROFILE_PAL_EVENTS();
    // do NOT call this routine with interrupts disabled,
    // as we can die here, since flags are only set in ISRs
    ASSERT_IRQ_MUST_BE_ON();

    // schedule an interrupt for this far in the future
    // timeout is in milliseconds, convert to Sleep Counts

    UINT64 CountsRemaining = CPU_MillisecondsToTicks( Timeout_Milliseconds );

#if defined(HAL_PROFILE_ENABLED)
    Events_WaitForEvents_Calls++;
#endif

    {
        GLOBAL_LOCK(irq);

        // then check to make sure the events haven't happened on the way in
        // we must do this before we sleep!

        UINT64 Expire           = HAL_Time_CurrentTicks() + CountsRemaining;
        BOOL   RunContinuations = TRUE;

        while(true)
        {
            UINT32 Events = Events_MaskedRead( WakeupSystemEvents ); if(Events) return Events;

            if(Expire <= HAL_Time_CurrentTicks()) return 0;


            // first check and possibly run any continuations
            // but only if we have slept after stalling
            if(RunContinuations && !SystemState_QueryNoLock( SYSTEM_STATE_NO_CONTINUATIONS ))
            {
                // restore interrupts before running a continuation
                irq.Release();

                // if we stall on time, don't check again until after we sleep
                RunContinuations = HAL_CONTINUATION::Dequeue_And_Execute();

                irq.Acquire();
            }
            else
            {
                // try stalled continuations again after sleeping
                RunContinuations = TRUE;

                //lcd_printf("\fSleep=%6lld   ", CountsRemaining);
                //lcd_printf(  "Events=%08x", Events_MaskedRead(0xffffffff));

#if defined(HAL_TIMEWARP)
                if(s_timewarp_lastButton < HAL_Time_TicksToTime( HAL_Time_CurrentTicks() ))
                {
                    CountsRemaining = Expire - HAL_Time_CurrentTicks();

                    if(CountsRemaining > 0)
                    {
                        s_timewarp_compensate += (CountsRemaining * 10*1000*1000) / CPU_TicksPerSecond();
                    }
                    return 0;
                }
#endif

                ASSERT_IRQ_MUST_BE_OFF();

                HAL_COMPLETION::WaitForInterrupts( Expire, sleepLevel, WakeupSystemEvents );

                irq.Probe(); // See if we have to serve any pending interrupts.                
            }
        }
    }
}