void refresh_next_alarm_text(void) { int alarm_id = get_next_alarm(s_alarms); // schedule the winner if(alarm_id>=0) { time_t timestamp = alarm_get_time_of_wakeup(&s_alarms[alarm_id]); struct tm *t = localtime(×tamp); if(s_show_remaining ) { time_t now = time(NULL); time_t diff = timestamp-now; snprintf(s_next_alarm_text,sizeof(s_next_alarm_text),"in %02dh,%02dm",(int)diff/3600,(int)(diff/60)%60); } else { if(clock_is_24h_style()) snprintf(s_next_alarm_text,sizeof(s_next_alarm_text),"%02d.%02d %02d:%02d",t->tm_mday, t->tm_mon+1,t->tm_hour,t->tm_min); else { int temp_hour; bool is_am; convert_24_to_12(t->tm_hour, &temp_hour, &is_am); snprintf(s_next_alarm_text,sizeof(s_next_alarm_text),"%02d.%02d %02d:%02d %s",t->tm_mday, t->tm_mon+1,temp_hour,t->tm_min,is_am?"AM":"PM"); } } alarm_phone_send_pin(&s_alarms[alarm_id]); } else { snprintf(s_next_alarm_text,sizeof(s_next_alarm_text),"---"); } }
/* * This is the clock interrupt handling routine. * You have to call minithread_clock_init with this * function as parameter in minithread_system_initialize */ void clock_handler(void* arg) { interrupt_level_t old_level = set_interrupt_level(DISABLED); nInterrupts++; // get_next_alarm always runs in O(1) alarm_t *next_alarm = get_next_alarm(); while (next_alarm) { call_handler(next_alarm); // since next_alarm is the first element, deregister also runs in O(1) deregister_alarm(next_alarm); next_alarm = get_next_alarm(); } implement_scheduler(); set_interrupt_level(old_level); }
/* handle update-ended timer */ static void check_update_timer(RTCState *s) { uint64_t next_update_time; uint64_t guest_nsec; int next_alarm_sec; /* From the data sheet: "Holding the dividers in reset prevents * interrupts from operating, while setting the SET bit allows" * them to occur. However, it will prevent an alarm interrupt * from occurring, because the time of day is not updated. */ if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) { qemu_del_timer(s->update_timer); return; } if ((s->cmos_data[RTC_REG_C] & REG_C_UF) && (s->cmos_data[RTC_REG_B] & REG_B_SET)) { qemu_del_timer(s->update_timer); return; } if ((s->cmos_data[RTC_REG_C] & REG_C_UF) && (s->cmos_data[RTC_REG_C] & REG_C_AF)) { qemu_del_timer(s->update_timer); return; } guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC; /* if UF is clear, reprogram to next second */ next_update_time = qemu_get_clock_ns(rtc_clock) + NSEC_PER_SEC - guest_nsec; /* Compute time of next alarm. One second is already accounted * for in next_update_time. */ next_alarm_sec = get_next_alarm(s); s->next_alarm_time = next_update_time + (next_alarm_sec - 1) * NSEC_PER_SEC; if (s->cmos_data[RTC_REG_C] & REG_C_UF) { /* UF is set, but AF is clear. Program the timer to target * the alarm time. */ next_update_time = s->next_alarm_time; } if (next_update_time != qemu_timer_expire_time_ns(s->update_timer)) { qemu_mod_timer(s->update_timer, next_update_time); } }
// accel_tap_service_unsubscribe(); } void perform_wakeup_tasks(Alarm* alarms, bool *snooze) { s_snooze=snooze; // Create main Window s_main_window = window_create(); window_set_window_handlers(s_main_window, (WindowHandlers) { .load = main_window_load, .unload = main_window_unload, }); // Update timeline pin int alarm_id = get_next_alarm(alarms); if(alarm_id>=0) alarm_phone_send_pin(&alarms[alarm_id]); APP_LOG(APP_LOG_LEVEL_DEBUG, "Alarm ID: %d",alarm_id); //s_flip_to_snooze = load_persistent_storage_bool(FLIP_TO_SNOOZE_KEY, false); // Subscribe to Wakeup API wakeup_service_subscribe(wakeup_handler); // Was this a wakeup? if(launch_reason() == APP_LAUNCH_WAKEUP) { // The app was started by a wakeup WakeupId id = 0; int32_t reason = 0;