MoonGen
 All Files Functions Variables Pages
distribute.lua
Go to the documentation of this file.
1 ---------------------------------
2 --- @file distribute.lua
3 --- @brief Distribute ...
4 --- @todo TODO docu
5 ---------------------------------
6 
7 local ffi = require "ffi"
8 local dpdk = require "dpdk"
9 local serpent = require "Serpent"
10 
11 ffi.cdef [[
12 struct mg_distribute_queue{
13  uint16_t next_idx;
14  uint16_t size;
15  struct rte_mbuf *pkts[0];
16 };
17 
18 struct mg_distribute_output{
19  uint8_t valid;
20  uint8_t port_id;
21  uint16_t queue_id;
22  uint64_t timeout;
23  uint64_t time_first_added;
24  struct mg_distribute_queue *queue;
25 };
26 
27 struct mg_distribute_config{
28  uint16_t entry_offset;
29  uint16_t nr_outputs;
30  uint8_t always_flush;
31  struct mg_distribute_output outputs[0];
32 };
33 
34 
35 inline int8_t mg_distribute_enqueue(
36  struct mg_distribute_queue * queue,
37  struct rte_mbuf *pkt
38  ){
39  queue->pkts[queue->next_idx] = pkt;
40  queue->next_idx++;
41  // TODO: is switch here faster?
42  // Attention: Order is relevant here, as a queue with size 1
43  // should always trigger a flush and never timestamping
44  if(unlikely(queue->next_idx == queue->size)){
45  return 2;
46  }
47  if(unlikely(queue->next_idx == 1)){
48  return 1;
49  }
50  return 0;
51 }
52 
53 struct mg_distribute_config * mg_distribute_create(
54  uint16_t entry_offset,
55  uint16_t nr_outputs,
56  uint8_t always_flush
57  );
58 
59 int mg_distribute_output_flush(
60  struct mg_distribute_config *cfg,
61  uint16_t number
62  );
63 
64 int mg_distribute_register_output(
65  struct mg_distribute_config *cfg,
66  uint16_t number,
67  uint8_t port_id,
68  uint16_t queue_id,
69  uint16_t burst_size,
70  uint64_t timeout
71  );
72 
73 int mg_distribute_send(
74  struct mg_distribute_config *cfg,
75  struct rte_mbuf **pkts,
76  struct mg_bitmask* pkts_mask,
77  void **entries
78  );
79 
80 void mg_distribute_handle_timeouts(
81  struct mg_distribute_config *cfg
82  );
83 ]]
84 
85 
86 local mod = {}
87 
88 local mg_distribute = {}
89 mod.mg_distribute = mg_distribute
90 mg_distribute.__index = mg_distribute
91 
92 
93 function mod.createDistributor(socket, entryOffset, nrOutputs, alwaysFlush)
94  socket = socket or select(2, dpdk.getCore())
95  entryOffset = entryOffset or 0
96  if alwaysFlush then
97  alwaysFlush = 1
98  else
99  alwaysFlush = 0
100  end
101 
102  return setmetatable({
103  cfg = ffi.gc(ffi.C.mg_distribute_create(entryOffset, nrOutputs, alwaysFlush), function(self)
104  print "lpm garbage"
105  ffi.C.mg_NOT_YET_IMPLEMENTED(self) -- FIXME
106  end),
107  socket = socket
108  }, mg_distribute)
109 end
110 
111 
112 function mg_distribute:__serialize()
113  return "require 'distribute'; return " .. serpent.addMt(serpent.dumpRaw(self), "require('distribute').mg_distribute"), true
114 end
115 
116 function mg_distribute:send(packets, bitMask, routingEntries)
117  return ffi.C.mg_distribute_send(self.cfg, packets.array, bitMask.bitmask, ffi.cast("void **", routingEntries.array))
118 end
119 
120 function mg_distribute:registerOutput(outputNumber, txQueue, bufferSize, timeout)
121  -- FIXME: is this a good idea, to use uint64_t bit integers in lua??
122  local f_cpu = dpdk.getCyclesFrequency()
123  local cycles_timeout = tonumber(f_cpu * timeout)
124 
125  local portID = txQueue.id
126  local queueID = txQueue.qid
127 
128  print ("register output NR " .. tostring(outputNumber) .. " -> port = " .. tostring(portID) .. " queue = " .. tostring(queueID) .. " timeout = " .. tostring(cycles_timeout))
129  ffi.C.mg_distribute_register_output(self.cfg, outputNumber, portID, queueID, bufferSize, cycles_timeout)
130 end
131 
132 function mg_distribute:handleTimeouts()
133  ffi.C.mg_distribute_handle_timeouts(self.cfg)
134  return
135 end
136 
137 return mod
local ffi
low-level dpdk wrapper
Definition: dpdkc.lua:6
local mod
high-level dpdk wrapper
Definition: dpdk.lua:6
function mod getCyclesFrequency()
get the TSC frequency
local pkt
Module for packets (rte_mbuf)
Definition: packet.lua:20