|
|
|
#!/bin/bash
|
|
|
|
cd "$(dirname "$(dirname $0)")"
|
|
|
|
|
|
|
|
node=${NODE:-./node}
|
|
|
|
|
|
|
|
name=${NAME:-stacks}
|
|
|
|
|
|
|
|
if type sysctl &>/dev/null; then
|
|
|
|
# darwin and linux
|
|
|
|
sudo sysctl -w net.inet.ip.portrange.first=12000
|
|
|
|
sudo sysctl -w net.inet.tcp.msl=1000
|
|
|
|
sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000
|
|
|
|
elif type /usr/sbin/ndd &>/dev/null; then
|
|
|
|
# sunos
|
|
|
|
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000
|
|
|
|
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535
|
|
|
|
/usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152
|
|
|
|
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576
|
|
|
|
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576
|
|
|
|
fi
|
|
|
|
|
|
|
|
ulimit -n 100000
|
|
|
|
$node benchmark/http_simple.js &
|
|
|
|
nodepid=$!
|
|
|
|
echo "node pid = $nodepid"
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
# has to stay alive until dtrace exits
|
|
|
|
dtrace -n 'profile-97/pid == '$nodepid' && arg1/{ @[jstack(150, 8000)] = count(); } tick-60s { exit(0); }' \
|
|
|
|
| grep -v _ZN2v88internalL21Builtin_HandleApiCallENS0_12_GLOBAL__N_116BuiltinA \
|
|
|
|
> "$name".src &
|
|
|
|
|
|
|
|
dtracepid=$!
|
|
|
|
|
|
|
|
echo "dtrace pid = $dtracepid"
|
|
|
|
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
test () {
|
|
|
|
c=$1
|
|
|
|
t=$2
|
|
|
|
l=$3
|
|
|
|
k=$4
|
|
|
|
ab $k -t 10 -c $c http://127.0.0.1:8000/$t/$l \
|
|
|
|
2>&1 | grep Req
|
|
|
|
}
|
|
|
|
|
|
|
|
#test 100 bytes 1024
|
|
|
|
#test 10 bytes 100 -k
|
|
|
|
#test 100 bytes 1024 -k
|
|
|
|
#test 100 bytes 1024 -k
|
|
|
|
#test 100 bytes 1024 -k
|
|
|
|
|
|
|
|
echo 'Keep going until dtrace stops listening...'
|
|
|
|
while pargs $dtracepid &>/dev/null; do
|
|
|
|
test 100 bytes ${LENGTH:-1} -k
|
|
|
|
done
|
|
|
|
|
|
|
|
kill $nodepid
|
|
|
|
|
|
|
|
echo 'Turn the stacks into a svg'
|
|
|
|
stackvis dtrace flamegraph-svg < "$name".src > "$name".raw.svg
|
|
|
|
|
|
|
|
echo 'Prune tiny stacks out of the graph'
|
|
|
|
node -e '
|
|
|
|
var infile = process.argv[1];
|
|
|
|
var outfile = process.argv[2];
|
|
|
|
var output = "";
|
|
|
|
var fs = require("fs");
|
|
|
|
var input = fs.readFileSync(infile, "utf8");
|
|
|
|
|
|
|
|
input = input.split("id=\"details\" > </text>");
|
|
|
|
var head = input.shift() + "id=\"details\" > </text>";
|
|
|
|
input = input.join("id=\"details\" > </text>");
|
|
|
|
|
|
|
|
var tail = "</svg>";
|
|
|
|
input = input.split("</svg>")[0];
|
|
|
|
|
|
|
|
var minyKept = Infinity;
|
|
|
|
var minyOverall = Infinity;
|
|
|
|
var rects = input.trim().split(/\n/).filter(function(rect) {
|
|
|
|
var my = rect.match(/y="([0-9\.]+)"/);
|
|
|
|
|
|
|
|
if (!my)
|
|
|
|
return false;
|
|
|
|
var y = +my[1];
|
|
|
|
if (!y)
|
|
|
|
return false;
|
|
|
|
minyOverall = Math.min(minyOverall, y);
|
|
|
|
|
|
|
|
// pluck off everything that will be less than one pixel.
|
|
|
|
var mw = rect.match(/width="([0-9\.]+)"/)
|
|
|
|
if (mw) {
|
|
|
|
var width = +mw[1];
|
|
|
|
if (!(width >= 1))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
minyKept = Math.min(minyKept, y);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
// move everything up to the top of the page.
|
|
|
|
var ydiff = minyKept - minyOverall;
|
|
|
|
rects = rects.map(function(rect) {
|
|
|
|
var my = rect.match(/y="([0-9\.]+)"/);
|
|
|
|
var y = +my[1];
|
|
|
|
var newy = y - ydiff;
|
|
|
|
rect = rect.replace(/y="([0-9\.]+)"/, "y=\"" + newy + "\"");
|
|
|
|
return rect;
|
|
|
|
});
|
|
|
|
|
|
|
|
fs.writeFileSync(outfile, head + "\n" + rects.join("\n") + "\n" + tail);
|
|
|
|
' "$name".raw.svg "$name".svg
|
|
|
|
|
|
|
|
echo ''
|
|
|
|
echo 'done. Results in '"$name"'.svg'
|