Пример #1
0
void ptimer_consume_time(ptimer_table_t *table, u32 time)
{
	ptimer_t *timer;
	u32 i;
	
	if(table == NULL) return;
	
	for(i=0; i<time; i++)
	{
		while(!DLLIST_EMPTY(&table->table[table->curslot]))
		{
			timer = (ptimer_t *)DLLIST_HEAD(&table->table[table->curslot]);

			assert(ptimer_is_running(timer));
			
			/* remove all timers in current slot */
			dllist_remove(NULL, (dllist_node_t *)timer);
			
			/* handle remainder */
			if(timer->remainder)
			{
				ptimer_start_remainder(table, timer, timer->remainder);
				continue;
			}
			
			/* mark timer as not running */
			timer->flags &= ~PTIMER_FLAG_RUNNING;
			
			/* call onexpired_func */
//			ZLOG_DEBUG("timer expired: 0x%p at slot %u\n", timer, table->curslot);
			if(timer->onexpired_func)
			{
				timer->onexpired_func(timer, timer->param[0], timer->param[1]);
			}
			
			/* if periodic timer */
			if((timer->flags & PTIMER_FLAG_PERIODIC) && !(timer->flags & PTIMER_FLAG_RUNNING))
				ptimer_start(table, timer, timer->duration);
		}
		
		table->curslot = (table->curslot + 1) & (table->allslots - 1);
	}
}
Пример #2
0
void output_rx_throughput(packet_t *pktt)
{
	static dllist_node_t rx_tpt_list = {
		.prev = &rx_tpt_list,
		.next = &rx_tpt_list
	};

	if (pktt && pktt->ptt != RX_OK) return;
	

	if (pktt == NULL) {
		/* output the result */
		while (!DLLIST_EMPTY(&rx_tpt_list)) {
			rx_throughput_t *ttt = (rx_throughput_t*) DLLIST_HEAD(&rx_tpt_list);
			ZLOG_INFO("rx tpt: at [%d, %d)s, throughput %d bps\n", ttt->time, ttt->time + 1, ttt->throughput /* bps */);
			dllist_remove(&rx_tpt_list, &(ttt->node));
			free(ttt);
		}
		return;
	}

	/* pktt != NULL, calcuate the rx *delivery* throughput */
	u32 remainder = pktt->rx_deliver_timestamp % (u32) MS2US(S2MS(1));
	u32 integer = (pktt->rx_deliver_timestamp - remainder) / MS2US(S2MS(1));
	rx_throughput_t * ttt = (rx_throughput_t*) DLLIST_TAIL(&rx_tpt_list);

	if (DLLIST_IS_HEAD(&rx_tpt_list, ttt) || ttt->time != integer) {
		/* new one */
		rx_throughput_t *new_ttt = (rx_throughput_t*) malloc(sizeof(rx_throughput_t));
		assert(new_ttt);
		new_ttt->time = integer;
		new_ttt->throughput = pktt->packet_size;
		dllist_append(&rx_tpt_list, &(new_ttt->node));
	} else {
		/* already existed, update it */
		ttt->throughput += (pktt->packet_size * OCTET);
	}
}
Пример #3
0
int main (int argc, char *argv[])
{
	/*
	  1. acquire all simulation parameters or use the default values
	  2. generate the simulation begin event @time = 0
	  3. add this event to the timer queue
	  4. while (simulatio not finished) {
	        advance the simu time by 1 time unit (ms)
	     }
	 */
	/* 1. */
	simu_paras_t spt;
	spt.t.packet_size = PKT_SIZE; /* bytes */
	spt.rl.link_distance = 0;
	spt.rl.prop_delay = MS2US(270);	   /* 270 ms */
	spt.rl.link_bandwidth = BANDWIDTH; /* bps */
	spt.rl.per = PER;					/* x/10000 */

	/* this should be set when the mac pdu is build (at the tx_begin_event) */
	/*
	spt.tx_delay = ( (1e3 * OCTET *
						   (spt.t.packet_size +
							MAC_HEADER_SIZE +
							PHY_HEADER_SIZE))
						  / spt.rl.link_bandwidth );
	*/					 

						  
	/* rlc params */
	spt.rlc_paras.ump.t_Reordering = MS2US(T_REORDERING); /* ms */
	spt.rlc_paras.ump.UM_Window_Size = UWSize;	   /* window size */
	spt.rlc_paras.ump.sn_FieldLength = SN_LEN;	   /* sn length */

#define PTIMER_MEM_MAX 4096*16
	spt.g_mem_ptimer_t = fastalloc_create(sizeof(ptimer_t), PTIMER_MEM_MAX, 0, 100);
	assert(spt.g_mem_ptimer_t);

/* #define PACKET_MEM_MAX (4096*16*16*8) */
/* 	spt.g_mem_packet_t = fastalloc_create(sizeof(packet_t), PACKET_MEM_MAX, 0, 100); */
/* 	assert(spt.g_mem_packet_t); */
	
	/* @transmitter */
	/* @receiver */
	/* leave these to be done at the simulatioin begin event */

	/* init log */
	zlog_default = openzlog(ZLOG_STDOUT);
	zlog_set_pri(zlog_default, LOG_INFO);
	zlog_reset_flag(zlog_default, ZLOG_LOGTIME); /* no time display */

	ZLOG_DEBUG("pkt size = %d, prop delay = %d, link bandwidth = %d\n",
			   spt.t.packet_size, spt.rl.prop_delay, spt.rl.link_bandwidth);

	/* 2. */
	/* FIXME: simu time unit: 1us! */
	ptimer_t simu_begin_timer = {
		.duration = 0,
		.onexpired_func = simu_begin_event,
		.param[0] = (void*) &spt,
		.param[1] = (void*) SIMU_BEGIN,
	};

	time_t t;
	
	srand((unsigned) time(&t));
	
	/* 3. */
	rlc_init();
	rlc_timer_start(&simu_begin_timer);

	/* 4. */
	int step_in_us = 1;
	while (g_is_finished == NOT_FINISHED && g_time_elasped_in_us <= MS2US(S2MS(SIMU_TIME)) ) {
		rlc_timer_push(step_in_us);		/* us */
		g_time_elasped_in_us += step_in_us;

		if ( g_time_elasped_in_us % (int)MS2US(S2MS(1)) == 0 ) {
			ZLOG_INFO("simu time = %f\n", g_time_elasped_in_us/MS2US(S2MS(1)));
		}
	}

	/* output the simu result */
	ZLOG_DEBUG("time_elasped_in_us = %d\n", g_time_elasped_in_us);

	int cnt = 0;
	int output_e2e_delay = 1;

	int n_rxok = 0, n_rxerr = 0;
	while (!DLLIST_EMPTY(&g_sink_packet_list)) {
		packet_t *pktt = (packet_t*) DLLIST_HEAD(&g_sink_packet_list);

		/* 1. tx throughput */
		// output_tx_throughput(pktt);
		// output_rx_throughput(pktt);

		/* 2. e2e delay */
		switch (pktt->ptt) {
		case RX_OK:
			n_rxok++;
			break;
		case RX_ERR:
			n_rxerr++;
			break;
			
		default:
			assert(0);
			break;
		}

		if( output_e2e_delay ) {
			if (pktt->ptt == RX_OK )
				ZLOG_INFO("SN, buffering: %u, %u\n", pktt->sequence_no, pktt->rx_deliver_timestamp - pktt->rx_end_timestamp);
		}
		
		dllist_remove(&g_sink_packet_list, &(pktt->node));
		cnt++;

		// FASTFREE(spt.g_mem_packet_t, pktt);
		free(pktt); pktt = NULL;
	}

	output_tx_throughput(NULL);
	output_rx_throughput(NULL);

	ZLOG_INFO("n_txed = %d, n_rxok = %d, n_rxerr = %d\n", cnt, n_rxok, n_rxerr);

	return 0;
}
Пример #4
0
void output_tx_throughput(packet_t *pktt)
{
	/* unit: second, based on the pktt->tx_begin_timestamp, the pktt->tx_end_timestamp */
	static dllist_node_t tx_tpt_list = {
		.prev = &tx_tpt_list,
		.next = &tx_tpt_list
	};
	
	
	if (pktt == NULL) {
		/* output the result */
		while (!DLLIST_EMPTY(&tx_tpt_list)) {
			tx_throughput_t *ttt = (tx_throughput_t*) DLLIST_HEAD(&tx_tpt_list);
			ZLOG_INFO("tx tpt: at [%d, %d)s, throughput %d bps\n", ttt->time, ttt->time + 1, ttt->throughput /* bps */);
			dllist_remove(&tx_tpt_list, &(ttt->node));
			free(ttt);
		}
		return;
	}

	/* pktt != NULL, calcuate the tx throughput */
	u32 remainder_begin = pktt->tx_begin_timestamp % (u32) MS2US(S2MS(1));
	u32 remainder_end = pktt->tx_end_timestamp % (u32) (MS2US(S2MS(1)));

	u32 integer_begin = (pktt->tx_begin_timestamp - remainder_begin) / MS2US(S2MS(1));
	u32 integer_end = (pktt->tx_end_timestamp - remainder_end) / MS2US(S2MS(1));

	tx_throughput_t * ttt = (tx_throughput_t*) DLLIST_TAIL(&tx_tpt_list);
	
	if ( integer_begin == integer_end ) {
		/* in the same time range */
		/* if have, get it */
		if (DLLIST_IS_HEAD(&tx_tpt_list, ttt) || ttt->time != integer_begin) {
			/* new one */
			tx_throughput_t *new_ttt = (tx_throughput_t*) malloc(sizeof(tx_throughput_t));
			assert(new_ttt);
			new_ttt->time = integer_begin;
			new_ttt->throughput = pktt->mac_pdu_size * OCTET;
			dllist_append(&tx_tpt_list, &(new_ttt->node));
		} else {
			/* already existed, update it */
			ttt->throughput += (pktt->mac_pdu_size * OCTET);
		}
	} else {
		/* not in the same time range, split it based on the pktt->mac_pdu_size */
		assert(integer_end - integer_begin == 1);
		u32 total = pktt->tx_end_timestamp - pktt->tx_begin_timestamp;

		if (DLLIST_IS_HEAD(&tx_tpt_list, ttt)) {
			ttt = (tx_throughput_t*) malloc(sizeof(tx_throughput_t));
			dllist_append(&tx_tpt_list, &(ttt->node));
		}

		u32 part = (pktt->mac_pdu_size * OCTET) * remainder_end / total;
		tx_throughput_t *new_ttt = (tx_throughput_t*) malloc(sizeof(tx_throughput_t));
		assert(new_ttt);
		new_ttt->time = integer_end;
		new_ttt->throughput = (pktt->mac_pdu_size * OCTET) * remainder_end / total;
		dllist_append(&tx_tpt_list, &(new_ttt->node));

		ttt->time = integer_begin;
		ttt->throughput += (pktt->mac_pdu_size * OCTET) * (1 - remainder_end / total);
		ZLOG_DEBUG("begin %d, remainder %d, tpt: %d, end %d, remainder %d, tpt: %d\n",
				  integer_begin, remainder_begin, pktt->mac_pdu_size * OCTET - part,
				  integer_end, remainder_end, part);
	}
}