/*perform a process switch*/ void handletimerinterrupt(short segment, short sp) { int i,cntr=79; /*save current process*/ process_table[current_process].segment=segment; process_table[current_process].sp=sp; /*print out the active processes at the top of the screen*/ for (i=MAXPROCESSES-1; i>=0; i--) { if (process_table[i].active>0) { printtop('P',cntr-5); printtop((char)(i+0x30),cntr-4); printtop(' ',cntr-3); if (process_table[i].active==1) printtop('A',cntr-2); else if (process_table[i].active==2) printtop('W',cntr-2); else if (process_table[i].active==3) printtop('K',cntr-2); printtop(' ',cntr-1); printtop(' ',cntr); cntr=cntr-6; } } printtop(' ',cntr); printtop(' ',cntr-1); printtop(':',cntr-2); printtop('s',cntr-3); printtop('e',cntr-4); printtop('s',cntr-5); printtop('s',cntr-6); printtop('e',cntr-7); printtop('c',cntr-8); printtop('o',cntr-9); printtop('r',cntr-10); printtop('P',cntr-11); /*find an active process round robin style*/ i=current_process; do { i++; if (i==MAXPROCESSES) i=0; } while(process_table[i].active!=1); current_process=i; /*restore that process*/ timer_restore(process_table[current_process].segment,process_table[current_process].sp); }
static void timers_migrate_2(void) { if (! persist_exists(PERSIST_TIMER_START)) { return; } int block_number = 0; TimerBlockTiny* block = malloc(sizeof(TimerBlockTiny)); persist_read_data(PERSIST_TIMER_START, block, sizeof(TimerBlockTiny)); uint8_t timer_count = block->total_timers; for (int t = 0; t < timer_count; t += 1) { if (t > 0 && t % TIMER_BLOCK_SIZE == 0) { block_number += 1; if (NULL != block) { free(block); block = NULL; } block = malloc(sizeof(TimerBlockTiny)); persist_read_data(PERSIST_TIMER_START + block_number, block, sizeof(TimerBlockTiny)); } TimerTiny* timer_tiny = &block->timers[t % TIMER_BLOCK_SIZE]; int seconds_elapsed = time(NULL) - block->save_time; Timer* timer = malloc(sizeof(Timer)); timer->id = timer_tiny->id; timer->current_time = timer_tiny->current_time; timer->length = timer_tiny->length; timer->repeat = timer_tiny->repeat; timer->repeat_count = timer_tiny->repeat_count; timer->status = timer_tiny->status; timer->vibration = timer_tiny->vibration; timer->type = timer_tiny->type; timer->wakeup_id = timer_tiny->wakeup_id; timer->timer = NULL; strcpy(timer->label, timer_tiny->label); timer_restore(timer, seconds_elapsed); timers_add(timer); } if (NULL != block) { free(block); } }
void timers_restore(void) { if (! persist_exists(PERSIST_TIMERS_VERSION)) { timers_migrate_1(); return; } if (TIMERS_VERSION_TINY == persist_read_int(PERSIST_TIMERS_VERSION)) { timers_migrate_2(); return; } timers_clear(); time_t now = time(NULL); uint16_t seconds_elapsed = 0; TimerBlock* block = NULL; if (persist_exists(PERSIST_TIMER_START)) { block = malloc(sizeof(TimerBlock)); persist_read_data(PERSIST_TIMER_START, block, sizeof(TimerBlock)); uint8_t num_timers = block->total_timers; uint8_t block_offset = 0; seconds_elapsed = now - block->save_time; for (uint8_t t = 0; t < num_timers; t += 1) { if (! block) { block = malloc(sizeof(TimerBlock)); persist_read_data(PERSIST_TIMER_START + block_offset, block, sizeof(TimerBlock)); } Timer* timer = timer_clone(&block->timers[t % TIMER_BLOCK_SIZE]); timers_add(timer); timer_restore(timer, seconds_elapsed); if (t % TIMER_BLOCK_SIZE == (TIMER_BLOCK_SIZE - 1)) { free(block); block = NULL; block_offset += 1; } } if (block) { free(block); block = NULL; } } }
static int pmtimer_resume(device_t dev) { int pl; u_int second, minute, hour; struct timeval resume_time, tmp_time; /* modified for adjkerntz */ pl = splsoftclock(); timer_restore(); /* restore the all timers */ inittodr(0); /* adjust time to RTC */ microtime(&resume_time); getmicrotime(&tmp_time); timevaladd(&tmp_time, &diff_time); #ifdef FIXME /* XXX THIS DOESN'T WORK!!! */ time = tmp_time; #endif #ifdef PMTIMER_FIXUP_CALLTODO /* Calculate the delta time suspended */ timevalsub(&resume_time, &suspend_time); /* Fixup the calltodo list with the delta time. */ adjust_timeout_calltodo(&resume_time); #endif /* PMTIMER_FIXUP_CALLTODOK */ splx(pl); #ifndef PMTIMER_FIXUP_CALLTODO second = resume_time.tv_sec - suspend_time.tv_sec; #else /* PMTIMER_FIXUP_CALLTODO */ /* * We've already calculated resume_time to be the delta between * the suspend and the resume. */ second = resume_time.tv_sec; #endif /* PMTIMER_FIXUP_CALLTODO */ hour = second / 3600; second %= 3600; minute = second / 60; second %= 60; log(LOG_NOTICE, "wakeup from sleeping state (slept %02d:%02d:%02d)\n", hour, minute, second); return (0); }
static int pmtimer_resume(device_t dev) { u_int second, minute, hour; struct timeval resume_time; /* modified for adjkerntz */ crit_enter(); timer_restore(); /* restore the all timers */ inittodr(0); /* adjust time to RTC */ microtime(&resume_time); crit_exit(); second = resume_time.tv_sec - suspend_time.tv_sec; hour = second / 3600; second %= 3600; minute = second / 60; second %= 60; log(LOG_NOTICE, "wakeup from sleeping state (slept %02d:%02d:%02d)\n", hour, minute, second); return (0); }
static void timers_migrate_1(void) { if (! persist_exists(PERSIST_TIMER_START)) { return; } int block = 0; OldTimerBlock* timerBlock = malloc(sizeof(OldTimerBlock)); persist_read_data(PERSIST_TIMER_START, timerBlock, sizeof(OldTimerBlock)); uint8_t timer_count = timerBlock->count; for (int t = 0; t < timer_count; t += 1) { if (t > 0 && t % TIMER_BLOCK_SIZE == 0) { block += 1; if (NULL != timerBlock) { free(timerBlock); timerBlock = NULL; } timerBlock = malloc(sizeof(OldTimerBlock)); persist_read_data(PERSIST_TIMER_START + block, timerBlock, sizeof(OldTimerBlock)); } OldTimer* old_timer = &timerBlock->timers[t % TIMER_BLOCK_SIZE]; int seconds_elapsed = time(NULL) - timerBlock->time; Timer* timer = malloc(sizeof(Timer)); timer->id = old_timer->id; timer->current_time = old_timer->time_left; timer->length = old_timer->length; timer->repeat = old_timer->repeat ? TIMER_REPEAT_INFINITE : 0; switch (old_timer->status) { case OLD_TIMER_STATUS_STOPPED: timer->status = TIMER_STATUS_STOPPED; break; case OLD_TIMER_STATUS_RUNNING: timer->status = TIMER_STATUS_RUNNING; break; case OLD_TIMER_STATUS_PAUSED: timer->status = TIMER_STATUS_PAUSED; break; case OLD_TIMER_STATUS_FINISHED: timer->status = TIMER_STATUS_DONE; break; } switch (old_timer->vibrate) { case OLD_TIMER_VIBRATION_OFF: timer->vibration = TIMER_VIBE_NONE; break; case OLD_TIMER_VIBRATION_SHORT: timer->vibration = TIMER_VIBE_SHORT; break; case OLD_TIMER_VIBRATION_LONG: timer->vibration = TIMER_VIBE_LONG; break; case OLD_TIMER_VIBRATION_DOUBLE: timer->vibration = TIMER_VIBE_DOUBLE; break; case OLD_TIMER_VIBRATION_TRIPLE: timer->vibration = TIMER_VIBE_TRIPLE; break; case OLD_TIMER_VIBRATION_CONTINUOUS: timer->vibration = TIMER_VIBE_SOLID; break; } switch (old_timer->direction) { case OLD_TIMER_DIRECTION_DOWN: timer->type = TIMER_TYPE_TIMER; break; case OLD_TIMER_DIRECTION_UP: timer->type = TIMER_TYPE_STOPWATCH; break; } timer->wakeup_id = -1; timer->timer = NULL; timer_restore(timer, seconds_elapsed); timers_add(timer); } if (NULL != timerBlock) { free(timerBlock); } }