summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp/trex_stream_vm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless/cp/trex_stream_vm.cpp')
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp90
1 files changed, 84 insertions, 6 deletions
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp
index 2984b896..a3f585ad 100644
--- a/src/stateless/cp/trex_stream_vm.cpp
+++ b/src/stateless/cp/trex_stream_vm.cpp
@@ -449,7 +449,7 @@ void StreamVm::build_program(){
op = StreamDPVmInstructions::ditRANDOM64 ;
}
- StreamDPOpFlowVar32 fv64;
+ StreamDPOpFlowVar64 fv64;
fv64.m_op = op;
fv64.m_flow_offset = get_var_offset(lpMan->m_var_name);
fv64.m_min_val = (uint64_t)lpMan->m_min_value;
@@ -577,19 +577,19 @@ void StreamVm::build_bss() {
switch (ins_man->m_size_bytes) {
case 1:
- *p=(uint8_t)ins_man->m_init_value;
+ *p=(uint8_t)ins_man->get_bss_init_value();
p+=1;
break;
case 2:
- *((uint16_t*)p)=(uint16_t)ins_man->m_init_value;
+ *((uint16_t*)p)=(uint16_t)ins_man->get_bss_init_value();
p+=2;
break;
case 4:
- *((uint32_t*)p)=(uint32_t)ins_man->m_init_value;
+ *((uint32_t*)p)=(uint32_t)ins_man->get_bss_init_value();
p+=4;
break;
case 8:
- *((uint64_t*)p)=(uint64_t)ins_man->m_init_value;
+ *((uint64_t*)p)=(uint64_t)ins_man->get_bss_init_value();
p+=8;
break;
default:
@@ -621,9 +621,58 @@ void StreamVm::build_bss() {
}
}
+/**
+ * set the VM split instruction
+ * instr is a pointer to an instruction inside
+ * the VM program
+ *
+ */
+void
+StreamVm::set_split_instruction(StreamVmInstructionVar *instr) {
+ m_split_instr = instr;
+}
+
+/**
+ * copy instructions from this VM to 'other'
+ *
+ * @author imarom (22-Dec-15)
+ *
+ * @param other
+ */
+void
+StreamVm::copy_instructions(StreamVm &other) const {
+ /* clear previous if any exists */
+ for (auto instr : other.m_inst_list) {
+ delete instr;
+ }
+
+ other.m_inst_list.clear();
+ for (auto instr : m_inst_list) {
+ StreamVmInstruction *new_instr = instr->clone();
+ other.m_inst_list.push_back(new_instr);
-void StreamVm::compile() {
+ /* for the split instruction - find the right one */
+ if (instr == m_split_instr) {
+ /* dynamic cast must succeed here */
+ other.m_split_instr = dynamic_cast<StreamVmInstructionVar *>(new_instr);
+ assert(other.m_split_instr);
+ }
+ }
+
+}
+
+/**
+ * actual work - compile the VM
+ *
+ */
+void StreamVm::compile(uint16_t pkt_len) {
+
+ if (is_vm_empty()) {
+ return;
+ }
+
+ m_pkt_size = pkt_len;
/* build flow var offset table */
build_flow_var_table() ;
@@ -638,6 +687,11 @@ void StreamVm::compile() {
ss << "maximum offset is" << get_max_packet_update_offset() << " bigger than maximum " <<svMAX_PACKET_OFFSET_CHANGE;
err(ss.str());
}
+
+ /* calculate the mbuf size that we should allocate */
+ m_prefix_size = calc_writable_mbuf_size(get_max_packet_update_offset(), m_pkt_size);
+
+ m_is_compiled = true;
}
@@ -648,6 +702,30 @@ StreamVm::~StreamVm() {
free_bss();
}
+/**
+* return a pointer to a flow var / client var
+* by name if exists, otherwise NULL
+*
+*/
+StreamVmInstructionVar *
+StreamVm::lookup_var_by_name(const std::string &var_name) {
+ for (StreamVmInstruction *inst : m_inst_list) {
+
+ /* try to cast up to a variable */
+ StreamVmInstructionVar *var = dynamic_cast<StreamVmInstructionVar *>(inst);
+ if (!var) {
+ continue;
+ }
+
+ if (var->get_var_name() == var_name) {
+ return var;
+ }
+
+ }
+
+ return NULL;
+}
+
void StreamVm::Dump(FILE *fd){
fprintf(fd," instructions \n");