MoonGen
 All Files Functions Variables Pages
main.lua
Go to the documentation of this file.
1 ---------------------------------
2 --- @file main.lua
3 --- @brief Main ...
4 --- @todo TODO docu
5 ---------------------------------
6 
7 -- globally available utility functions
8 require "utils"
9 -- all available headers, packets, ... and their utility functions
10 require "proto.proto"
11 
12 local dpdk = require "dpdk"
13 local dpdkc = require "dpdkc"
14 local dev = require "device"
15 local stp = require "StackTracePlus"
16 local ffi = require "ffi"
17 local memory = require "memory"
18 local serpent = require "Serpent"
19 
20 -- TODO: add command line switches for this and other luajit-debugging features
21 --require("jit.v").on()
22 
23 local function getStackTrace(err)
24  printf("[ERROR] Lua error in task %s", MOONGEN_TASK_NAME)
25  print(stp.stacktrace(err, 2))
26 end
27 
28 local function run(file, ...)
29  local script, err = loadfile(file)
30  if not script then
31  error(err)
32  end
33  xpcall(script, getStackTrace, ...)
34 end
35 
36 local function parseCommandLineArgs(...)
37  local args = { ... }
38  for i, v in ipairs(args) do
39  -- is it just a simple number?
40  if tonumber(v) then
41  v = tonumber(v)
42  end
43  -- currently not supported as we can't pass structs to slaves
44  -- ip?
45  -- local ip = parseIPAddress(v)
46  -- if ip then
47  -- v = ip
48  -- end
49  args[i] = v
50  end
51  return args
52 end
53 
54 local function master(_, file, ...)
55  MOONGEN_TASK_NAME = "master"
56  if not dpdk.init() then
57  print("Could not initialize DPDK")
58  return
59  end
60  local devices = dev.getDevices()
61  printf("Found %d usable devices:", #devices)
62  for _, device in ipairs(devices) do
63  printf(" Device %d: %s (%s)", device.id, device.mac, device.name)
64  end
65  dpdk.userScript = file -- needs to be passed to slave cores
66  local args = parseCommandLineArgs(...)
67  arg = args -- for cliargs in busted
68  run(file) -- should define a global called "master"
69  xpcall(_G["master"], getStackTrace, unpack(args))
70  -- exit program once the master task finishes
71  -- it is up to the user program to wait for slaves to finish, e.g. by calling dpdk.waitForSlaves()
72 end
73 
74 local function slave(taskId, userscript, args)
75  -- must be done before parsing the args as they might rely on deserializers defined in the script
76  run(userscript)
77  args = loadstring(args)()
78  func = args[1]
79  if func == "master" then
80  print("[WARNING] Calling master as slave. This is probably a bug.")
81  end
82  if not _G[func] then
83  errorf("slave function %s not found", func)
84  end
85  --require("jit.p").start("l")
86  --require("jit.dump").on()
87  MOONGEN_TASK_NAME = func
88  MOONGEN_TASK_ID = taskId
89  -- decode args
90  local results = { select(2, xpcall(_G[func], getStackTrace, select(2, unpackAll(args)))) }
91  local vals = serpent.dump(results)
92  local buf = ffi.new("char[?]", #vals + 1)
93  ffi.copy(buf, vals)
94  dpdkc.store_result(taskId, buf)
95  local ok, err = pcall(dev.reclaimTxBuffers)
96  if ok then
97  memory.freeMemPools()
98  else
99  printf("Could not reclaim tx memory: %s", err)
100  end
101  --require("jit.p").stop()
102 end
103 
104 function main(task, ...)
105  (task == "master" and master or slave)(...)
106 end
107 
function mod waitForSlaves()
waits until all slave cores have finished their jobs
local ffi
low-level dpdk wrapper
Definition: dpdkc.lua:6
function parseIPAddress(ip)
Parse a string to an IP address.
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct.
function printf(str,...)
Print a formatted string.
function mod init()
Inits DPDK. Called by MoonGen on startup.
function ip4Addr add(val)
Add a number to an IPv4 address in-place.
function mod stop()
request all tasks to exit
local ip
IP4 protocol constants.
Definition: ip4.lua:25
function errorf(str,...)
Print a formatted error string.
function mod freeMemPools()
Free all memory pools owned by this task.