summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp28
-rw-r--r--src/stateless/cp/trex_stream_vm.h72
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp24
-rw-r--r--src/stateless/dp/trex_stream_node.h9
4 files changed, 116 insertions, 17 deletions
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp
index cccbfe88..a3f585ad 100644
--- a/src/stateless/cp/trex_stream_vm.cpp
+++ b/src/stateless/cp/trex_stream_vm.cpp
@@ -191,7 +191,29 @@ void StreamVm::build_flow_var_table() {
var_clear_table();
m_cur_var_offset=0;
uint32_t ins_id=0;
+ m_is_random_var=false;
/* scan all flow var instruction and build */
+
+ for (auto inst : m_inst_list) {
+ if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){
+ StreamVmInstructionFlowMan * ins_man=(StreamVmInstructionFlowMan *)inst;
+ if (ins_man->m_op ==StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM){
+ m_is_random_var =true;
+ }
+ }
+ }
+
+ /* if we found allocate BSS +4 bytes */
+ if ( m_is_random_var ){
+ VmFlowVarRec var;
+
+ var.m_offset = m_cur_var_offset;
+ var.m_ins.m_ins_flowv = NULL;
+ var.m_size_bytes = sizeof(uint32_t);
+ var_add("___random___",var);
+ m_cur_var_offset += sizeof(uint32_t);
+ }
+
for (auto inst : m_inst_list) {
if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){
@@ -207,6 +229,7 @@ void StreamVm::build_flow_var_table() {
ss << "instruction id '" << ins_id << "' flow variable name " << ins_man->m_var_name << " already exists";
err(ss.str());
}else{
+
var.m_offset=m_cur_var_offset;
var.m_ins.m_ins_flowv = ins_man;
var.m_size_bytes = ins_man->m_size_bytes;
@@ -541,6 +564,11 @@ void StreamVm::build_bss() {
alloc_bss();
uint8_t * p=(uint8_t *)m_bss;
+ if ( m_is_random_var ){
+ *((uint32_t*)p)=rand();
+ p+=sizeof(uint32_t);
+ }
+
for (auto inst : m_inst_list) {
if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index f327267e..891e5b51 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -32,6 +32,46 @@ limitations under the License.
+//https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/
+
+//Used to seed the generator.
+inline void fast_srand(uint32_t &g_seed, int seed ){
+ g_seed = seed;
+}
+
+
+//fastrand routine returns one integer, similar output value range as C lib.
+
+inline int fastrand(uint32_t &g_seed)
+{
+ g_seed = (214013*g_seed+2531011);
+ return (g_seed>>16)&0x7FFF;
+}
+
+static inline void vm_srand(uint32_t * per_thread_seed,uint64_t seedval)
+{
+ fast_srand( *per_thread_seed,seedval );
+}
+
+static inline uint32_t vm_rand16(uint32_t * per_thread_seed)
+{
+ return ( fastrand(*per_thread_seed));
+}
+
+static inline uint32_t vm_rand32(uint32_t * per_thread_seed)
+{
+ return ( (vm_rand16(per_thread_seed)<<16)+vm_rand16(per_thread_seed));
+}
+
+static inline uint64_t vm_rand64(uint32_t * per_thread_seed)
+{
+ uint64_t res;
+
+ res=((uint64_t)vm_rand32(per_thread_seed)<<32)+vm_rand32(per_thread_seed);
+
+ return (res);
+}
+
class StreamVm;
@@ -64,9 +104,9 @@ public:
}
}
- inline void run_rand(uint8_t * flow_var) {
+ inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
uint8_t * p=(flow_var+m_flow_offset);
- *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1));
+ *p= m_min_val + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1));
}
@@ -98,9 +138,9 @@ public:
}
}
- inline void run_rand(uint8_t * flow_var) {
+ inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
uint16_t * p=(uint16_t *)(flow_var+m_flow_offset);
- *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1));
+ *p= m_min_val + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1));
}
@@ -133,9 +173,9 @@ public:
}
}
- inline void run_rand(uint8_t * flow_var) {
+ inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
uint32_t * p=(uint32_t *)(flow_var+m_flow_offset);
- *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1));
+ *p= m_min_val + (vm_rand32(per_thread_random) % (int)(m_max_val - m_min_val + 1));
}
} __attribute__((packed)) ;
@@ -166,9 +206,9 @@ public:
}
}
- inline void run_rand(uint8_t * flow_var) {
+ inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
uint64_t * p=(uint64_t *)(flow_var+m_flow_offset);
- *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1));
+ *p= m_min_val + ( vm_rand64(per_thread_random) % (int)(m_max_val - m_min_val + 1));
}
@@ -403,7 +443,8 @@ private:
class StreamDPVmInstructionsRunner {
public:
- inline void run(uint32_t program_size,
+ inline void run(uint32_t * per_thread_random,
+ uint32_t program_size,
uint8_t * program, /* program */
uint8_t * flow_var, /* flow var */
uint8_t * pkt); /* pkt */
@@ -411,7 +452,8 @@ public:
};
-inline void StreamDPVmInstructionsRunner::run(uint32_t program_size,
+inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random,
+ uint32_t program_size,
uint8_t * program, /* program */
uint8_t * flow_var, /* flow var */
uint8_t * pkt){
@@ -496,22 +538,22 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t program_size,
case StreamDPVmInstructions::ditRANDOM8 :
ua.lpv8 =(StreamDPOpFlowVar8 *)p;
- ua.lpv8->run_rand(flow_var);
+ ua.lpv8->run_rand(flow_var,per_thread_random);
p+=sizeof(StreamDPOpFlowVar8);
break;
case StreamDPVmInstructions::ditRANDOM16 :
ua.lpv16 =(StreamDPOpFlowVar16 *)p;
- ua.lpv16->run_rand(flow_var);
+ ua.lpv16->run_rand(flow_var,per_thread_random);
p+=sizeof(StreamDPOpFlowVar16);
break;
case StreamDPVmInstructions::ditRANDOM32 :
ua.lpv32 =(StreamDPOpFlowVar32 *)p;
- ua.lpv32->run_rand(flow_var);
+ ua.lpv32->run_rand(flow_var,per_thread_random);
p+=sizeof(StreamDPOpFlowVar32);
break;
case StreamDPVmInstructions::ditRANDOM64 :
ua.lpv64 =(StreamDPOpFlowVar64 *)p;
- ua.lpv64->run_rand(flow_var);
+ ua.lpv64->run_rand(flow_var,per_thread_random);
p+=sizeof(StreamDPOpFlowVar64);
break;
@@ -1023,6 +1065,7 @@ public:
m_bss=0;
m_pkt_size=0;
m_cur_var_offset=0;
+ m_is_random_var=false;
m_split_instr=NULL;
m_is_compiled = false;
}
@@ -1153,6 +1196,7 @@ private:
void add_field_cnt(uint16_t new_cnt);
private:
+ bool m_is_random_var;
bool m_is_compiled;
uint16_t m_prefix_size;
uint16_t m_pkt_size;
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index acbf1b88..c211b9f5 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -69,12 +69,31 @@ void CGenNodeStateless::Dump(FILE *fd){
}
+
+void CGenNodeStateless::refresh_vm_bss(){
+ if ( m_vm_flow_var ) {
+ StreamVmDp * vm_s=m_ref_stream_info->m_vm_dp;
+ assert(vm_s);
+ memcpy(m_vm_flow_var,vm_s->get_bss(),vm_s->get_bss_size());
+ }
+}
+
+
+/**
+ * this function called when stream restart after it was inactive
+ */
void CGenNodeStateless::refresh(){
/* refill the stream info */
m_single_burst = m_single_burst_refill;
m_multi_bursts = m_ref_stream_info->m_num_bursts;
m_state = CGenNodeStateless::ss_ACTIVE;
+
+ /* refresh init value */
+#if 0
+ /* TBD should add a JSON varible for that */
+ refresh_vm_bss();
+#endif
}
@@ -124,7 +143,8 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){
/* run the VM program */
StreamDPVmInstructionsRunner runner;
- runner.run( m_vm_program_size,
+ runner.run( (uint32_t*)m_vm_flow_var,
+ m_vm_program_size,
m_vm_program,
m_vm_flow_var,
(uint8_t*)p);
@@ -302,7 +322,7 @@ bool TrexStatelessDpCore::set_stateless_next_node(CGenNodeStateless * cur_node,
/* can't be FREE_RESUSE */
assert(state != CGenNodeStateless::ss_FREE_RESUSE);
- if (next_node->get_state() == CGenNodeStateless::ss_INACTIVE ) {
+ if (state == CGenNodeStateless::ss_INACTIVE ) {
/* refill start info and scedule, no update in active streams */
next_node->refresh();
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index d33785fe..70a66e6a 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -102,11 +102,13 @@ private:
uint8_t * m_vm_flow_var; /* pointer to the vm flow var */
uint8_t * m_vm_program; /* pointer to the program */
uint16_t m_vm_program_size; /* up to 64K op codes */
+ uint16_t m_pad2;
+ uint32_t m_pad3;
/* End Fast Field VM Section */
/* pad to match the size of CGenNode */
- uint8_t m_pad_end[30];
+ uint8_t m_pad_end[20];
public:
@@ -329,6 +331,11 @@ public:
void Dump(FILE *fd);
+private:
+
+ void refresh_vm_bss();
+
+
} __rte_cache_aligned;
static_assert(sizeof(CGenNodeStateless) == sizeof(CGenNode), "sizeof(CGenNodeStateless) != sizeof(CGenNode)" );