int timer () { timespec_t t; printf ( "Example program: [%s:%s]\n%s\n\n", __FILE__, __FUNCTION__, timer_PROG_HELP ); clock_gettime ( CLOCK_REALTIME, &t0 ); printf ( "System time: %d:%d\n", t0.tv_sec, t0.tv_nsec/100000000 ); t.tv_sec = 10; t.tv_nsec = 555555555; clock_settime ( CLOCK_REALTIME, &t ); printf ( "System time set to: %d:%d\n", t.tv_sec, t.tv_nsec/100000000 ); clock_gettime ( CLOCK_REALTIME, &t0 ); printf ( "System time: %d:%d\n", t0.tv_sec, t0.tv_nsec/100000000 ); t.tv_sec = 3; t.tv_nsec = 0; arch_timer_set ( &t, alarm ); do { clock_gettime ( CLOCK_REALTIME, &t ); } while ( t0.tv_sec + 5 > t.tv_sec ); printf ( "System time: %d:%d\n", t.tv_sec, t.tv_nsec / 100000000 ); return 0; }
/*! Iterate through active alarms and activate newly expired ones */ static void k_schedule_alarms () { kalarm_t *first; time_t time, ref_time; arch_get_time ( &time ); ref_time = time; time_add ( &ref_time, &threshold ); /* should any alarm be activated? */ first = list_get ( &kalarms, FIRST ); while ( first != NULL ) { if ( time_cmp ( &first->alarm.exp_time, &ref_time ) <= 0 ) { /* 'activate' alarm */ /* but first remove alarm from list */ first = list_remove ( &kalarms, FIRST, NULL ); if ( first->alarm.flags & ALARM_PERIODIC ) { /* calculate next activation time */ time_add ( &first->alarm.exp_time, &first->alarm.period ); /* put back into list */ list_sort_add ( &kalarms, first, &first->list, alarm_cmp ); } else { first->active = 0; } if ( first->alarm.action ) /* activate alarm */ first->alarm.action ( first->alarm.param ); first = list_get ( &kalarms, FIRST ); } else { break; } } first = list_get ( &kalarms, FIRST ); if ( first ) { ref_time = first->alarm.exp_time; time_sub ( &ref_time, &time ); arch_timer_set ( &ref_time, k_timer_interrupt ); } }
/*! Activate timers and reschedule threads if required */ static void ktimer_schedule () { ktimer_t *first; timespec_t time, ref_time; int resched = 0; kclock_gettime ( CLOCK_REALTIME, &time ); /* should have separate "scheduler" for each clock */ ref_time = time; time_add ( &ref_time, &threshold ); /* use "ref_time" instead of "time" when looking timers to activate */ /* should any timer be activated? */ first = list_get ( &ktimers, FIRST ); while ( first != NULL ) { /* timers have absolute values in 'it_value' */ if ( time_cmp ( &first->itimer.it_value, &ref_time ) <= 0 ) { /* 'activate' timer */ /* but first remove timer from list */ first = list_remove ( &ktimers, FIRST, NULL ); /* and add to list if period is given */ if ( TIME_IS_SET ( &first->itimer.it_interval) ) { /* calculate next activation time */ time_add ( &first->itimer.it_value, &first->itimer.it_interval ); /* put back into list */ list_sort_add ( &ktimers, first, &first->list, ktimer_cmp ); } else { TIMER_DISARM ( first ); } if ( first->owner == NULL ) { /* timer set by kernel - call now, directly */ if ( first->evp.sigev_notify_function ) first->evp.sigev_notify_function ( first->evp.sigev_value ); } else { /* timer set by thread */ if ( !ksignal_process_event ( &first->evp, first->owner, SI_TIMER ) ) { resched++; } } first = list_get ( &ktimers, FIRST ); } else { break; } } first = list_get ( &ktimers, FIRST ); if ( first ) { ref_time = first->itimer.it_value; time_sub ( &ref_time, &time ); arch_timer_set ( &ref_time, ktimer_schedule ); } if ( resched ) kthreads_schedule (); }
/*! * Iterate through active alarms and activate newly expired ones */ static int k_schedule_alarms () { kalarm_t *first; time_t time, ref_time; int resched_thr = 0; kprocess_t *proc; arch_get_time ( &time ); ref_time = time; time_add ( &ref_time, &threshold ); /* should any alarm be activated? */ first = list_get ( &kalarms, FIRST ); while ( first != NULL ) { if ( time_cmp ( &first->alarm.exp_time, &ref_time ) <= 0 ) { /* 'activate' alarm */ /* but first remove alarm from list */ first = list_remove ( &kalarms, FIRST, NULL ); if ( first->alarm.flags & ALARM_PERIODIC ) { /* calculate next activation time */ time_add ( &first->alarm.exp_time, &first->alarm.period ); /* put back into list */ list_sort_add ( &kalarms, first, &first->list, alarm_cmp ); } else { first->active = 0; } if ( first->alarm.action ) { /* call directly: first->alarm.action ( first->alarm.param ); or create new thread for that job: */ if ( first->thread ) { /* alarm scheduled by thread */ proc = k_get_thread_process ( first->thread ); k_create_thread ( first->alarm.action, first->alarm.param, proc->pi->exit, k_get_thread_prio ( first->thread ) + 1, NULL, 0, 1, proc ); resched_thr++; } else { /* alarm scheduled by kernel */ first->alarm.action ( first->alarm.param ); } } resched_thr += k_release_all_threads ( &first->queue ); first = list_get ( &kalarms, FIRST ); } else { break; } } first = list_get ( &kalarms, FIRST ); if ( first ) { ref_time = first->alarm.exp_time; time_sub ( &ref_time, &time ); arch_timer_set ( &ref_time, k_timer_interrupt ); } return resched_thr; }