void mem_event_handler(mem_state * s, tw_bf * bf, mem_message * m, tw_lp * lp) { tw_lpid dest; tw_event *e; tw_memory *b; int i; s->stats.s_recv++; // read membufs off inbound event, check it and free it for(i = 0; i < nbufs; i++) { b = tw_event_memory_get(lp); if(!b) tw_error(TW_LOC, "Missing memory buffers: %d of %d", i+1, nbufs); mem_verify(b); tw_memory_free(lp, b, my_fd); s->stats.s_mem_free++; s->stats.s_mem_get++; } if(tw_rand_unif(lp->rng) <= percent_remote) { bf->c1 = 1; dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); dest += offset_lpid; if(dest >= ttl_lps) dest -= ttl_lps; } else { bf->c1 = 0; dest = lp->gid; } e = tw_event_new(dest, tw_rand_exponential(lp->rng, mean), lp); // allocate membufs and attach them to the event for(i = 0; i < nbufs; i++) { b = mem_alloc(lp); if(!b) tw_error(TW_LOC, "no membuf allocated!"); mem_fill(b); tw_event_memory_set(e, b, my_fd); s->stats.s_mem_alloc++; } tw_event_send(e); }
/* * There is nothing to do with ACKs unless I get a negative ACK */ void ospf_ack_process(ospf_nbr * nbr, tw_bf * bf, tw_lp * lp) { tw_memory *buf; ospf_db_entry *dbe; int cnt; cnt = 0; for (buf = tw_event_memory_get(lp); buf; buf = tw_event_memory_get(lp)) { dbe = tw_memory_data(buf); tw_memory_free(lp, buf, g_ospf_fd); } #if VERIFY_OSPF_ACK if (nbr->state < ospf_nbr_exchange_st) { printf("%ld: nbr state is %d: LS ACK is ignored\n", lp->gid, nbr->state); return; } #endif }
void rm_particle_handler(rm_state * state, tw_bf * bf, rm_message * m, tw_lp * lp) { //tw_memory *b; //tw_memory *b_in; #if VERIFY_PARTICLE && DWB rm_particle *p; double *position; #endif #if DWB b_in = tw_event_memory_get(lp); #endif #if 0 if(state->prev_time != tw_now(lp)) { if(state->initial) { bf->c1 = 1; tw_memory_free(lp, state->initial, g_rm_fd); state->initial = NULL; } state->initial = b_in; state->prev_time = tw_now(lp); } else if(state->initial != NULL) { bf->c0 = 1; rm_proximity_send(state, b_in, state->initial, lp); tw_memory_free(lp, b_in, g_rm_fd); tw_memory_free(lp, state->initial, g_rm_fd); state->initial = NULL; } else tw_error(TW_LOC, "Initial == NULL, but prev_time == now!"); #endif #if DWB // if in next timestep, dump the particle queue and add this particle //if(state->prev_time != tw_now(lp) && state->particles->size != 0) if(state->prev_time != tw_now(lp)) { bf->c0 = 1; while((NULL != (b = tw_memoryq_pop(state->particles)))) tw_memory_free(lp, b, g_rm_fd); state->initial = b_in; state->prev_time = tw_now(lp); } else // check if we have detected a collision { // and send notifications to affected user LPs for(b = state->particles->head; b; b = b->next) rm_proximity_send(state, b_in, state->initial, lp); } // add this particle to the queue tw_memoryq_push(state->particles, b_in); #endif #if VERIFY_PARTICLE && DWB // plot leading edge of node range p = tw_memory_data(b_in); position = rm_getlocation(lp); fprintf(g_rm_parts_plt_f, "%lf %ld %lf %lf %ld\n", tw_now(lp), p->user_lp->id, position[0], position[1], lp->id); #endif }
/* * epi_event_handler - main event processing (per node LP) * * state - our node LP state space * bf - a bitfield provided by the simulation ecxecutive * m - the incoming event or message * lp - our node LP */ void epi_event_handler(epi_state * state, tw_bf * bf, epi_message * msg, tw_lp * lp) { tw_memory *buf; tw_memory *b; epi_agent *a; int population; int ncontagious[g_epi_ndiseases]; int today; int pq_clean = 0; int i; // TO DO: need to check for last day to get last day of statistics today = (int) (tw_now(lp) / TWENTY_FOUR_HOURS); population = pq_get_size(g_epi_pq[lp->id]); for(i = 0; i < g_epi_ndiseases; i++) ncontagious[i] = state->ncontagious[i]; if(today > g_epi_day) { // report yesterday's statistics epi_report_census_tract(today); epi_report_hospitals(today); g_epi_day++; printf("%ld: DAY %d \n", lp->id, today); } if(g_epi_complete) return; // may return NULL in case of EPI_REMOVE if(NULL != (buf = tw_event_memory_get(lp))) { a = tw_memory_data(buf); while(NULL != (b = tw_event_memory_get(lp))) { b->next = a->pathogens; a->pathogens = b; } epi_agent_add(state, bf, buf, lp); printf("%ld: ADD %d at %lf \n", lp->id, a->id, tw_now(lp)); } else { epi_agent_remove(state, bf, lp); } // Bring SEIR computation up to date for the agents at this location // Ok to skip if no change to infectious population, // or no change to overall location population // // basically, avoid calling epi_seir_update, like it was the plague, // pun intended. for(i = 0; i < g_epi_ndiseases; i++) { if((population != pq_get_size(g_epi_pq[lp->id]) && state->ncontagious[i]) || ncontagious[i] != state->ncontagious[i]) { epi_seir_compute(state, bf, i, lp); pq_clean = 1; } } if(pq_clean) pq_cleanup(g_epi_pq[lp->id]); epi_location_timer(state, lp); }
/** * OSPF model event handler function. * * This is the OSPF model event handler function. This function is a * simple switch statement which determine what kind of event was recieved * and passes control to the appropriate function. */ void ospf_event_handler(ospf_state * state, tw_bf * bf, rn_message * rn_msg, tw_lp * lp) { tw_memory *b; ospf_nbr *nbr; ospf_message *msg; // get the OSPF message header b = tw_event_memory_get(lp); if(!b) tw_error(TW_LOC, "No membuf on event!"); msg = tw_memory_data(b); nbr = ospf_int_getinterface(state, rn_msg->src); if(!nbr) nbr = msg->data; if(rn_msg->type != TIMER && rn_getas(state->m) != rn_getas(nbr->m)) printf("Got event from nbr outside my AS! \n"); /* //printf("%d: got message %d at %g\n", lp->gid, rn_msg->src, tw_now(lp)); if(g_route[gr1] == lp->gid) { gr1++; g_route[gr1] = state->from; } if(g_route1[gr2] == lp->gid) { gr2++; g_route1[gr2] = state->from1; } */ if(rn_msg->port != 23) tw_error(TW_LOC, "%ld: recv non-ospf message from %d!", lp->gid, nbr->id); switch (msg->type) { case OSPF_HELLO_MSG: #if VERIFY_HELLO || 1 if(1 == lp->gid) printf("%lld OSPF: recv HELLO_MSG (%ld) from %lld, ts %f\n", lp->gid, (long int) lp->pe->cur_event, rn_msg->src, tw_now(lp)); #endif ospf_hello_packet(state, nbr, msg->data, bf, lp); state->stats->s_e_hello_in++; break; case OSPF_HELLO_SEND: #if VERIFY_HELLO || 1 if(1 == lp->gid) printf("%lld OSPF: recv HELLO_SEND timer from %lld, ts %lf \n", lp->gid, rn_msg->src, tw_now(lp)); #endif ospf_hello_send(state, nbr, bf, lp); break; case OSPF_DD_MSG: #if VERIFY_DD || 1 if(1 == lp->gid) printf("\n%lld OSPF: got DD packet from %lld\n", lp->gid, rn_msg->src); #endif ospf_dd_event_handler(state, nbr, bf, lp); state->stats->s_e_dd_msgs++; break; case OSPF_LS_REQUEST: #if VERIFY_LS || 1 if(1 == lp->gid) printf("\n%lld: got LS_Request from %lld at %f\n", lp->gid, rn_msg->src, tw_now(lp)); #endif ospf_ls_request_recv(state, bf, nbr, lp); state->stats->s_e_ls_requests++; break; case OSPF_LS_UPDATE: #if VERIFY_LS || 1 if(1 == lp->gid) printf("\n%lld: got LS Update from %lld at %f\n", lp->gid, rn_msg->src, tw_now(lp)); #endif ospf_ls_update_recv(state, bf, nbr, lp); state->stats->s_e_ls_updates++; break; case OSPF_FLOOD_TIMEOUT: tw_error(TW_LOC, "Should not be here!!"); //ospf_flood_recv(state, nbr, bf, lp); break; case OSPF_LS_ACK: #if VERIFY_LS || 1 if(1 == lp->gid) printf("\n%lld: got LS_ACK from %lld %f\n", lp->gid, rn_msg->src, tw_now(lp)); #endif ospf_ack_process(nbr, bf, lp); state->stats->s_e_ls_acks++; break; case OSPF_AGING_TIMER: #if VERIFY_AGING || 1 if(1 == lp->gid) printf("%lld: got AGING_TIMER at %f\n", lp->gid, tw_now(lp)); #endif ospf_aging_timer(state, bf, lp); state->stats->s_e_aging_timeouts++; break; case OSPF_RT_TIMER: #if 1 printf("\n%lld: rt timer fired! \n", lp->gid); #endif tw_event_memory_get(lp); ospf_rt_timer(state, lp->gid); break; case OSPF_RETRANS_TIMEOUT: #if VERIFY_DD || 1 if(1 == lp->gid) printf("%lld: got RETRANS_TIMEOUT\n", lp->gid); #endif tw_error(TW_LOC, "should not be here!"); ospf_dd_retransmit(state, nbr, bf, lp); break; case OSPF_ACK_TIMEOUT: #if VERIFY_LS || 1 if(1 == lp->gid) printf("%lld: got Ack Timer \n", lp->gid); #endif ospf_ack_timed_out(nbr, bf, lp); state->stats->s_e_ack_timeouts++; break; case OSPF_HELLO_TIMEOUT: #if VERIFY_HELLO || 1 if(1 == lp->gid) printf("%lld: recv HELLO_TIMEOUT for nbr %d, ts %lf \n", lp->gid, nbr->id, tw_now(lp)); #endif state->stats->s_e_hello_timeouts++; ospf_nbr_event_handler(state, nbr, ospf_nbr_inactivity_timer_ev, lp); break; case OSPF_WEIGHT_CHANGE: #if VERIFY_OSPF_EXPERIMENT printf("%lld: recv WEIGHT CHANGE for link %ld, ts %lf \n", lp->gid, (long int) msg->data, tw_now(lp)); #endif ospf_experiment_weights(state, (long int) msg->data, lp); break; default: tw_error(TW_LOC, "%lld: Invalid packet type: %d at %f", lp->gid, msg->type, tw_now(lp)); } // Free the OSPF message header membuf tw_memory_free(lp, b, g_ospf_fd); if(lp->pe->cur_event->memory) tw_error(TW_LOC, "Left memory buffer on event!"); }