+ //FIXME if the current time is prior than 1970 secs will be negative
+ if ((sys > secs) || ((sys == secs) && (microsys > microsecs))) {
+ os_log(OS_LOG_DEFAULT, "%s WARNING: %s is less then sys %s %lu s %d u sys %lu s %d u\n",
+ __func__, (has_monotonic_clock)?"monotonic":"PMU", (has_monotonic_clock)?"monotonic":"PMU", (unsigned long)secs, microsecs, (unsigned long)sys, microsys);
+ secs = sys;
+ microsecs = microsys;
+ }
+
+ // PMU or monotonic - sys
+ // This macro stores the subtraction result in secs and microsecs
+ TIME_SUB(secs, sys, microsecs, microsys, USEC_PER_SEC);
+ clock2bintime(&secs, µsecs, &bt);
+
+ /*
+ * Safety belt: the UTC clock will likely have a lower resolution than the tick counter.
+ * It's also possible that the device didn't fully transition to the powered-off state on
+ * the most recent sleep, so the tick counter may not have reset or may have only briefly
+ * tured off. In that case it's possible for the difference between the UTC clock and the
+ * tick counter to be less than the previously recorded value in clock.calend.basesleep.
+ * In that case simply record that we slept for 0 ticks.
+ */
+ if ((bt.sec > clock_calend.basesleep.sec) ||
+ ((bt.sec == clock_calend.basesleep.sec) && (bt.frac > clock_calend.basesleep.frac))) {
+
+ //last_sleep is the difference between current PMU or monotonic - abs and last wake PMU or monotonic - abs
+ last_sleep_bt = bt;
+ bintime_sub(&last_sleep_bt, &clock_calend.basesleep);
+
+ //set baseseep to current PMU or monotonic - abs
+ clock_calend.basesleep = bt;
+ bintime2usclock(&last_sleep_bt, &last_sleep_sec, &last_sleep_usec);
+ bintime2absolutetime(&last_sleep_bt, &mach_absolutetime_last_sleep);
+ mach_absolutetime_asleep += mach_absolutetime_last_sleep;
+
+ bintime_add(&clock_calend.offset, &last_sleep_bt);
+ bintime_add(&clock_calend.bintime, &last_sleep_bt);
+
+ } else{
+ mach_absolutetime_last_sleep = 0;
+ last_sleep_sec = last_sleep_usec = 0;
+ bintime2usclock(&clock_calend.basesleep, &basesleep_s, &basesleep_us);
+ os_log(OS_LOG_DEFAULT, "%s WARNING: basesleep (%lu s %d u) > %s-sys (%lu s %d u) \n",
+ __func__, (unsigned long) basesleep_s, basesleep_us, (has_monotonic_clock)?"monotonic":"PMU", (unsigned long) secs_copy, microsecs_copy );
+ }
+
+ KERNEL_DEBUG_CONSTANT(
+ MACHDBG_CODE(DBG_MACH_CLOCK,MACH_EPOCH_CHANGE) | DBG_FUNC_NONE,
+ (uintptr_t) mach_absolutetime_last_sleep,
+ (uintptr_t) mach_absolutetime_asleep,
+ (uintptr_t) (mach_absolutetime_last_sleep >> 32),
+ (uintptr_t) (mach_absolutetime_asleep >> 32),
+ 0);
+
+ commpage_update_mach_continuous_time(mach_absolutetime_asleep);
+ adjust_cont_time_thread_calls();
+
+#if DEVELOPMENT || DEBUG
+ struct clock_calend clock_calend_cp = clock_calend;
+#endif
+
+ clock_unlock();
+ splx(s);
+
+#if DEVELOPMENT || DEBUG
+ if (g_should_log_clock_adjustments) {
+ os_log(OS_LOG_DEFAULT, "PMU was %lu s %d u\n",(unsigned long) utc_sec, utc_usec);
+ os_log(OS_LOG_DEFAULT, "last sleep was %lu s %d u\n",(unsigned long) last_sleep_sec, last_sleep_usec);
+ print_all_clock_variables("clock_wakeup_calendar:BEFORE",
+ &secs_copy, µsecs_copy, &sys, µsys, &clock_calend_cp1);
+ print_all_clock_variables("clock_wakeup_calendar:AFTER", NULL, NULL, NULL, NULL, &clock_calend_cp);
+ }
+#endif /* DEVELOPMENT || DEBUG */
+
+ host_notify_calendar_change();
+
+#if CONFIG_DTRACE
+ clock_track_calend_nowait();
+#endif