summaryrefslogtreecommitdiffstats
path: root/src/bp_sim.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bp_sim.cpp')
-rwxr-xr-xsrc/bp_sim.cpp413
1 files changed, 149 insertions, 264 deletions
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 76bd6ec7..f9cb3220 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -3858,187 +3858,86 @@ int CNodeGenerator::flush_file(dsec_t max_time,
-#if 0
-int CNodeGenerator::flush_file(dsec_t max_time,
- dsec_t d_time,
- bool always,
- CFlowGenListPerThread * thread,
- double &old_offset){
- CGenNode * node;
- #ifdef TREX_SIM
- dsec_t flush_time=now_sec();
- #endif
- dsec_t offset=0.0;
- #ifdef TREX_SIM
- dsec_t n_time;
- #endif
- if (always) {
- offset=old_offset;
- }
- #ifdef TREX_SIM
- uint32_t events=0;
- #endif
- bool done=false;
-
- thread->m_cpu_dp_u.start_work1();
-
- /**
- * if a positive value was given to max time
- * schedule an exit node
- */
- if ( (max_time > 0) && (!always) ) {
- CGenNode *exit_node = thread->create_node();
-
- exit_node->m_type = CGenNode::EXIT_SCHED;
- exit_node->m_time = max_time;
- add_node(exit_node);
- }
-
- while (true) {
-
- node = m_p_queue.top();
- #ifdef TREX_SIM
- n_time = node->m_time + offset;
-
- events++;
+void CNodeGenerator::handle_flow_pkt(CGenNode *node, CFlowGenListPerThread *thread) {
+
+ /*repeat and NAT is not supported */
+ if ( node->is_nat_first_state() ) {
+ node->set_nat_wait_state();
+ flush_one_node_to_file(node);
+ #ifdef _DEBUG
+ update_stats(node);
#endif
-/*#ifdef VALG
- if (events > 1 ) {
- CALLGRIND_START_INSTRUMENTATION;
- }
-#endif*/
-
- thread->m_cpu_dp_u.commit1();
- thread->m_cpu_dp_u.start_work1();
-
- #ifdef TREX_SIM
-
- if ( likely ( m_is_realtime ) ){
- dsec_t dt ;
- thread->m_cpu_dp_u.commit1();
-
- while ( true ) {
- dt = now_sec() - n_time ;
-
- if (dt> (-0.00003)) {
- break;
- }
-
- rte_pause();
- }
- thread->m_cpu_dp_u.start_work1();
+ } else {
+ if ( node->is_nat_wait_state() ) {
+ if (node->is_responder_pkt()) {
+ m_p_queue.pop();
+ /* time out, need to free the flow and remove the association , we didn't get convertion yet*/
+ thread->terminate_nat_flows(node);
+ return;
- /* add offset in case of faliures more than 100usec */
- if ( unlikely( dt > 0.000100 ) ) {
- offset += dt;
- }
- /* update histogram */
- if ( unlikely( events % 16 ) ==0 ) {
- m_realtime_his.Add(dt);
- }
- /* flush evey 10 usec */
- if ( now_sec() - flush_time > 0.00001 ){
- m_v_if->flush_tx_queue();
- flush_time=now_sec();
+ } else {
+ flush_one_node_to_file(node);
+ #ifdef _DEBUG
+ update_stats(node);
+ #endif
}
+ } else {
+ assert(0);
}
- #endif
+ }
+ m_p_queue.pop();
+ if ( node->is_last_in_flow() ) {
+ thread->free_last_flow_node( node);
+ } else {
+ node->update_next_pkt_in_flow();
+ m_p_queue.push(node);
+ }
+}
+void CNodeGenerator::handle_flow_sync(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler) {
+ /* flow sync message is a sync point for time */
+ thread->m_cur_time_sec = node->m_time;
- uint8_t type=node->m_type;
+ /* first pop the node */
+ m_p_queue.pop();
- if ( type == CGenNode::STATELESS_PKT ) {
- m_p_queue.pop();
- CGenNodeStateless *node_sl = (CGenNodeStateless *)node;
+ thread->check_msgs(); /* check messages */
+ m_v_if->flush_tx_queue(); /* flush pkt each timeout */
- /* if the stream has been deactivated - end */
- if ( unlikely( node_sl->is_mask_for_free() ) ) {
- thread->free_node(node);
- } else {
+ /* exit in case this is the last node*/
+ if ( m_p_queue.size() == m_parent->m_non_active_nodes ) {
+ thread->free_node(node);
+ exit_scheduler = true;
+ } else {
+ /* schedule for next maintenace */
+ node->m_time += SYNC_TIME_OUT;
+ m_p_queue.push(node);
+ }
- /* count before handle - node might be destroyed */
- #ifdef TREX_SIM
- update_stl_stats(node_sl);
- #endif
+}
- node_sl->handle(thread);
+void CNodeGenerator::handle_command(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler) {
+ m_p_queue.pop();
+ CGenNodeCommand *node_cmd = (CGenNodeCommand *)node;
+ TrexStatelessCpToDpMsgBase * cmd=node_cmd->m_cmd;
+ cmd->handle(&thread->m_stateless_dp_info);
+ exit_scheduler = cmd->is_quit();
+ thread->free_node((CGenNode *)node_cmd);/* free the node */
+}
- #ifdef TREX_SIM
- if (has_limit_reached()) {
- thread->m_stateless_dp_info.stop_traffic(node_sl->get_port_id(), false, 0);
- }
- #endif
+void CNodeGenerator::handle_pcap_pkt(CGenNode *node, CFlowGenListPerThread *thread) {
+ m_p_queue.pop();
- }
-
-
- }else{
- if ( likely( type == CGenNode::FLOW_PKT ) ) {
- /* PKT */
- if ( !(node->is_repeat_flow()) || (always==false)) {
- flush_one_node_to_file(node);
- #ifdef _DEBUG
- update_stats(node);
- #endif
- }
- m_p_queue.pop();
- if ( node->is_last_in_flow() ) {
- if ((node->is_repeat_flow()) && (always==false)) {
- /* Flow is repeated, reschedule it */
- thread->reschedule_flow( node);
- }else{
- /* Flow will not be repeated, so free node */
- thread->free_last_flow_node( node);
- }
- }else{
- node->update_next_pkt_in_flow();
- m_p_queue.push(node);
- }
- }else{
- if ((type == CGenNode::FLOW_FIF)) {
- /* callback to our method */
- m_p_queue.pop();
- if ( always == false) {
- thread->m_cur_time_sec = node->m_time ;
-
- if ( thread->generate_flows_roundrobin(&done) <0){
- break;
- }
- if (!done) {
- node->m_time +=d_time;
- m_p_queue.push(node);
- }else{
- thread->free_node(node);
- }
- }else{
- thread->free_node(node);
- }
-
- }else{
- bool exit_sccheduler = handle_slow_messages(type,node,thread,always);
- if (exit_sccheduler) {
- break;
- }
- }
- }
- }
- }
+ CGenNodePCAP *node_pcap = (CGenNodePCAP *)node;
- if ( thread->is_terminated_by_master() ) {
- return (0);
- }
-
- if (!always) {
- old_offset =offset;
- }else{
- // free the left other
- thread->handler_defer_job_flush();
+ /* might have been marked for free */
+ if ( unlikely( node_pcap->is_marked_for_free() ) ) {
+ thread->free_node(node);
+ } else {
+ node_pcap->handle(thread);
}
- return (0);
}
-#endif
-
bool
CNodeGenerator::handle_slow_messages(uint8_t type,
CGenNode * node,
@@ -4048,89 +3947,42 @@ CNodeGenerator::handle_slow_messages(uint8_t type,
/* should we continue after */
bool exit_scheduler = false;
- if (unlikely (type == CGenNode::FLOW_DEFER_PORT_RELEASE) ) {
+ switch (type) {
+ case CGenNode::PCAP_PKT:
+ handle_pcap_pkt(node, thread);
+ break;
+
+ case CGenNode::FLOW_DEFER_PORT_RELEASE:
m_p_queue.pop();
thread->handler_defer_job(node);
thread->free_node(node);
+ break;
- } else if (type == CGenNode::FLOW_PKT_NAT) {
- /*repeat and NAT is not supported */
- if ( node->is_nat_first_state() ){
- node->set_nat_wait_state();
- flush_one_node_to_file(node);
- #ifdef _DEBUG
- update_stats(node);
- #endif
- }else{
- if ( node->is_nat_wait_state() ) {
- if (node->is_responder_pkt()) {
- m_p_queue.pop();
- /* time out, need to free the flow and remove the association , we didn't get convertion yet*/
- thread->terminate_nat_flows(node);
- return (exit_scheduler);
-
- }else{
- flush_one_node_to_file(node);
- #ifdef _DEBUG
- update_stats(node);
- #endif
- }
- }else{
- assert(0);
- }
- }
- m_p_queue.pop();
- if ( node->is_last_in_flow() ) {
- thread->free_last_flow_node( node);
- }else{
- node->update_next_pkt_in_flow();
- m_p_queue.push(node);
- }
-
- } else if ( type == CGenNode::FLOW_SYNC ) {
+ case CGenNode::FLOW_PKT_NAT:
+ handle_flow_pkt(node, thread);
+ break;
- /* flow sync message is a sync point for time */
- thread->m_cur_time_sec = node->m_time;
+ case CGenNode::FLOW_SYNC:
+ handle_flow_sync(node, thread, exit_scheduler);
+ break;
- /* first pop the node */
- m_p_queue.pop();
+ case CGenNode::EXIT_SCHED:
+ m_p_queue.pop();
+ thread->free_node(node);
+ exit_scheduler = true;
+ break;
- thread->check_msgs(); /* check messages */
- m_v_if->flush_tx_queue(); /* flush pkt each timeout */
- /* exit in case this is the last node*/
- if ( m_p_queue.size() == m_parent->m_non_active_nodes ) {
- thread->free_node(node);
- exit_scheduler = true;
- } else {
- /* schedule for next maintenace */
- node->m_time += SYNC_TIME_OUT;
- m_p_queue.push(node);
- }
+ case CGenNode::COMMAND:
+ handle_command(node, thread, exit_scheduler);
+ break;
+ default:
+ assert(0);
+ }
- } else if ( type == CGenNode::EXIT_SCHED ) {
- m_p_queue.pop();
- thread->free_node(node);
- exit_scheduler = true;
-
- } else {
- if ( type == CGenNode::COMMAND) {
- m_p_queue.pop();
- CGenNodeCommand *node_cmd = (CGenNodeCommand *)node;
- {
- TrexStatelessCpToDpMsgBase * cmd=node_cmd->m_cmd;
- cmd->handle(&thread->m_stateless_dp_info);
- exit_scheduler = cmd->is_quit();
- thread->free_node((CGenNode *)node_cmd);/* free the node */
- }
- }else{
- printf(" ERROR type is not valid %d \n",type);
- assert(0);
- }
- }
+ return (exit_scheduler);
- return exit_scheduler;
}
@@ -4408,8 +4260,6 @@ void CFlowGenListPerThread::check_msgs(void) {
}
}
-//void delay(int msec);
-
void CFlowGenListPerThread::start_stateless_simulation_file(std::string erf_file_name,
@@ -5123,39 +4973,66 @@ int CErfIFStl::update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){
}
-int CErfIFStl::send_node(CGenNode * _no_to_use){
-
- if ( m_preview_mode->getFileWrite() ){
-
- CGenNodeStateless * node_sl=(CGenNodeStateless *) _no_to_use;
+int CErfIFStl::send_sl_node(CGenNodeStateless *node_sl) {
+ pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
- pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
-
- rte_mbuf_t * m;
- if ( likely(node_sl->is_cache_mbuf_array()) ) {
- m=node_sl->cache_mbuf_array_get_cur();
- fill_raw_packet(m,_no_to_use,dir);
+ rte_mbuf_t * m;
+ if ( likely(node_sl->is_cache_mbuf_array()) ) {
+ m=node_sl->cache_mbuf_array_get_cur();
+ fill_raw_packet(m,(CGenNode *)node_sl,dir);
+ }else{
+ m=node_sl->get_cache_mbuf();
+ if (m) {
+ /* cache packet */
+ fill_raw_packet(m,(CGenNode *)node_sl,dir);
+ /* can't free the m, it is cached*/
}else{
- m=node_sl->get_cache_mbuf();
- if (m) {
- /* cache packet */
- fill_raw_packet(m,_no_to_use,dir);
- /* can't free the m, it is cached*/
- }else{
-
- m=node_sl->alloc_node_with_vm();
- assert(m);
- fill_raw_packet(m,_no_to_use,dir);
- rte_pktmbuf_free(m);
- }
+ m=node_sl->alloc_node_with_vm();
+ assert(m);
+ fill_raw_packet(m,(CGenNode *)node_sl,dir);
+ rte_pktmbuf_free(m);
}
+ }
/* check that we have mbuf */
+ int rc = write_pkt(m_raw);
+ BP_ASSERT(rc == 0);
+
+ return (rc);
+}
- int rc = write_pkt(m_raw);
- BP_ASSERT(rc == 0);
+
+int CErfIFStl::send_pcap_node(CGenNodePCAP *pcap_node) {
+ rte_mbuf_t *m = pcap_node->get_pkt();
+ if (!m) {
+ return (-1);
}
+ pkt_dir_t dir = (pkt_dir_t)pcap_node->get_mbuf_dir();
+ fill_raw_packet(m, (CGenNode*)pcap_node, dir);
+ rte_pktmbuf_free(m);
+
+ int rc = write_pkt(m_raw);
+ BP_ASSERT(rc == 0);
+
+ return (rc);
+}
+
+int CErfIFStl::send_node(CGenNode * _no_to_use){
+
+ if ( m_preview_mode->getFileWrite() ) {
+
+ switch (_no_to_use->m_type) {
+ case CGenNode::STATELESS_PKT:
+ return send_sl_node((CGenNodeStateless *) _no_to_use);
+
+ case CGenNode::PCAP_PKT:
+ return send_pcap_node((CGenNodePCAP *) _no_to_use);
+
+ default:
+ assert(0);
+ }
+ }
return (0);
}
@@ -6523,10 +6400,18 @@ void CGenNodeBase::free_base(){
CGenNodeStateless* p=(CGenNodeStateless*)this;
p->free_stl_node();
return;
+ }
+
+ if (m_type == PCAP_PKT) {
+ CGenNodePCAP *p = (CGenNodePCAP *)this;
+ p->destroy();
+ return;
}
+
if ( m_type == COMMAND ) {
CGenNodeCommand* p=(CGenNodeCommand*)this;
p->free_command();
}
}
+