/*! Start time slice for thread (or countinue interrupted) */ static int rr_thread_activate ( kthread_t *kthread ) { kthread_sched_data_t *tsched = kthread_get_sched_param ( kthread ); ksched_t *gsched = ksched_get ( tsched->sched_policy ); /* check remainder if needs to be replenished */ if ( time_cmp ( &tsched->params.rr.remainder, &gsched->params.rr.threshold ) <= 0 ) { time_add ( &tsched->params.rr.remainder, &gsched->params.rr.time_slice ); } /* Get current time and store it */ k_get_time ( &tsched->params.rr.slice_start ); /* When to wake up? */ tsched->params.rr.slice_end = tsched->params.rr.slice_start; time_add ( &tsched->params.rr.slice_end, &tsched->params.rr.remainder ); /* Set alarm for remainder time */ gsched->params.rr.alarm.exp_time = tsched->params.rr.slice_end; gsched->params.rr.alarm.param = kthread; k_alarm_set ( gsched->params.rr.rr_alarm, &gsched->params.rr.alarm ); return 0; }
int main(int argc, char *argv[]) { struct timespec start, curr; struct timers timers; struct list_head expired; struct timer t[PER_CONN_TIME]; unsigned int i, num; bool check = false; opt_register_noarg("-c|--check", opt_set_bool, &check, "Check timer structure during progress"); opt_parse(&argc, argv, opt_log_stderr_exit); num = argv[1] ? atoi(argv[1]) : (check ? 100000 : 100000000); list_head_init(&expired); curr = start = time_now(); timers_init(&timers, start); for (i = 0; i < num; i++) { curr = time_add(curr, time_from_msec(1)); if (check) timers_check(&timers, NULL); timers_expire(&timers, curr, &expired); if (check) timers_check(&timers, NULL); assert(list_empty(&expired)); if (i >= PER_CONN_TIME) { timer_del(&timers, &t[i%PER_CONN_TIME]); if (check) timers_check(&timers, NULL); } timer_add(&timers, &t[i%PER_CONN_TIME], time_add(curr, time_from_msec(CONN_TIMEOUT_MS))); if (check) timers_check(&timers, NULL); } if (num > PER_CONN_TIME) { for (i = 0; i < PER_CONN_TIME; i++) timer_del(&timers, &t[i]); } curr = time_sub(time_now(), start); if (check) timers_check(&timers, NULL); timers_cleanup(&timers); opt_free_table(); for (i = 0; i < ARRAY_SIZE(timers.level); i++) if (!timers.level[i]) break; printf("%u in %lu.%09lu (%u levels / %zu)\n", num, (long)curr.tv_sec, curr.tv_nsec, i, ARRAY_SIZE(timers.level)); 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 ); } }
static void start_flows(struct request_start_flows *request) { struct timespec start; gettime(&start); #if 0 if (start.tv_sec < request->start_timestamp) { /* If the clock is synchronized between nodes, all nodes will * start at the same time regardless of any RPC delays */ start.tv_sec = request->start_timestamp; start.tv_nsec = 0; } #else /* 0 */ UNUSED_ARGUMENT(request); #endif /* 0 */ const struct list_node *node = fg_list_front(&flows); while (node) { struct flow *flow = node->data; node = node->next; /* initalize random number generator etc */ init_math_functions(flow, flow->settings.random_seed); /* READ and WRITE */ for (int j = 0; j < 2; j++) { flow->start_timestamp[j] = start; time_add(&flow->start_timestamp[j], flow->settings.delay[j]); if (flow->settings.duration[j] >= 0) { flow->stop_timestamp[j] = flow->start_timestamp[j]; time_add(&flow->stop_timestamp[j], flow->settings.duration[j]); } } flow->next_write_block_timestamp = flow->start_timestamp[WRITE]; gettime(&flow->last_report_time); flow->first_report_time = flow->last_report_time; flow->next_report_time = flow->last_report_time; time_add(&flow->next_report_time, flow->settings.reporting_interval); } started = 1; }
void ccmd_forward(t_data *data, int cs, char **cmd, t_timeval **t) { t_player *player; t_timeval now; if (*t == NULL) { gettimeofday(&now, NULL); *t = (t_timeval*)malloc(sizeof(t_timeval)); **t = time_add(data, &now, MOVE_T); return ; } (void)cmd; player = &data->fds[cs].player; if (player->o == N) player->y = mod(player->y - 1, data->y); else if (player->o == S) player->y = mod(player->y + 1, data->y); else if (player->o == W) player->x = mod(player->x - 1, data->x); else if (player->o == E) player->x = mod(player->x + 1, data->x); dprintf(cs, "ok\n"); gui_broadcast(data, gui_ppo, player); }
/*! * Registered 'arch' handler for timer interrupts; * update system time and forward interrupt to kernel if its timer is expired */ static void arch_timer_handler () { void (*k_handler) (); time_add ( &clock, &last_load ); time_sub ( &delay, &last_load ); last_load = timer->max_interval; if ( time_cmp ( &delay, &threshold ) <= 0 ) { delay = timer->max_interval; timer->set_interval ( &last_load ); k_handler = alarm_handler; alarm_handler = NULL; /* reset kernel callback function */ if ( k_handler ) k_handler (); /* forward interrupt to kernel */ } else { if ( time_cmp ( &delay, &last_load ) < 0 ) last_load = delay; timer->set_interval ( &last_load ); } }
static void timer_check() { struct timespec now; if (!started) return; gettime(&now); for (unsigned int i = 0; i < num_flows; i++) { struct _flow *flow = &flows[i]; DEBUG_MSG(LOG_DEBUG, "processing timer_check() for flow %d", flow->id); if (!flow->settings.reporting_interval) continue; if (!time_is_after(&now, &flow->next_report_time)) continue; /* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */ if (flow->fd != -1) flow->statistics[INTERVAL].has_tcp_info = get_tcp_info(flow, &flow->statistics[INTERVAL].tcp_info) ? 0 : 1; report_flow(flow, INTERVAL); do { time_add(&flow->next_report_time, flow->settings.reporting_interval); } while (time_is_after(&now, &flow->next_report_time)); } DEBUG_MSG(LOG_DEBUG, "finished timer_check()"); }
static void timer_init(t_data *data, t_timeval **timer) { t_timeval now; gettimeofday(&now, NULL); *timer = (t_timeval*)malloc(sizeof(t_timeval)); **timer = time_add(data, &now, BCAST_T); }
/* * ExecuteTimers: checks to see if any currently pending timers have * gone off, and if so, execute them, delete them, etc, setting the * current_exec_timer, so that we can't remove the timer while its * still executing. * * changed the behavior: timers will not hook while we are waiting. */ void ExecuteTimers (void) { Timeval right_now; Timer * current, *next; int old_from_server = from_server; get_time(&right_now); while (PendingTimers && time_diff(right_now, PendingTimers->time) < 0) { int old_refnum; old_refnum = current_window->refnum; current = PendingTimers; unlink_timer(current); /* Reschedule the timer if necessary */ if (current->events < 0 || (current->events != 1)) { next = clone_timer(current); if (next->events != -1) next->events--; next->time = time_add(next->time, next->interval); schedule_timer(next); } /* * Restore from_server and current_window from when the * timer was registered */ make_window_current_by_refnum(current->window); if (is_server_open(current->server)) from_server = current->server; else if (is_server_open(current_window->server)) from_server = current_window->server; else from_server = NOSERV; /* * If a callback function was registered, then * we use it. If no callback function was registered, * then we use ''parse_line''. */ get_time(&right_now); now = right_now; if (current->callback) (*current->callback)(current->callback_data); else parse_line("TIMER", current->command, current->subargs ? current->subargs : empty_string, 0,0); from_server = old_from_server; make_window_current_by_refnum(old_refnum); delete_timer(current); } }
void thread_pause (int delay) { context_disable (); if (current_process) { thread_insert_timer (current_process, time_add (delay, current_process->time)); } context_switch (context_select ()); }
static void timer_init(t_data *data, t_timeval **timer, t_player *player) { t_timeval now; gettimeofday(&now, NULL); *timer = (t_timeval*)malloc(sizeof(t_timeval)); **timer = time_add(data, &now, DROP_T); gui_broadcast(data, gui_pfk, player); }
/* * update the packet (num and size) counters * and get the time diff to calculate the * rate */ void stats_half_end(struct half_stats *hs, u_int len) { struct timeval diff; float ttime; float ptime; /* get the time */ gettimeofday(&hs->te, 0); time_sub(&hs->te, &hs->ts, &diff); time_add(&hs->ttot, &diff, &hs->ttot); time_add(&hs->tpar, &diff, &hs->tpar); /* calculate the rate (packet/time) */ ttime = hs->ttot.tv_sec + hs->ttot.tv_usec/1.0e6; ptime = hs->tpar.tv_sec + hs->tpar.tv_usec/1.0e6; /* update the packet count */ hs->pck_recv++; hs->pck_size += len; hs->tmp_size += len; if ( (hs->pck_recv % GBL_CONF->sampling_rate) == 0 ) { /* save the average and the worst sampling */ hs->rate_adv = hs->pck_recv/ttime; if (hs->rate_worst > GBL_CONF->sampling_rate/ptime || hs->rate_worst == 0) hs->rate_worst = GBL_CONF->sampling_rate/ptime; hs->thru_adv = hs->pck_size/ttime; if (hs->thru_worst > hs->tmp_size/ptime || hs->thru_worst == 0) hs->thru_worst = hs->tmp_size/ptime; #if 0 DEBUG_MSG("PACKET RATE: %llu [%d] [%d] -- [%d] [%d]\n", hs->pck_recv, hs->rate_worst, hs->rate_adv, hs->thru_worst, hs->thru_adv); #endif /* reset the partial */ memset(&hs->tpar, 0, sizeof(struct timeval)); hs->tmp_size = 0; } }
/*! * Get 'current' system time * \param time Store address for current time */ void arch_get_time ( time_t *time ) { time_t remainder; timer->get_interval_remainder ( &remainder ); *time = last_load; time_sub ( time, &remainder ); time_add ( time, &clock ); }
/* Configures the program to die with SIGALRM 'secs' seconds from now, if * 'secs' is nonzero, or disables the feature if 'secs' is zero. */ void time_alarm(unsigned int secs) { sigset_t oldsigs; time_init(); block_sigalrm(&oldsigs); deadline = secs ? time_add(time_now(), secs) : TIME_MIN; unblock_sigalrm(&oldsigs); }
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes, struct timeval *timeout) { #ifdef VERBOSE printf("vrpn_read_available_characters(timeout): Entering\n"); #endif struct timeval start, finish, now; int sofar = 0, ret; // How many characters we have read so far unsigned char *where = buffer; // Find out what time it is at the start, and when we should end // (unless the timeout is NULL) if (timeout == NULL) { // Set up so that it will never be that now > finish // This prevents the while() loop below from stopping looping vrpn_gettimeofday(&now, NULL); memcpy(&finish, &now, sizeof(finish)); vrpn_gettimeofday(&finish, NULL); } else { vrpn_gettimeofday(&start, NULL); memcpy(&now, &start, sizeof(now)); time_add(start, *timeout, finish); } // Keep reading until we timeout. Exit from the middle of this by // returning if we complete or find an error so that the loop only has // to check for timeout, not other terminating conditions. do { ret = vrpn_read_available_characters(comm, where, bytes - sofar); if (ret == -1) { return -1; } sofar += ret; if (sofar == bytes) { break; } where += ret; if (timeout != NULL) { // Update the time if we are checking timeout vrpn_gettimeofday(&now, NULL); } } while (!(time_greater(now, finish))); #ifdef VERBOSE printf("vrpn_read_available_characters(timeout): Exiting\n"); #endif return sofar; }
void ccmd_right(t_data *data, int cs, char **cmd, t_timeval **t) { t_player *player; t_timeval now; if (!(*t)) { gettimeofday(&now, NULL); *t = (t_timeval*)malloc(sizeof(t_timeval)); **t = time_add(data, &now, MOVE_T); return ; } (void)cmd; player = &data->fds[cs].player; player->o = (player->o % 4) + 1; dprintf(cs, "ok\n"); gui_broadcast(data, gui_ppo, player); }
void cpustats_leave() { unsigned int oldmask = 0; oldmask = irq_getmask(); irq_setmask(0); enter_count--; if(enter_count == 0) { struct timestamp ts; struct timestamp diff; time_get(&ts); time_diff(&diff, &ts, &first_enter); time_add(&acc, &diff); } irq_setmask(oldmask); }
static t_egg *init_egg(t_data *data, int cs, t_player *player, t_timeval t) { t_egg *egg; egg = (t_egg*)malloc(sizeof(t_egg)); egg->id = data->egg_nb++; egg->owner = cs; egg->team = strdup(player->team); egg->food = 10; egg->food_t = t; egg->birth = time_add(data, &t, BIRTH_T); egg->ready = 0; egg->x = player->x; egg->y = player->y; egg->o = player->o; egg->next = data->eggs; return (egg); }
void ccmd_invent(t_data *data, int cs, char **cmd, t_timeval **t) { t_player *player; char buf[BUF_SIZE]; t_timeval now; if (!(*t)) { gettimeofday(&now, NULL); *t = (t_timeval*)malloc(sizeof(t_timeval)); **t = time_add(data, &now, MOVE_T); return ; } (void)cmd; player = &(data->fds[cs].player); concat(buf, player); dprintf(cs, "%s\n", buf); }
static void work_run_usrcpu(int work_id, long micros) { TRACE("work %d: Starting mathematical calculations...\n", work_id); long i = 0, j = 0; double pi = 0; struct timeval curtime, endtime; gettimeofday(&endtime, 0); time_add(&endtime, micros); for (;;) { gettimeofday(&curtime, 0); if (!time_before(&curtime, &endtime)) { break; } for (j = i + 1000; i < j; ++i) { pi += 1.0 / (i * 4.0 + 1.0); pi -= 1.0 / (i * 4.0 + 3.0); } } TRACE("work %d: Completed calculation, did %ld iterations\n", work_id, j) }
static void up_handler(state_t s, event_t e, unmarsh_t abv) { endpt_id_t origin ; unmarsh_endpt_id(abv, &origin) ; if (s->partition) { sys_abort() ; } else { etime_t delay ; if (!distrib(s, &delay)) { up_free(e, abv) ; } else { etime_t when = time_add(alarm_gettime(s->alarm), delay) ; item_t item = record_create(item_t, item) ; /*eprintf("type=%s\n", event_type_to_string(event_type(e))) ;*/ item->type = DROP_UP ; item->u.up.event = e ; item->u.up.abv = abv ; priq_add(s->priq, when, item) ; dnnm(s, event_timer_time(when)) ; } } }
/*! * Set next timer activation * \param time Time of next activation * \param alarm_func Function to call upon timer expiration */ void arch_timer_set ( time_t *time, void *alarm_func ) { time_t remainder; timer->get_interval_remainder ( &remainder ); time_sub ( &last_load, &remainder ); time_add ( &clock, &last_load ); delay = *time; if ( time_cmp ( &delay, &timer->min_interval ) < 0 ) delay = timer->min_interval; alarm_handler = alarm_func; if ( time_cmp ( &delay, &timer->max_interval ) > 0 ) last_load = timer->max_interval; else last_load = delay; timer->set_interval ( &last_load ); }
static void nvod_video_calc_left_time() { time_shifted_svc_evt_t *p_ts_svc_evt = NULL; u32 total_left_second = 0; utc_time_t end_time = {0}; utc_time_t cur_time = {0}; p_ts_svc_evt = ui_get_playing_nvod_time_shifted_svc_evt(); time_get(&cur_time,TRUE); g_past_second = time_dec(&cur_time, &p_ts_svc_evt->start_time); memset(&left_time, 0, sizeof(utc_time_t)); memcpy(&end_time, &p_ts_svc_evt->start_time, sizeof(utc_time_t)); time_add(&end_time, &p_ts_svc_evt->drt_time); total_left_second = time_dec(&end_time, &cur_time); left_time.hour = (u8)(total_left_second / 3600); left_time.minute = (u8)((total_left_second % 3600)/60); left_time.second = (u8)((total_left_second % 60)); }
/*! * Arm/disarm timer * \param ktimer Timer * \param flags Various flags * \param value Set timer values (it_value+it_period) * \param ovalue Where to store time to next timer expiration (+period) * \return status 0 for success */ int ktimer_settime ( ktimer_t *ktimer, int flags, itimerspec_t *value, itimerspec_t *ovalue ) { timespec_t now; ASSERT ( ktimer ); kclock_gettime ( ktimer->clockid, &now ); if ( ovalue ) { *ovalue = ktimer->itimer; /* return relative time to timer expiration */ if ( TIME_IS_SET ( &ovalue->it_value ) ) time_sub ( &ovalue->it_value, &now ); } /* first disarm timer, if it was armed */ if ( TIMER_IS_ARMED ( ktimer ) ) { TIMER_DISARM ( ktimer ); list_remove ( &ktimers, 0, &ktimer->list ); } if ( value && TIME_IS_SET ( &value->it_value ) ) { /* arm timer */ ktimer->itimer = *value; if ( !(flags & TIMER_ABSTIME) ) /* convert to absolute time */ time_add ( &ktimer->itimer.it_value, &now ); list_sort_add ( &ktimers, ktimer, &ktimer->list, ktimer_cmp ); } ktimer_schedule (); return EXIT_SUCCESS; }
/* * Must be called with interrupts disabled, * and with the CPU time counter counting. */ void cpustats_tick() { struct timestamp ts; struct timestamp diff; int usec; if(enter_count == 0) { printf("cpustats_tick() called with enter_count == 0!\n"); return; } time_get(&ts); time_diff(&diff, &ts, &first_enter); time_add(&acc, &diff); usec = acc.sec*1000000+acc.usec; load = usec/10000; first_enter.sec = ts.sec; first_enter.usec = ts.usec; acc.sec = 0; acc.usec = 0; }
static void work_run_syscpu(int work_id, long micros) { TRACE("work %d: Starting writing to temporary file...\n", work_id); FILE* fd; long i = 0, j = 0; char buf[1024]; struct timeval curtime, endtime; gettimeofday(&endtime, 0); time_add(&endtime, micros); if (fd = tmpfile()) { for (;;) { gettimeofday(&curtime, 0); if (!time_before(&curtime, &endtime)) { break; } for (j = i + 10; i < j; ++i) { fwrite(buf, 1, sizeof (buf), fd); fflush(fd); } } fclose(fd); } TRACE("work %d: Completed writing to file, wrote %ld bytes\n", work_id, j * sizeof(buf)); }
static void timer_check() { struct timespec now; if (!started) return; gettime(&now); const struct list_node *node = fg_list_front(&flows); while (node) { struct flow *flow = node->data; node = node->next; DEBUG_MSG(LOG_DEBUG, "processing timer_check() for flow %d", flow->id); if (!flow->settings.reporting_interval) continue; if (!time_is_after(&now, &flow->next_report_time)) continue; /* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */ if (flow->fd != -1) flow->statistics[INTERVAL].has_tcp_info = get_tcp_info(flow, &flow->statistics[INTERVAL].tcp_info) ? 0 : 1; report_flow(flow, INTERVAL); do { time_add(&flow->next_report_time, flow->settings.reporting_interval); } while (time_is_after(&now, &flow->next_report_time)); } DEBUG_MSG(LOG_DEBUG, "finished timer_check()"); }
static RET_CODE epg_event_list_update(control_t* p_list, u16 start, u16 size, u32 context) { event_node_t *p_evt_node = NULL; u16 total_evt = 0; utc_time_t curn_time = {0}; s8 time_cmp_result = 0; u8 i, pos; u8 ascstr[32]; u16 cnt = list_get_count(p_list); utc_time_t start_time = {0}; utc_time_t end_time = {0}; book_pg_t temp_node = {0}; p_evt_node = mul_epg_get_sch_event(&g_prog_info, &total_evt); if(p_evt_node == NULL) { return ERR_FAILURE; } /*! found start event node. */ if(start > 0) { p_evt_node = mul_epg_get_sch_event_by_pos(&g_prog_info, p_evt_node, start); } for (i = 0; i < size; i++) { pos = (u8)(i + start); if((pos < cnt) && (pos < total_evt)) { if(p_evt_node != NULL) { time_to_local(&(p_evt_node->start_time), &start_time); memcpy(&end_time, &start_time, sizeof(utc_time_t)); time_add(&end_time, &(p_evt_node->drt_time)); sprintf((char*)ascstr,"%.2d:%.2d-%.2d:%.2d", \ start_time.hour, start_time.minute,\ end_time.hour, end_time.minute); memset(&temp_node, 0, sizeof(book_pg_t)); temp_node.pgid = db_dvbs_get_id_by_view_pos(ui_dbase_get_pg_view_id(), prog_focus); memcpy(&(temp_node.start_time), &start_time, sizeof(utc_time_t)); memcpy(&(temp_node.drt_time), &(p_evt_node->drt_time), sizeof(utc_time_t)); temp_node.book_mode = BOOK_TMR_ONCE; time_get(&curn_time, FALSE); time_cmp_result = time_cmp(&start_time, &curn_time, FALSE); if((book_get_match_node(&temp_node) < MAX_BOOK_PG) && (time_cmp_result >= 0)) { list_set_field_content_by_icon(p_list, pos, 0, IM_EPG_BOOK); } else { list_set_field_content_by_icon(p_list, pos, 0, 0); } list_set_field_content_by_ascstr(p_list, pos, 1, ascstr); list_set_field_content_by_unistr(p_list, pos, 2, p_evt_node->event_name); if(p_evt_node != NULL && p_evt_node->p_sht_text != NULL) { list_set_field_content_by_icon(p_list, pos, 3, IM_EPG_INFOR); } else { list_set_field_content_by_icon(p_list, pos, 3, 0); } p_evt_node = mul_epg_get_sch_event_by_pos(&g_prog_info, p_evt_node, 1); } } } return SUCCESS; }
/*! 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 (); }
static void upnm_handler(state_t s, event_t e) { switch(event_type(e)) { case EVENT_FAIL: assert(bool_array_super(event_failures(e), s->failed, s->vs->nmembers)) ; bool_array_copy_into(s->failed, event_failures(e), s->vs->nmembers) ; upnm(s, e) ; break ; case EVENT_INIT: dnnm(s, event_timer_time(time_zero())) ; upnm(s, e) ; break ; case EVENT_TIMER: { etime_t time = event_time(e) ; item_t item ; while (priq_get_upto(s->priq, time, NULL, (void**)&item)) { s->acct_delivered ++ ; switch(item->type) { case DROP_UP: { rank_t origin = event_peer(item->u.up.event) ; if (origin >= 0 && array_get(s->failed, origin)) { up_free(item->u.up.event, item->u.up.abv) ; } else { up(s, item->u.up.event, item->u.up.abv) ; } } break ; case DROP_UPNM: upnm(s, item->u.upnm.event) ; break ; OTHERWISE_ABORT() ; } record_free(item) ; } if (time_ge(time, s->next_sweep)) { if (!time_is_zero(s->next_sweep) && sys_random(5) == 1) { rank_t i ; bool_array_t suspects = bool_array_create_init(s->vs->nmembers, FALSE) ; for(i=0;i<s->vs->nmembers;i++) { if (i == s->ls->rank) { continue ; } if (sys_random(4) == 0) { array_set(suspects, i, TRUE) ; } } if (bool_array_exists(suspects, s->vs->nmembers)) { dnnm(s, event_suspect_reason_create(suspects, name)) ; } else { array_free(suspects) ; } } #if 0 /* Suspicions are randomly generated every 0-8 seconds. */ s->next_sweep = time_add(time, time_of_usecs(sys_random(1<<23/*8M*/))) ; #else s->next_sweep = time_add(time, time_of_usecs(sys_random(1<<20/*1M*/))) ; #endif dnnm(s, event_timer_time(s->next_sweep)) ; /* request next sweep */ } upnm(s, e) ; } break ; case EVENT_GOSSIP_EXT: { /*endpt_id_t origin = NULL ;*/ etime_t delay ; /* let origin = getExtender (function | HealGos(_,(_,endpt),_,_) -> Some (Some endpt) | SwitchGos(_,(_,endpt),_) -> Some (Some endpt) | _ -> None ) None ev in */ if (1 /*!origin*/) { upnm(s, e) ; } else if (s->partition) { sys_abort() ; } else if (!distrib(s, &delay)) { event_free(e) ; } else { /* Deliver after a certain delay.... */ etime_t when = time_add(alarm_gettime(s->alarm), delay) ; item_t item = record_create(item_t, item) ; item->type = DROP_UPNM ; item->u.upnm.event = e ; priq_add(s->priq, when, item) ; dnnm(s, event_timer_time(when)) ; } } break ; case EVENT_ACCOUNT: log(("delivered=%d dropped=%d", s->acct_delivered, s->acct_dropped)) ; upnm(s, e) ; break ; EVENT_DUMP_HANDLE() ; default: upnm(s, e) ; break ; } }