Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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
}
Exemple #5
0
	/*
	 * 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);
}
Exemple #6
0
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;
}
Exemple #7
0
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

}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
0
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
	}
}
Exemple #11
0
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;
}
Exemple #12
0
/*
 * 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;
}
Exemple #13
0
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
	}
}
Exemple #15
0
	/*
	 * 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]++;
		}
	}
}
Exemple #16
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
}
Exemple #18
0
	/*
	 * 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]);
	}
}
Exemple #19
0
/* 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);
    
	
}	
Exemple #20
0
/*
 * 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);
}
Exemple #21
0
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;
    }
}
Exemple #22
0
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;
}
Exemple #24
0
/*
 * 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);
	}
}
Exemple #25
0
// 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);	
}
Exemple #26
0
// 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);	
}
Exemple #27
0
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;
}