// In this scenario, two clients make non-concurrent, composable changes so that // transformation is never needed. bool basic_compose_scenario(char** msg) { setup(2); ot_op* opa = ot_new_op(); ot_insert(opa, "a"); ot_client_apply(clients[0], &opa); flush_clients(); flush_server(); ASSERT_CONVERGENCE("a", msg); ot_op* opb = ot_new_op(); ot_skip(opb, 1); ot_insert(opb, "b"); ot_client_apply(clients[1], &opb); flush_clients(); flush_server(); ASSERT_CONVERGENCE("ab", msg); ot_op* opc = ot_new_op(); ot_skip(opc, 1); ot_delete(opc, 1); ot_client_apply(clients[0], &opc); flush_clients(); flush_server(); ASSERT_CONVERGENCE("a", msg); teardown(); return true; }
static inline void do_vswitchd(void) { static uint64_t last_stats_display_tsc = 0; static uint64_t next_tsc = 0; uint64_t curr_tsc_local; /* handle any packets from vswitchd */ handle_request_from_vswitchd(); /* * curr_tsc is accessed by all cores but is updated here for each loop * which causes cacheline contention. By setting a defined update * period for curr_tsc of 1us this contention is removed. */ curr_tsc_local = rte_rdtsc(); if (curr_tsc_local >= next_tsc) { curr_tsc = curr_tsc_local; next_tsc = curr_tsc_local + tsc_update_period; } /* display stats every 'stats' sec */ if ((curr_tsc - last_stats_display_tsc) / cpu_freq >= stats_display_interval && stats_display_interval != 0) { last_stats_display_tsc = curr_tsc; stats_display(); } flush_clients(); flush_ports(); flush_vhost_devs(); }
do_client_switching(void) { static unsigned client = CLIENT1; static unsigned kni_vportid = KNI0; static unsigned veth_vportid = VETH0; static unsigned vhost_vportid = VHOST0; int rx_count = 0; struct rte_mbuf *bufs[PKT_BURST_SIZE]; /* Client ports */ rx_count = receive_from_vport(client, &bufs[0]); do_switch_packets(client, bufs, rx_count); /* move to next client and dont handle client 0*/ if (++client == num_clients) { client = 1; } /* KNI ports */ if (num_kni) { rx_count = receive_from_vport(kni_vportid, &bufs[0]); do_switch_packets(kni_vportid, bufs, rx_count); /* move to next kni port */ if (++kni_vportid == (unsigned)KNI0 + num_kni) { kni_vportid = KNI0; } } /* vETH Devices */ if (unlikely(num_veth)) { /* vEth devices are optional */ rx_count = receive_from_vport(veth_vportid, &bufs[0]); do_switch_packets(veth_vportid, bufs, rx_count); /* move to next veth port */ if (++veth_vportid == (unsigned)VETH0 + num_veth) { veth_vportid = VETH0; } } /* Vhost Devices */ if (num_vhost) { rx_count = receive_from_vport(vhost_vportid, &bufs[0]); do_switch_packets(vhost_vportid, bufs, rx_count); /* move to next vhost port */ if (++vhost_vportid == (unsigned)VHOST0 + num_vhost) { vhost_vportid = VHOST0; } } flush_clients(); flush_ports(); flush_vhost_devs(); }
do_port_switching(unsigned vportid) { int rx_count = 0; struct rte_mbuf *bufs[PKT_BURST_SIZE]; rx_count = receive_from_vport(vportid, &bufs[0]); do_switch_packets(vportid, bufs, rx_count); flush_clients(); flush_ports(); flush_vhost_devs(); flush_nic_tx_ring(vportid); }
// In this scenario, two clients send an initial op at the same time, requiring // that the server transform them. Before the server replies with the // transformed ops, one client buffers additional changes. The buffered changes // are then sent after the server's response is received. bool xform_buffer_scenario(char** msg) { setup(2); ot_op* opc = ot_new_op(); ot_insert(opc, "ABC"); ot_client_apply(clients[1], &opc); flush_clients(); ASSERT_OP_SNAPSHOT(clients[1]->doc->composed, "ABC", msg); ot_op* opa = ot_new_op(); ot_insert(opa, "abc"); ot_client_apply(clients[0], &opa); flush_clients(); ASSERT_OP_SNAPSHOT(clients[0]->doc->composed, "abc", msg); ot_op* opb = ot_new_op(); ot_skip(opb, 3); ot_insert(opb, "def"); ot_client_apply(clients[0], &opb); ASSERT_OP_SNAPSHOT(clients[0]->doc->composed, "abcdef", msg); flush_server(); ASSERT_OP_SNAPSHOT(server->doc->composed, "ABCabc", msg); ASSERT_OP_SNAPSHOT(clients[0]->doc->composed, "ABCabcdef", msg); ASSERT_OP_SNAPSHOT(clients[1]->doc->composed, "ABCabc", msg); flush_clients(); flush_server(); ASSERT_CONVERGENCE("ABCabcdef", msg); teardown(); return true; }