int main(void){ char c; int i=0, j=0, k=0; PQueue *min = pq_init(); char array[MAX_UNIQUE_CHARS]; char freq[MAX_UNIQUE_CHARS]; char path[MAX_LENGTH]; gets(array); gets(freq); gets(path); int r=0; while(array[r]!=NULL){ Tree *node= tree_init(freq[r]-'0', array[r]); pq_enqueue(min, node, freq[r]-'0'); r+=2; } while(min->size > 1){ Tree *left=pq_dequeue(min); Tree *right=pq_dequeue(min); Tree *node=tree_merge(left, right); pq_enqueue(min, node, node->root->freq); } List *l=init_list(9); Stack *s=init_stack(); l=recursive_Encoding(min->data[0]->root, s, l); read_path(min->data[0]->root, path); }
int test_enqueue_full(void) { int i; p_queue pq; pq_init(&pq); for (i = 0; i < N_ELEMS; i++) { if (pq_enqueue(&pq, i, LOWEST) == PQ_FAILURE) { return TEST_FAILURE; } } if (pq_enqueue(&pq, 10, HIGH) == PQ_SUCCESS) { return TEST_FAILURE; } for (i = 0; i < N_ELEMS; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } return TEST_SUCCESS; }
int test_move_interleave(void) { int i; p_queue pq; pq_init(&pq); for (i = 0; i < N_ELEMS; i += 2) { if (pq_enqueue(&pq, i, LOWEST) == PQ_FAILURE) { return TEST_FAILURE; } } for (i = 0; i < N_ELEMS; i += 2) { pq_move(&pq, i, LOWEST, HIGH); pq_enqueue(&pq, i + 1, HIGH); } for (i = 0; i < N_ELEMS; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } return TEST_SUCCESS; }
void echo_test(){ #ifdef USE_FREERTOS for( ;; ){ /* Wait to receive data for echo test */ if( xQueueReceive( echo_queue, &echo_data, portMAX_DELAY )){ /* * The data can be processed here and send back * Since it is simple echo test, the data is sent without * processing */ xQueueSend( OpenAMPInstPtr.send_queue, &echo_data, portMAX_DELAY ); } } #else /* check whether data is received for echo test */ if(pq_qlength(echo_queue) > 0){ echo_data = pq_dequeue(echo_queue); /* * The data can be processed here and send back * Since it is simple echo test, the data is sent without * processing */ pq_enqueue(OpenAMPInstPtr.send_queue, echo_data); } #endif }
/* * epi_agent_add_back: helper routine that adds an agent back to the * queue from which it was just removed * Must call num_add if appropriate, since we are skipping * the EPI_ADD event */ void epi_agent_add_back(epi_state * state, tw_lp * lp, tw_memory * buf) { tw_memory *b; epi_agent *a; epi_pathogen *p; a = tw_memory_data(buf); if(5 == a->id && 0) printf("%lld: added back %d at %lf \n", lp->gid, a->id && 0, tw_now(lp)); // Need to move curr but not change location. if(++a->curr >= a->nloc) a->curr = 0; a->ts_next = a->ts_remove = tw_now(lp) + a->dur[a->curr]; for(b = a->pathogens; b; b = b->next) { p = tw_memory_data(b); if (p->ts_stage_tran <= a->ts_remove) a->ts_next = p->ts_stage_tran; } pq_enqueue(g_epi_pq[lp->id], buf); //epi_num_add(state, (tw_bf *) NULL, a, lp); }
int test_full_flush_all(void) { int i; priority_t p; p_queue pq; pq_init(&pq); for (p = HIGH; p < N_PRIORITIES; p++) { for (i = 0; i < N_ELEMS; i++) { if (pq_enqueue(&pq, i, p) == PQ_FAILURE) { return TEST_FAILURE; } } for (i = 0; i < N_ELEMS; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } } for (p = LOWEST; p != HIGH - 1; p--) { for (i = 0; i < N_ELEMS; i++) { if (pq_enqueue(&pq, i, p) == PQ_FAILURE) { return TEST_FAILURE; } } for (i = 0; i < N_ELEMS; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } } return TEST_SUCCESS; }
static void xemacif_recv_handler(void *arg) { struct xemac_s *xemac = (struct xemac_s *)(arg); xemacliteif_s *xemacliteif = (xemacliteif_s *)(xemac->state); XEmacLite *instance = xemacliteif->instance; struct pbuf *p; int len = 0; struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index]; #if XLWIP_CONFIG_INCLUDE_EMACLITE_ON_ZYNQ == 1 #else XIntc_AckIntr(xtopologyp->intc_baseaddr, 1 << xtopologyp->intc_emac_intr); #endif p = pbuf_alloc(PBUF_RAW, XEL_MAX_FRAME_SIZE, PBUF_POOL); if (!p) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif /* receive and just ignore the frame. * we need to receive the frame because otherwise emaclite will * not generate any other interrupts since it cannot receive, * and we do not actively poll the emaclite */ XEmacLite_Recv(instance, xemac_tx_frame); return; } /* receive the packet */ len = XEmacLite_Recv(instance, p->payload); if (len == 0) { #if LINK_STATS lwip_stats.link.drop++; #endif pbuf_free(p); return; } /* store it in the receive queue, where it'll be processed by xemacif input thread */ if (pq_enqueue(xemacliteif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); return; } #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif }
int test_reverse(void) { int i; p_queue pq; pq_init(&pq); pq_enqueue(&pq, 0, LOWEST); pq_enqueue(&pq, 1, LOW); pq_enqueue(&pq, 2, MED); pq_enqueue(&pq, 3, HIGH); for (i = 3; i >= 0; i--) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } return TEST_SUCCESS; }
int test_basic(void) { int i; p_queue pq; pq_init(&pq); pq_enqueue(&pq, 0, HIGH); pq_enqueue(&pq, 1, MED); pq_enqueue(&pq, 2, LOW); pq_enqueue(&pq, 3, LOWEST); for (i = 0; i < 4; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } return TEST_SUCCESS; }
static void xllfifo_recv_handler(struct xemac_s *xemac) { u32_t frame_length; struct pbuf *p; xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state); XLlFifo *llfifo = &xaxiemacif->axififo; /* While there is data in the fifo ... */ while (XLlFifo_RxOccupancy(llfifo)) { /* find packet length */ frame_length = XLlFifo_RxGetLen(llfifo); /* allocate a pbuf */ p = pbuf_alloc(PBUF_RAW, frame_length, PBUF_POOL); if (!p) { char tmp_frame[XAE_MAX_FRAME_SIZE]; #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif /* receive and drop packet to keep data & len registers in sync */ XLlFifo_Read(llfifo, tmp_frame, frame_length); continue; } /* receive packet */ XLlFifo_Read(llfifo, p->payload, frame_length); #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* store it in the receive queue, where it'll be processed by xemacif input thread */ if (pq_enqueue(xaxiemacif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); continue; } #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif #if LINK_STATS lwip_stats.link.recv++; #endif } }
int test_cycle(void) { int i; int limit = N_ELEMS / 2; p_queue pq; pq_init(&pq); for (i = 0; i < N_ELEMS; i++) { if (pq_enqueue(&pq, i, HIGH) == PQ_FAILURE) { return TEST_FAILURE; } } for (i = 0; i < limit; i++) { if (pq_front(&pq) != i) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } for (i = N_ELEMS; i < N_ELEMS + limit; i++) { if (pq_enqueue(&pq, i, HIGH) == PQ_FAILURE) { return TEST_FAILURE; } } for (i = 0; i < N_ELEMS; i++) { if (pq_front(&pq) != i + limit) { return TEST_FAILURE; } if (pq_dequeue(&pq) != PQ_SUCCESS) { return TEST_FAILURE; } } return TEST_SUCCESS; }
/* * low_level_output(): * * Should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf * might be chained. * */ static err_t low_level_output(struct netif *netif, struct pbuf *p) { SYS_ARCH_DECL_PROTECT(lev); struct xemac_s *xemac = (struct xemac_s *)(netif->state); xemacliteif_s *xemacliteif = (xemacliteif_s *)(xemac->state); XEmacLite *instance = xemacliteif->instance; struct pbuf *q; SYS_ARCH_PROTECT(lev); /* check if space is available to send */ if (XEmacLite_TxBufferAvailable(instance) == TRUE) { if (pq_qlength(xemacliteif->send_q)) { /* send backlog */ _unbuffered_low_level_output(instance, (struct pbuf *)pq_dequeue(xemacliteif->send_q)); } else { /* send current */ _unbuffered_low_level_output(instance, p); SYS_ARCH_UNPROTECT(lev); return ERR_OK; } } /* if we cannot send the packet immediately, then make a copy of the whole packet * into a separate pbuf and store it in send_q. We cannot enqueue the pbuf as is * since parts of the pbuf may be modified inside lwIP. */ q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL); if (!q) { #if LINK_STATS lwip_stats.link.drop++; #endif SYS_ARCH_UNPROTECT(lev); return ERR_MEM; } for (q->len = 0; p; p = p->next) { memcpy(q->payload + q->len, p->payload, p->len); q->len += p->len; } if (pq_enqueue(xemacliteif->send_q, (void *)q) < 0) { #if LINK_STATS lwip_stats.link.drop++; #endif SYS_ARCH_UNPROTECT(lev); return ERR_MEM; } SYS_ARCH_UNPROTECT(lev); return ERR_OK; }
int test_move_all_bad(void) { p_queue pq; pq_init(&pq); if (pq_move( &pq, 10, HIGH, LOWEST ) == PQ_SUCCESS) { return TEST_FAILURE; } pq_enqueue(&pq, 10, HIGH); if (pq_move( &pq, 10, MED, LOWEST ) == PQ_SUCCESS) { return TEST_FAILURE; } if (pq_move( &pq, 4, HIGH, LOWEST ) == PQ_SUCCESS) { return TEST_FAILURE; } return TEST_SUCCESS; }
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len, void * priv, unsigned long src) { if ((*(int *) data) == SHUTDOWN_MSG) { remoteproc_resource_deinit(proc); #ifdef USE_FREERTOS int TempTimerId; stop_scheduler = xTimerCreate("TMR", DELAY_200MSEC, pdFALSE, (void *)&TempTimerId, StopSchedulerTmrCallBack); xTimerStart(stop_scheduler, 0); #endif }else{ recv_mat_data.data = data; recv_mat_data.length = len; #ifdef USE_FREERTOS xQueueSend(mat_mul_queue , &recv_mat_data, portMAX_DELAY ); #else pq_enqueue(mat_mul_queue, &recv_mat_data); #endif } }
/* * Adding an agent means placing them into our PQ. If agent * remove ts is < PQ->min, then must update LP remove timer. * * Check time for stage change. Place in queue by minimum * stage change time or remove time. Set timer for stage * change time (and event) or remove time (and event). */ void epi_agent_add(epi_state * state, tw_bf * bf, tw_memory * buf, tw_lp * lp) { epi_agent *a; a = tw_memory_data(buf); if(5 == a->id && 0) printf("%lld: added %d at %lf \n", lp->gid, a->id && 0, tw_now(lp)); // Test to make sure this location is this lp if (lp->gid != a->loc[a->curr]) tw_error(TW_LOC, "epi_agent_add adding agent to lp %d but loc[%d] is %d", lp->gid, a->curr, a->loc[a->curr]); // if agent is contagious, increment number of contagious agents here epi_agent_contagious(state, buf, +1); a->ts_remove = tw_now(lp) + a->dur[a->curr]; epi_agent_update_ts(state, bf, a, lp); pq_enqueue(g_epi_pq[lp->id], buf); if(pq_get_size(g_epi_pq[lp->id]) > state->max_queue_size) state->max_queue_size = pq_get_size(g_epi_pq[lp->id]); // If not at home, if agent is a worried well, if there are already enough symtomatic // people here then starting tomorrow, this agent will stay home for the number // of days remaining. days_remaining is checked in agent_remove(). if(!a->days_remaining && a->nloc > 1 && a->loc[a->curr] != a->loc[0] && (a->behavior_flags & EPI_AGENT_WORRIED_WELL)) { if ((float) state->ncontagious_tot / (float) state->max_queue_size > g_epi_ww_threshold) { a->days_remaining = g_epi_ww_duration; a->behavior_flags = 0; g_epi_hospital_ww[state->hospital][0]++; } } }
int test_move_priority_basic(void) { int i; p_queue pq; pq_init(&pq); pq_enqueue(&pq, 0, HIGH); if (pq_front(&pq) != 0) { return TEST_FAILURE; } if (pq_move( &pq, 0, HIGH, MED ) != PQ_SUCCESS) return TEST_FAILURE; if (pq_front(&pq) != 0) { return TEST_FAILURE; } if (pq_move( &pq, 0, MED, LOW ) != PQ_SUCCESS) return TEST_FAILURE; if (pq_front(&pq) != 0) { return TEST_FAILURE; } if (pq_move( &pq, 0, LOW, LOWEST ) != PQ_SUCCESS) return TEST_FAILURE; if (pq_front(&pq) != 0) { return TEST_FAILURE; } return TEST_SUCCESS; }
void matrix_mul(){ #ifdef USE_FREERTOS for( ;; ){ if( xQueueReceive(mat_mul_queue, &mat_array, portMAX_DELAY )){ env_memcpy(matrix_array, mat_array.data, mat_array.length); Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result); mat_result_array.length = sizeof(matrix); mat_result_array.data = &matrix_result; xQueueSend( OpenAMPInstPtr.send_queue, &mat_result_array, portMAX_DELAY ); } } #else if(pq_qlength(mat_mul_queue) > 0){ mat_array = pq_dequeue(mat_mul_queue); env_memcpy(matrix_array, mat_array->data, mat_array->length); /* Process received data and multiple matrices. */ Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result); mat_result_array.length = sizeof(matrix); mat_result_array.data = &matrix_result; pq_enqueue(OpenAMPInstPtr.send_queue, &mat_result_array); } #endif }
/* * When the LPs REMOVE timer fires, we should dequeue the next agent * and send it on to it's next location. We must set the next remove * timer appropriately for the agents remaining in our PQ. * * If the remove is from location 0, then this is the first move of the * day, i.e., from home. We activate agent logic to see if agent * will stay home today, due to quarantine, being ill, or having * ill spouse or children to care for. * * NOTE: We want the agent in the event to be consistent with the * agent in the timer, even if they have the same remove timestamp. * The reason for this is that in the reverse computation, I need to put * the agent back into the PQ, and where else can I get it from but the * timer event? * */ void epi_agent_remove(epi_state * state, tw_bf * bf, tw_lp * lp) { tw_memory *buf; epi_agent *a; while(NULL != (buf = pq_dequeue(g_epi_pq[lp->id]))) { a = tw_memory_data(buf); if(a->ts_next != tw_now(lp)) { pq_enqueue(g_epi_pq[lp->id], buf); break; } if(epi_agent_stage_tran(state, bf, buf, lp)) continue; // if days_remaining > 0, then go through motions by moving curr, but // do not move agent. Thus, a->loc[a->curr] may not be home. Need // to do this in order to send network traffic. // only change days_remaining at midnight, so when days_remaining goes // to zero, curr will go to zero and agent will be at home. // Make sure agent is at home. If agent becomes worried well at // work, must continue to move until he is at home. if(a->days_remaining && lp->gid == a->loc[0]) { if ((int) tw_now(lp) % TWENTY_FOUR_HOURS == 0) { if(--a->days_remaining) { epi_agent_add_back(state, lp, buf); continue; } } else { epi_agent_add_back(state, lp, buf); continue; } } if(5 == a->id || 1) printf("%lld: REM %d at %lf \n", lp->gid, a->id, tw_now(lp)); //epi_num_remove(state, bf, a, lp); // if agent is contagious, decrement number of // contagious agents in this location epi_agent_contagious(state, buf, -1); if (state->ncontagious < 0) tw_error(TW_LOC, "Less than zero contagious agents in %lld", lp->gid); // increment location if(++a->curr >= a->nloc) a->curr = 0; epi_agent_send(lp, buf, 0.0, a->loc[a->curr]); } }
/* find the lowest cost path and mark it on the map */ void make_path(struct map *map, int x0, int y0, int x1, int y1) { int start, end, cost, i, index, mdistance; pq_t * pq; int edges[4]; pq = pq_create(); cost = 0; start = y0 * map->width + x0; end = y1 * map->width + x1; map->grid[start].flags |= SQ_FLAG_START; map->grid[end].flags |= SQ_FLAG_GOAL; map->grid[start].glyph = 'A'; map->grid[end].glyph = 'B'; if(map->grid[start].cost == -1 || map->grid[end].cost == -1) { map->cost = -1; return; } curses_draw_map(map); mdistance = man_distance(start, end, map); if(!pq_enqueue(pq, start, map->grid[start].cost + mdistance)) exit(EXIT_FAILURE); while(1) { if(!pq_dequeue(pq, &index, &cost)) exit(EXIT_FAILURE); if(map->grid[index].parent) /* * Kill two birds with one stone (Visited == enqueued in this case) */ map->grid[index].flags |= SQ_FLAG_VISITED; map->grid[index].flags &= ~SQ_FLAG_ENQUEUED; if(index == end) break; get_edges(index, edges, map); curses_draw_map(map); for(i = 0; i < 4; i++) { if(edges[i] != -1) { map->grid[edges[i]].parent = index; mdistance = man_distance(edges[i], end, map); if(!pq_enqueue(pq, edges[i], (cost) + map->grid[edges[i]].cost)) exit(EXIT_FAILURE); map->grid[edges[i]].flags |= SQ_FLAG_ENQUEUED; map->grid[edges[i]].flags |= SQ_FLAG_VISITED; } } } /* * This next section will fill the path array in the map struct by iterating * through the path found in the above code, which is done by following each * node's parent. * It will begin with setting the total cost of the path to the cost of the * end node, then working backwards towards the start node which has a zero cost * (which is actually appended to the total cost). * It will then begin iteration, setting the glyph and flags, then setting the * start and end node's glyphs, as these will be set with 'o' during the loop. * If the start and the end have the same coordinates, there will be a zero cost * because the only node which is appended to the total is the end, which is * the start, which has a zero cost. */ i = end; /* * Instantiate the path array */ map->path = safe_malloc(map->width * map->height * sizeof(int)); map->path_index = 0; map->cost = -1; /* * Dont include the start node's cost in the calculation */ map->grid[start].cost = 0; /* * Make sure the start node's parent is 0; * */ map->grid[start].parent = 0; map->cost = map->grid[i].cost; while(map->grid[i].parent) { /* This will miss the start node, therefore we will append it after the loop */ map->grid[i].flags |= SQ_FLAG_PATH; map->grid[i].glyph = 'o'; map->path[map->path_index++] = i; i = map->grid[i].parent; map->cost += map->grid[i].cost; } map->path[map->path_index++] = i; map->grid[start].glyph = 'A'; map->grid[end].glyph = 'B'; curses_draw_map(map); pq_destroy(pq); }
/* * epi_init - initialize node LPs state variables * * state - our node LP state space * lp - our node LP */ void epi_init(epi_state * state, tw_lp * lp) { tw_memory *b; tw_memory *agent = NULL; tw_stime ts_min_tran = DBL_MAX; epi_agent *a; epi_pathogen *p; epi_ic_stage *s; double x; int i; int j; int sz; // hard-coded, single hospital LP if(lp->id == g_tw_nlp-1) { fprintf(g_epi_hospital_f, "0 0 %u %u %u\n", g_epi_hospital[0][0], g_epi_hospital_ww[0][0], g_epi_hospital_wws[0][0]); g_epi_hospital[0][0] = 0; g_epi_hospital_ww[0][0] = 0; g_epi_hospital_wws[0][0] = 0; return; } // ID of the hospital I go to (or nearest if office/school) state->hospital = 0; state->stats = tw_calloc(TW_LOC, "", sizeof(epi_statistics), 1); state->ncontagious = tw_calloc(TW_LOC, "", sizeof(unsigned int), g_epi_ndiseases); state->ts_seir = tw_calloc(TW_LOC, "", sizeof(tw_stime), g_epi_ndiseases); for(i = 0; i < g_epi_ndiseases; i++) state->ts_seir[i] = DBL_MAX; // if no agents initially at this location, then we are done! if(0 == (sz = pq_get_size(g_epi_pq[lp->id]))) return; // determine agents initial parameters / configuration for(i = 0; i < sz; i++) { agent = pq_next(g_epi_pq[lp->id], i); a = tw_memory_data(agent); for(j = 0; j < g_epi_ndiseases; j++) { if(!a->id && !j) { // ALLOCATE PATHOGEN AND FILL IT IN b = tw_memory_alloc(lp, g_epi_pathogen_fd); p = tw_memory_data(b); b->next = a->pathogens; a->pathogens = b; p->index = j; p->stage = EPI_SUSCEPTIBLE; p->ts_stage_tran = DBL_MAX; g_epi_regions[a->region][p->index][p->stage]--; p->stage = EPI_EXPOSED; g_epi_regions[a->region][p->index][p->stage]++; g_epi_exposed_today[j]++; // determine if agents start out sick. if(tw_rand_unif(lp->rng) < g_epi_sick_rate) { s = &g_epi_diseases[p->index].stages[p->stage]; x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / (double) INT_MAX); p->ts_stage_tran = (s->min_duration + (x * (s->max_duration - s->min_duration))); if(0.0 >= p->ts_stage_tran) tw_error(TW_LOC, "Immediate stage transition?!"); //state->stats->s_ninfected++; state->ncontagious[p->index]++; state->ncontagious_tot++; //g_epi_hospital[0][0]++; g_epi_sick_init_pop[j]++; ts_min_tran = min(ts_min_tran, p->ts_stage_tran); if(!a->id) printf("%ld: agent exposed %d: %s, transition at %lf\n", lp->id, a->id, g_epi_diseases[j].name, p->ts_stage_tran); } } } // reflect ts_next change in PQ ordering if(ts_min_tran < a->ts_next) { a->ts_next = ts_min_tran; pq_delete_any(g_epi_pq[lp->id], &agent); pq_enqueue(g_epi_pq[lp->id], agent); } // determine if agents are a part of worried well population. if(g_epi_ww_rate) { if(tw_rand_unif(lp->rng) < g_epi_ww_rate) { a->behavior_flags = 1; g_epi_hospital_ww[0][0]++; g_epi_ww_init_pop++; } } else if(g_epi_wws_rate) { if(tw_rand_unif(lp->rng) < g_epi_wws_rate) { a->behavior_flags = 2; g_epi_hospital_wws[0][0]++; g_epi_wws_init_pop++; } } // define agent's at work contact population //g_epi_regions[a->region][a->stage]++; } epi_location_timer(state, lp); }
void epi_init_agent_default(void) { tw_memory *b; epi_agent *a; int i; int j; int id; int lid; int rid; if(!g_epi_nagents) tw_error(TW_LOC, "No agents specified!"); if(!g_tw_nlp) tw_error(TW_LOC, "No locations specified!"); if(!g_epi_nregions) tw_error(TW_LOC, "No regions specified!"); g_epi_regions = tw_calloc(TW_LOC, "", sizeof(unsigned int *), g_epi_nregions); // create reporting tables for each region, for each disease for(i = 0; i < g_epi_nregions; i++) { g_epi_regions[i] = tw_calloc(TW_LOC, "", sizeof(*g_epi_regions[i]), g_epi_ndiseases); for(j = 0; j < g_epi_ndiseases; j++) g_epi_regions[i][j] = tw_calloc(TW_LOC, "", sizeof(*g_epi_regions[i][j]), g_epi_diseases[j].nstages); } // allocate the location priority queues for this node g_epi_pq = tw_calloc(TW_LOC, "", sizeof(*g_epi_pq), g_tw_nlp); for(i = 0; i < g_tw_nlp; i++) g_epi_pq[i] = pq_create(); // round-robin mapping of agents to locations, and locations to regions for(i = 0; i < g_epi_nagents; i++) { lid = i % g_tw_nlp; rid = lid % g_epi_nregions; b = tw_memory_alloc(g_tw_lp[lid], g_epi_fd); a = tw_memory_data(b); a->id = id++; a->region = rid; a->pathogens = NULL; a->curr = 0; a->nloc = tw_rand_integer(g_tw_lp[lid]->rng, 0, 10); // setup "home" location a->loc[0] = lid; a->dur[0] = tw_rand_exponential(g_tw_lp[lid]->rng, g_epi_mean); a->ts_next = a->ts_remove = a->dur[0]; pq_enqueue(g_epi_pq[a->loc[0]], b); printf("A %d nloc %d: (%d, %lf) ", a->id, a->nloc, a->loc[0], a->dur[0]); for(j = 1; j < a->nloc; j++) { a->loc[j] = tw_rand_integer(g_tw_lp[lid]->rng, 0, (g_tw_nlp * tw_nnodes()) - 2); a->dur[j] = tw_rand_exponential(g_tw_lp[lid]->rng, g_epi_mean); printf("(%d %lf) ", a->loc[j], a->dur[j]); } printf("\n"); ga = a; } }
void epi_init_agent(void) { FILE *g; FILE *f; fpos_t pos; tw_memory *b; tw_memory *next; epi_agent *a; int *home_to_ct; int nagents = 0; int nlp = -1; int i; int j; int h; int o; int t; printf("\nEPI Agent Initialization: \n\n"); home_to_ct = tw_calloc(TW_LOC, "home to ct", sizeof(*home_to_ct), 3363607); // create census tract table, hard-coded to 2214 (all CT) for Chicago g_epi_nregions = 2215; g_epi_regions = tw_calloc(TW_LOC, "", sizeof(unsigned int *), g_epi_nregions); // need to read in homes.dat to get CT ids if(NULL == (g = fopen("homes.dat", "r"))) tw_error(TW_LOC, "Unable to open: homes.dat"); i = 0; while(EOF != (fscanf(g, "%d", &home_to_ct[i++]))) ; for(i = 0; i < g_epi_nregions; i++) { g_epi_regions[i] = tw_calloc(TW_LOC, "", sizeof(unsigned int *), g_epi_ndiseases); for(j = 0; j < g_epi_ndiseases; j++) g_epi_regions[i][j] = tw_calloc(TW_LOC, "", sizeof(unsigned int), g_epi_diseases[j].nstages); } if(NULL == (f = fopen("agents.dat", "r"))) tw_error(TW_LOC, "Unable to open: agents.dat"); i = 0; if(!g_epi_nagents) { fgetpos(f, &pos); while(EOF != fscanf(f, "%d %d %*d", &h, &o)) g_epi_nagents++; fsetpos(f, &pos); } if(0 == g_epi_nagents) tw_error(TW_LOC, "No agents in agents.dat!"); g_epi_agents = tw_calloc(TW_LOC, "", sizeof(tw_memoryq), 1); g_epi_agents->start_size = g_epi_nagents; g_epi_agents->d_size = sizeof(epi_agent); g_epi_agents->grow = 1; tw_memory_allocate(g_epi_agents); b = g_epi_agents->head; while(EOF != (fscanf(f, "%d %d %d", &h, &o, &t))) { // allocate the agent a = tw_memory_data(b); a->id = nagents++; if(h && h > nlp) nlp = h; if(o != -1 && o > nlp) nlp = o; // the CT id is stored on the h-th line of the homes.dat file a->region = home_to_ct[h]; if(a->region > 2214) tw_error(TW_LOC, "Bad Home to CT Mapping!"); a->pathogens = NULL; #if 0 // default disease stats a->stage = EPI_SUSCEPTIBLE; a->ts_stage_tran = DBL_MAX; #endif a->curr = 0; //a->ts_last_tran = 0.0; // go to work at 9am on first day a->ts_next = a->ts_remove = (double) 32400.0; //a->n_infected = 0; if(-1 != o) a->nloc = 3; else a->nloc = 2; // only two locs =( a->loc[1] = o; a->loc[0] = a->loc[a->nloc-1] = h; a->dur[0] = 9 * 3600; a->dur[1] = 8 * 3600; a->dur[a->nloc-1] += 7 * 3600; a->behavior_flags = 0; a->ts_remove = a->ts_next = a->dur[a->curr]; for(i = 0; i < g_epi_ndiseases; i++) g_epi_regions[a->region][i][0]++; if(g_epi_nagents == nagents) break; b = b->next; } if(nlp == 0) tw_error(TW_LOC, "No locations!"); else printf("\t%-48s %11d\n", "Max Location", ++nlp); g_epi_pq = tw_calloc(TW_LOC, "", sizeof(void *), nlp); for(i = 0; i < nlp; i++) g_epi_pq[i] = pq_create(); for(b = g_epi_agents->head; b; b = next) { a = tw_memory_data(b); next = b->next; pq_enqueue(g_epi_pq[a->loc[0]], b); } g_tw_nlp = nlp; }
void emacps_recv_handler(void *arg) { struct pbuf *p; XEmacPs_Bd *rxbdset, *curbdptr; struct xemac_s *xemac; xemacpsif_s *xemacpsif; XEmacPs_BdRing *rxring; volatile s32_t bd_processed; s32_t rx_bytes, k; u32_t bdindex; u32_t regval; xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps); #ifdef OS_IS_FREERTOS xInsideISR++; #endif /* * If Reception done interrupt is asserted, call RX call back function * to handle the processed BDs and then raise the according flag. */ regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET); XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval); resetrx_on_no_rxdata(xemacpsif); while(1) { bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset); if (bd_processed <= 0) { break; } for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) { bdindex = XEMACPS_BD_TO_INDEX(rxring, curbdptr); p = (struct pbuf *)rx_pbufs_storage[bdindex]; /* * Adjust the buffer size to the actual number of bytes received. */ rx_bytes = XEmacPs_BdGetLength(curbdptr); pbuf_realloc(p, rx_bytes); /* store it in the receive queue, * where it'll be processed by a different handler */ if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); } else { #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif } curbdptr = XEmacPs_BdRingNext( rxring, curbdptr); } /* free up the BD's */ XEmacPs_BdRingFree(rxring, bd_processed, rxbdset); setup_rx_bds(rxring); } #ifdef OS_IS_FREERTOS xInsideISR--; #endif return; }
/* * Stage transition causes the agent to be removed from the * queue (it is at the head), increment the stage, collect * statistics, and place back in the queue with the minimum * of the next stage transition time and the remove time. */ void agent_stage_tran(epi_state * state, tw_bf * bf, tw_memory * buf, epi_pathogen * p, tw_lp * lp) { epi_ic_stage *s; epi_agent *a; a = tw_memory_data(buf); s = &g_epi_diseases[p->index].stages[p->stage]; if(5 == a->id || 1) printf("%lld: transition %d at %lf \n", lp->gid, a->id && 0, tw_now(lp)); // if this agent is contagious in the old stage, then reduce the location number of // contagious agents by one. if(s->ln_multiplier != 0.0) { state->ncontagious[p->index]--; state->ncontagious_tot--; if(a->behavior_flags == EPI_AGENT_WORRIED_WELL) a->behavior_flags = 0; } if(state->ncontagious[p->index] < 0) tw_error(TW_LOC, "Less than zero ncontagious!"); g_epi_regions[a->region][p->index][p->stage]--; p->stage++; g_epi_regions[a->region][p->index][p->stage]++; if(p->stage >= g_epi_diseases[p->index].nstages) tw_error(TW_LOC, "Invalid stage: %d", p->stage); s = &g_epi_diseases[p->index].stages[p->stage]; p->ts_stage_tran = tw_now(lp); if(fabs(s->max_duration - s->min_duration) < EPSILON) p->ts_stage_tran += s->min_duration; else p->ts_stage_tran += s->min_duration + tw_rand_unif(lp->rng) * (s->max_duration - s->min_duration); if(p->ts_stage_tran > tw_now(lp) + s->max_duration) tw_error(TW_LOC, "Too long!"); if(p->ts_stage_tran < tw_now(lp)) tw_error(TW_LOC, "Backwards stage tran!"); if(p->ts_stage_tran < s->min_duration) tw_error(TW_LOC, "Too short!"); // Perform mortality check if (s->mortality_rate > 0 && tw_rand_unif(lp->rng) < s->mortality_rate ) { a->behavior_flags = EPI_AGENT_DEAD; a->days_remaining = 0; g_epi_regions[a->region][p->index][p->stage]--; p->stage = g_epi_diseases[p->index].nstages; g_epi_regions[a->region][p->index][p->stage]++; // collect statistics state->stats->s_ndead++; } else { // if new stage has infectivity, // then increment number of contagious agents in location. if(s->ln_multiplier != 0.0) { state->ncontagious[p->index]++; state->ncontagious_tot++; state->stats->s_ninfected++; // then must set number of days to stay home if(!(a->behavior_flags & EPI_AGENT_WORK_WHILE_SICK)) { a->days_remaining = ((int) (p->ts_stage_tran - tw_now(lp)) / TWENTY_FOUR_HOURS); if (a->days_remaining < 1) a->days_remaining = 1; g_epi_hospital[state->hospital][0]++; } } epi_agent_update_ts(state, bf, a, lp); // re-enqueue with new ts_next pq_enqueue(g_epi_pq[lp->id], buf); } }
// NON-standard version of Dijkstra's: // Print out the shortest paths from the source node to each other node void dijkstras(graph_t *g, int source) { int i; int u, v; double weight; // generous vars for edge (u->v,weight) double new_weight; // To store current min-costs and previous vertices int *prev; // prev[v]=u if v was reached from u double *dist; // dist[v]= current best dist from source to v assert(prev= malloc( g->n * sizeof(*prev) ) ); assert(dist= malloc( g->n * sizeof(*dist) ) ); /* Initialization ------------------------------ */ for (i = 0; i < g->n; i++) { prev[i] = NO_PREV; dist[i] = INFINITY; } dist[source] = 0; // enqueue "source" - the only one that has limitted dist pq_t *queue = new_pq(); pq_enqueue(queue, source, dist[source]); /* Main loop of Dijkstra's ------------------------------ */ // buddy array of n elements to store the adjacency list of a vertex data_t *neighbours; int n; assert(neighbours= malloc( g->n * sizeof(*neighbours) ) ); while (!pq_is_empty(queue)) { // remove min vertex u = pq_remove_min(queue); // With this vertex u: // * first, copies the adjacency list of u to array neighbours n= list_2_array(g->vs[u].A, neighbours); // * then, inspects each of the neighbour for (i = 0; i < n; i++) { v = neighbours[i].id; // looking at edge (u-->v,weight) weight = neighbours[i].weight; new_weight = dist[u] + weight; // if v was reached before with a better outcome // then we just ignore the edge u-->v if ( dist[v] <= new_weight) continue; // updates vertex v in the queue if (dist[v] == INFINITY) { // if v never been reached before, adds it to queue pq_enqueue(queue, v, new_weight); } else { // otherwise, updates weight of v in the queue // note that the update must be successful if ( !pq_update(queue, v, new_weight) ){ fprintf(stderr, "Internal error: Something wrong " "in code or in data (such as negative weight)\n"); exit(EXIT_FAILURE); } } // now updaes dist[v] and prev[v] dist[v] = new_weight; prev[v] = u; } } /* Prints out all shortest paths ------------------------------ */ print_all_path(dist, prev, g, source); // free the dynamic data structures free(dist); free(prev); free(neighbours); free_pq(queue); }
// The "standard" version of Dijkstra's, // ie the one that is the same as shown in the lecture // see page 16 of lec08.pdf // Comments starting with //* are the lines from pseudocode in page 16 // Print out the shortest paths from the source node to each other node void dijkstras(graph_t *g, int v0) { int v; int u, w; double weight; // generous vars for edge (u->w,weight) // To store current min-costs and previous vertices int *prev; // prev[v]=u if v was reached from u double *dist; // dist[v]= current best dist from source to v bool *inQ; // a helping array for quick check if v in Q assert(prev= malloc( g->n * sizeof(*prev) ) ); assert(dist= malloc( g->n * sizeof(*dist) ) ); assert(inQ= malloc( g->n * sizeof(*inQ) ) ); /* Initialization ------------------------------ */ for (v = 0; v < g->n; v++) { //* foreach v in V prev[v] = NO_PREV; //* prev[v]= nil dist[v] = INFINITY; //* dist[v]= infinity } dist[v0] = 0; //* dist[v0]=0 //* Q = InitPriorityQueue(V) pq_t *Q = new_pq(); for (v = 0; v < g->n; v++) { pq_enqueue(Q, v, dist[v]); inQ[v]= true; // marks v as being inside the queue } /* Main loop of Dijkstra's ------------------------------ */ // buddy array of n elements to store the adjacency list of a vertex data_t *neighbours; int n; assert(neighbours= malloc( g->n * sizeof(*neighbours) ) ); while (!pq_is_empty(Q)) { //* while Q is non empty do // remove min vertex u = pq_remove_min(Q); //* u= EjectMin(Q) inQ[u]= false; // marks u as not in Q anymore // With this vertex u: // first, copies the adjacency list of u to array neighbours n= list_2_array(g->vs[u].A, neighbours); for (v = 0; v < n; v++) { //* for each (u,w) in E do w = neighbours[v].id; // having:edge (u-->w,weight) weight= neighbours[v].weight; //* if (w in Q && dist[v]+weight(u,w) <dist[v] if ( inQ[w] && dist[w] > dist[u]+weight) { dist[w] = dist[u]+weight; //* dist[w]= dist[u]+weight(u,v) prev[w] = u; //* prev[w]= u //* Update(Q, w, dist[w]) pq_update(Q, w, dist[w]); } } } /* Prints out all shortest paths ------------------------------ */ print_all_path(dist, prev, g, v0); // free the dynamic data structures free(dist); free(prev); free(neighbours); free_pq(Q); }
void epi_xml(epi_state * state, tw_lp * lp) { xmlNodePtr agent; xmlNodePtr move; rn_machine *m = rn_getmachine(lp->id); epi_agent *a; epi_ic_stage *s; double x; int ct; int i; char *sick; // create census tract table if it does not exist // need 1 more than number of stages to save dead agents // dead is not a stage. if (!g_epi_ct) { g_epi_nct = 2200; //rn_getarea(m)->nsubnets; g_epi_ct = tw_vector_create(sizeof(unsigned int *), g_epi_nct); for (i = 0; i < g_epi_nct; i++) g_epi_ct[i] = tw_vector_create(sizeof(unsigned int), g_epi_nstages); } state->stats = tw_vector_create(sizeof(epi_statistics), 1); state->pq = pq_create(); ct = rn_getsubnet(m)->id - rn_getarea(m)->subnets[0].id; // spin through agents 'homed' at this location and allocate + init them // // NOTE: May not have *any* agents homed at a given location for(agent = node->children; agent; agent = agent->next) { if(0 != strcmp((char *) agent->name, "agent")) continue; a = tw_vector_create(sizeof(epi_agent), 1); a->ct = m->uid; //ct; a->num = tw_getlp(atoi(xml_getprop(agent, "num"))); //a->a_type = atoi(xml_getprop(agent,"type")); sick = xml_getprop(agent, "sick"); if(g_epi_psick > EPSILON) { if ( tw_rand_unif(lp->rng) < g_epi_psick ) sick = "1"; } if(0 != strcmp(sick, "0")) { //a->ts_infected = atof(sick); a->stage = EPI_INCUBATING; s = &g_epi_stages[a->stage]; x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / (double) INT_MAX); a->ts_stage_tran = (s->min_duration + (x * (s->max_duration - s->min_duration))); #if EPI_XML_VERIFY printf("\tstage: %d, time %5f \n", s->stage_index, a->ts_stage_tran); #endif g_epi_nsick++; } else { a->stage = EPI_SUSCEPTIBLE; a->ts_stage_tran = DBL_MAX; //a->ts_infected = DBL_MAX; } g_epi_ct[a->ct][a->stage]++; //a->id = g_epi_nagents++; g_epi_nagents++; a->curr = 0; //a->ts_last_tran = 0.0; a->ts_next = a->ts_remove = (double) 86400.0; //a->n_infected = 0; for(move = agent->children; move; move = move->next) { if(0 != strcmp((char *) move->name, "move")) continue; a->nloc++; } if(!a->nloc) tw_error(TW_LOC, "Agent has no locations!"); a->nloc++; // add a location to return home at end of day a->loc = tw_vector_create(sizeof(int) * a->nloc, 1); a->dur = tw_vector_create(sizeof(tw_stime) * a->nloc, 1); int seconds_used = 0; // totals duration to check for 24 hours for(i = 0, move = agent->children; move; move = move->next) { if(0 != strcmp((char *) move->name, "move")) continue; a->loc[i] = atoi(xml_getprop(move, "loc")); a->dur[i] = atoi(xml_getprop(move, "dur")) * 3600; seconds_used += a->dur[i]; i++; } if (seconds_used > 86400) tw_error(TW_LOC, "Agent has duration more than 24 hours\n"); else if (seconds_used == 86400) a->nloc--; // do not need last location else { a->loc[a->nloc-1] = a->loc[0]; // return home a->dur[a->nloc-1] = 86400 - seconds_used; } a->behavior_flags = 0; if (g_epi_worried_well_rate > 0) { if (tw_rand_unif(lp->rng) < g_epi_worried_well_rate) a->behavior_flags = 1; } else if (g_epi_work_while_sick_p > EPSILON) if (tw_rand_unif(lp->rng) < g_epi_work_while_sick_p) a->behavior_flags = 2; // Set ts_next and enqueue a->ts_remove = a->dur[a->curr]; if(a->ts_remove < a->ts_stage_tran) a->ts_next = a->ts_remove; else a->ts_next = a->ts_stage_tran; pq_enqueue(state->pq, a); } }
void emacps_recv_handler(void *arg) { struct pbuf *p; unsigned irq_status, i; XEmacPs_Bd *rxbdset, *CurBdPtr; struct xemac_s *xemac; xemacpsif_s *xemacpsif; XEmacPs_BdRing *rxring; volatile int bd_processed; int rx_bytes, k; unsigned int BdIndex; xemac = (struct xemac_s *)(arg); xemacpsif = (xemacpsif_s *)(xemac->state); rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps); #ifdef OS_IS_FREERTOS xInsideISR++; #endif /* * If Reception done interrupt is asserted, call RX call back function * to handle the processed BDs and then raise the according flag. */ while(1) { bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset); if (bd_processed <= 0) { #ifdef OS_IS_FREERTOS xInsideISR--; #endif return; } for (k = 0, CurBdPtr=rxbdset; k < bd_processed; k++) { BdIndex = XEMACPS_BD_TO_INDEX(rxring, CurBdPtr); p = (struct pbuf *)rx_pbufs_storage[BdIndex]; /* * Adjust the buffer size to the actual number of bytes received. */ rx_bytes = XEmacPs_BdGetLength(CurBdPtr); pbuf_realloc(p, rx_bytes); Xil_DCacheInvalidateRange((unsigned int)p->payload, (unsigned)XEMACPS_MAX_FRAME_SIZE); /* store it in the receive queue, * where it'll be processed by a different handler */ if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) { #if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++; #endif pbuf_free(p); } else { #if !NO_SYS sys_sem_signal(&xemac->sem_rx_data_available); #endif } CurBdPtr = XEmacPs_BdRingNext( rxring, CurBdPtr); } /* free up the BD's */ XEmacPs_BdRingFree(rxring, bd_processed, rxbdset); _setup_rx_bds(rxring); } return; }