summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-11-01 14:28:28 +0200
committerimarom <imarom@cisco.com>2015-11-01 14:28:28 +0200
commitee2c7f45e0bf973443b70eb8329811bcad44f83a (patch)
treec3f2cc1db1b090bedfd80979c931d50708053100 /src
parenta1971ec3a7f6cbe0aea1393a57aa17bf44deedac (diff)
stateless cores starts on IDLE - and starts the scheduler only when
traffic is being transmitted if the traffic stops completely on the core - back to IDLE state
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bp_sim.cpp51
-rwxr-xr-xsrc/bp_sim.h6
-rwxr-xr-xsrc/main.cpp19
-rwxr-xr-xsrc/main_dpdk.cpp24
-rw-r--r--src/mock/trex_rpc_server_mock.cpp18
-rwxr-xr-xsrc/os_time.h20
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp44
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h13
8 files changed, 102 insertions, 93 deletions
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 6e291367..92beab91 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -3420,7 +3420,8 @@ int CNodeGenerator::flush_file(dsec_t max_time,
if ( likely ( m_is_realtime ) ){
dsec_t dt ;
thread->m_cpu_dp_u.commit();
- bool once=false;
+
+ thread->check_msgs();
while ( true ) {
dt = now_sec() - n_time ;
@@ -3429,12 +3430,6 @@ int CNodeGenerator::flush_file(dsec_t max_time,
break;
}
- if (!once) {
- /* check the msg queue once */
- thread->check_msgs();
- once=true;
- }
-
rte_pause();
}
thread->m_cpu_dp_u.start_work();
@@ -3453,8 +3448,9 @@ int CNodeGenerator::flush_file(dsec_t max_time,
flush_time=now_sec();
}
}
+
#ifndef RTE_DPDK
- thread->check_msgs();
+ thread->check_msgs();
#endif
uint8_t type=node->m_type;
@@ -3530,16 +3526,16 @@ int CNodeGenerator::flush_file(dsec_t max_time,
}
void CNodeGenerator::handle_slow_messages(uint8_t type,
- CGenNode * node,
- CFlowGenListPerThread * thread,
+ CGenNode * node,
+ CFlowGenListPerThread * thread,
bool always){
if (unlikely (type == CGenNode::FLOW_DEFER_PORT_RELEASE) ) {
m_p_queue.pop();
thread->handler_defer_job(node);
thread->free_node(node);
- }else{
- if (type == CGenNode::FLOW_PKT_NAT) {
+
+ } else if (type == CGenNode::FLOW_PKT_NAT) {
/*repeat and NAT is not supported */
if ( node->is_nat_first_state() ){
node->set_nat_wait_state();
@@ -3573,27 +3569,28 @@ void CNodeGenerator::handle_slow_messages(uint8_t type,
m_p_queue.push(node);
}
- }else{
- if ( type == CGenNode::FLOW_SYNC ){
+ } else if ( type == CGenNode::FLOW_SYNC ) {
- m_p_queue.pop();
+ m_p_queue.pop();
- thread->check_msgs(); /* check messages */
- m_v_if->flush_tx_queue(); /* flush pkt each timeout */
-
- if ( always == false) {
- node->m_time += SYNC_TIME_OUT;
- m_p_queue.push(node);
- }else{
- thread->free_node(node);
- }
+ thread->check_msgs(); /* check messages */
+ m_v_if->flush_tx_queue(); /* flush pkt each timeout */
+ if (always == false) {
+ node->m_time += SYNC_TIME_OUT;
+ m_p_queue.push(node);
}else{
- printf(" ERROR type is not valid %d \n",type);
- assert(0);
+ thread->free_node(node);
}
+
+ /* must be the last section of processing */
+ } else if ( type == CGenNode::EXIT_SCHED ) {
+ remove_all(thread);
+
+ } else {
+ printf(" ERROR type is not valid %d \n",type);
+ assert(0);
}
- }
}
diff --git a/src/bp_sim.h b/src/bp_sim.h
index a11011ce..af084757 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -1364,7 +1364,8 @@ public:
FLOW_DEFER_PORT_RELEASE =2,
FLOW_PKT_NAT =3,
FLOW_SYNC =4, /* called evey 1 msec */
- STATELESS_PKT =5
+ STATELESS_PKT =5,
+ EXIT_SCHED =6
};
@@ -1680,8 +1681,6 @@ public:
} __rte_cache_aligned ;
-
-
/* run time verification of objects size and offsets
need to clean this up and derive this objects from base object but require too much refactoring right now
hhaim
@@ -1857,6 +1856,7 @@ public:
CFlowGenListPerThread * Parent(){
return (m_parent);
}
+
public:
void add_node(CGenNode * mynode);
void remove_all(CFlowGenListPerThread * thread);
diff --git a/src/main.cpp b/src/main.cpp
index 0321761f..bd64c5a4 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -185,25 +185,6 @@ int curent_time(){
#include <pthread.h>
-void delay(int msec){
-
- if (msec == 0)
- {//user that requested that probebly wanted the minimal delay
- //but because of scaling problem he have got 0 so we will give the min delay
- //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
- // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
- msec =1;
-
- }
-
- struct timespec time1, remain; // 2 sec max delay
- time1.tv_sec=msec/1000;
- time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
-
- nanosleep(&time1,&remain);
-}
-
-
struct per_thread_t {
pthread_t tid;
};
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 46fcb4a2..b9fee6bd 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -951,35 +951,11 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
int main_test(int argc , char * argv[]);
-
-
-void delay(int msec){
-
- if (msec == 0)
- {//user that requested that probebly wanted the minimal delay
- //but because of scaling problem he have got 0 so we will give the min delay
- //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
- // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
- msec =1;
-
- }
-
- struct timespec time1, remain; // 2 sec max delay
- time1.tv_sec=msec/1000;
- time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
-
- nanosleep(&time1,&remain);
-}
-
-
-
static const char * default_argv[] = {"xx","-c", "0x7", "-n","2","-b","0000:0b:01.01"};
static int argv_num = 7;
-
-
#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */
diff --git a/src/mock/trex_rpc_server_mock.cpp b/src/mock/trex_rpc_server_mock.cpp
index 8bbcbf5b..0bdf6cf1 100644
--- a/src/mock/trex_rpc_server_mock.cpp
+++ b/src/mock/trex_rpc_server_mock.cpp
@@ -86,24 +86,6 @@ uint16_t gtest_get_mock_server_port() {
return g_rpc_port;
}
-void delay(int msec){
-
- if (msec == 0)
- {//user that requested that probebly wanted the minimal delay
- //but because of scaling problem he have got 0 so we will give the min delay
- //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
- // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
- msec =1;
-
- }
-
- struct timespec time1, remain; // 2 sec max delay
- time1.tv_sec=msec/1000;
- time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
-
- nanosleep(&time1,&remain);
-}
-
/**
* on simulation this is not rebuild every version
* (improved stub)
diff --git a/src/os_time.h b/src/os_time.h
index 153ee3e3..0e732abf 100755
--- a/src/os_time.h
+++ b/src/os_time.h
@@ -22,6 +22,7 @@ limitations under the License.
*/
#include <stdint.h>
+#include <time.h>
typedef uint64_t hr_time_t; // time in high res tick
typedef uint32_t hr_time_32_t; // time in high res tick
@@ -129,6 +130,25 @@ static inline dsec_t now_sec(void){
}
+static inline
+void delay(int msec){
+
+ if (msec == 0)
+ {//user that requested that probebly wanted the minimal delay
+ //but because of scaling problem he have got 0 so we will give the min delay
+ //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
+ // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
+ msec =1;
+
+ }
+
+ struct timespec time1, remain; // 2 sec max delay
+ time1.tv_sec=msec/1000;
+ time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
+
+ nanosleep(&time1,&remain);
+}
+
#endif
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index fd54256d..306b23d0 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -37,9 +37,30 @@ TrexStatelessDpCore::TrexStatelessDpCore(uint8_t thread_id, CFlowGenListPerThrea
m_state = STATE_IDLE;
}
-void
-TrexStatelessDpCore::start() {
+/**
+ * in idle state loop, the processor most of the time sleeps
+ * and periodically checks for messages
+ *
+ * @author imarom (01-Nov-15)
+ */
+void
+TrexStatelessDpCore::idle_state_loop() {
+ while (m_state == STATE_IDLE) {
+ periodic_check_for_cp_messages();
+ delay(200);
+ }
+}
+
+/**
+ * scehduler runs when traffic exists
+ * it will return when no more transmitting is done on this
+ * core
+ *
+ * @author imarom (01-Nov-15)
+ */
+void
+TrexStatelessDpCore::start_scheduler() {
/* creates a maintenace job using the scheduler */
CGenNode * node_sync = m_core->create_node() ;
node_sync->m_type = CGenNode::FLOW_SYNC;
@@ -48,7 +69,16 @@ TrexStatelessDpCore::start() {
double old_offset = 0.0;
m_core->m_node_gen.flush_file(100000000, 0.0, false, m_core, old_offset);
+}
+
+void
+TrexStatelessDpCore::start() {
+
+ while (true) {
+ idle_state_loop();
+ start_scheduler();
+ }
}
void
@@ -126,6 +156,16 @@ TrexStatelessDpCore::stop_traffic(uint8_t port_id) {
if (m_active_nodes.size() == 0) {
m_state = STATE_IDLE;
+ /* stop the scheduler */
+
+ CGenNode *node = m_core->create_node() ;
+
+ node->m_type = CGenNode::EXIT_SCHED;
+
+ /* make sure it will be scheduled after the current node */
+ node->m_time = m_core->m_node_gen.m_p_queue.top()->m_time;
+
+ m_core->m_node_gen.add_node(node);
}
}
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index b71431ad..698cac2f 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -94,6 +94,19 @@ public:
private:
/**
+ * in idle state loop, the processor most of the time sleeps
+ * and periodically checks for messages
+ *
+ */
+ void idle_state_loop();
+
+ /**
+ * real job is done when scheduler is launched
+ *
+ */
+ void start_scheduler();
+
+ /**
* handles a CP to DP message
*
* @author imarom (27-Oct-15)