|
Packit Service |
f88c7f |
#!/usr/bin/python
|
|
Packit Service |
f88c7f |
# Copyright 2017 Red Hat, Inc.
|
|
Packit Service |
f88c7f |
#
|
|
Packit Service |
f88c7f |
# Author: Jan Pokorny <jpokorny@redhat.com>
|
|
Packit Service |
f88c7f |
#
|
|
Packit Service |
f88c7f |
# This file is part of libqb.
|
|
Packit Service |
f88c7f |
#
|
|
Packit Service |
f88c7f |
# libqb is free software: you can redistribute it and/or modify
|
|
Packit Service |
f88c7f |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
f88c7f |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit Service |
f88c7f |
# (at your option) any later version.
|
|
Packit Service |
f88c7f |
#
|
|
Packit Service |
f88c7f |
# libqb is distributed in the hope that it will be useful,
|
|
Packit Service |
f88c7f |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f88c7f |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
f88c7f |
# GNU Lesser General Public License for more details.
|
|
Packit Service |
f88c7f |
#
|
|
Packit Service |
f88c7f |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
f88c7f |
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
# expected to work with both Python 2.6+/3+
|
|
Packit Service |
f88c7f |
from __future__ import print_function
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
"""Generate callsite-heavy logging client so as to evaluate use of resources"""
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
from getopt import GetoptError, getopt
|
|
Packit Service |
f88c7f |
from math import ceil, floor, log10
|
|
Packit Service |
f88c7f |
#from pprint import pprint
|
|
Packit Service |
f88c7f |
#from random import shuffle
|
|
Packit Service |
f88c7f |
from sys import argv, exit
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
def die(*args, **kwargs):
|
|
Packit Service |
f88c7f |
print(*args, **kwargs)
|
|
Packit Service |
f88c7f |
exit(1)
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
def list_to_c_source(worklist, fnc_prefix, width=0):
|
|
Packit Service |
f88c7f |
ret = []
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
while worklist:
|
|
Packit Service |
f88c7f |
item = worklist.pop()
|
|
Packit Service |
f88c7f |
if type(item) is list:
|
|
Packit Service |
f88c7f |
head, children = item
|
|
Packit Service |
f88c7f |
if type(children) is list:
|
|
Packit Service |
f88c7f |
for i, ci in enumerate(children):
|
|
Packit Service |
f88c7f |
ret += list_to_c_source([ci], fnc_prefix, width)
|
|
Packit Service |
f88c7f |
if type(ci) is list:
|
|
Packit Service |
f88c7f |
children[i] = ci[0]
|
|
Packit Service |
f88c7f |
if type(children[i]) is list:
|
|
Packit Service |
f88c7f |
children[i] = children[i][0]
|
|
Packit Service |
f88c7f |
else:
|
|
Packit Service |
f88c7f |
head = item
|
|
Packit Service |
f88c7f |
children = []
|
|
Packit Service |
f88c7f |
if type(head) is not list:
|
|
Packit Service |
f88c7f |
head = [head]
|
|
Packit Service |
f88c7f |
ret += ["static void {0}_{1:0{2}}(int doit) {{"
|
|
Packit Service |
f88c7f |
.format(fnc_prefix, head[0], width),
|
|
Packit Service |
f88c7f |
"\tif (!doit) return;"]
|
|
Packit Service |
f88c7f |
ret += ["\tqb_log(LOG_ERR, \"{0:0{1}}\");".format(i, width)
|
|
Packit Service |
f88c7f |
for i in head]
|
|
Packit Service |
f88c7f |
ret += ["\t{0}_{1:0{2}}(doit);".format(fnc_prefix, i, width)
|
|
Packit Service |
f88c7f |
for i in reversed(children)]
|
|
Packit Service |
f88c7f |
ret += ["}"]
|
|
Packit Service |
f88c7f |
return ret
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
def main(opts, args):
|
|
Packit Service |
f88c7f |
FNC_PREFIX = "fnc"
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
try:
|
|
Packit Service |
f88c7f |
CALLSITE_COUNT = int(opts["CALLSITE_COUNT"])
|
|
Packit Service |
f88c7f |
if not 0 < CALLSITE_COUNT < 10 ** 6: raise ValueError
|
|
Packit Service |
f88c7f |
except ValueError:
|
|
Packit Service |
f88c7f |
die("callsites count can only be a number x, 0 < x < 1e6")
|
|
Packit Service |
f88c7f |
try:
|
|
Packit Service |
f88c7f |
BRANCHING_FACTOR = int(opts["BRANCHING_FACTOR"])
|
|
Packit Service |
f88c7f |
if not 0 < BRANCHING_FACTOR < 10 ** 3: raise ValueError
|
|
Packit Service |
f88c7f |
except ValueError:
|
|
Packit Service |
f88c7f |
die("branching factor can only be a number x, 0 < x < 1000")
|
|
Packit Service |
f88c7f |
try:
|
|
Packit Service |
f88c7f |
CALLSITES_PER_FNC = int(opts["CALLSITES_PER_FNC"])
|
|
Packit Service |
f88c7f |
if not 0 < CALLSITES_PER_FNC < 10 ** 3: raise ValueError
|
|
Packit Service |
f88c7f |
except ValueError:
|
|
Packit Service |
f88c7f |
die("callsites-per-fnc count can only be a number x, 0 < x < 1000")
|
|
Packit Service |
f88c7f |
try:
|
|
Packit Service |
f88c7f |
ROUND_COUNT = int(opts["ROUND_COUNT"])
|
|
Packit Service |
f88c7f |
if not 0 < ROUND_COUNT < 10 ** 6: raise ValueError
|
|
Packit Service |
f88c7f |
except ValueError:
|
|
Packit Service |
f88c7f |
die("round count can only be a number x, 0 < x < 1e6")
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
worklist, worklist_len = list(range(0, CALLSITE_COUNT)), CALLSITE_COUNT
|
|
Packit Service |
f88c7f |
#shuffle(worklist)
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
#pprint(worklist)
|
|
Packit Service |
f88c7f |
first = worklist[0]
|
|
Packit Service |
f88c7f |
while worklist_len > 1:
|
|
Packit Service |
f88c7f |
item = worklist.pop(); worklist_len -= 1
|
|
Packit Service |
f88c7f |
reminder = worklist_len % CALLSITES_PER_FNC
|
|
Packit Service |
f88c7f |
parent = (worklist_len - reminder if reminder
|
|
Packit Service |
f88c7f |
else (worklist_len // CALLSITES_PER_FNC - 1)
|
|
Packit Service |
f88c7f |
// BRANCHING_FACTOR * CALLSITES_PER_FNC)
|
|
Packit Service |
f88c7f |
#print("parent {0} (len={1})".format(parent, worklist_len))
|
|
Packit Service |
f88c7f |
if type(worklist[parent]) is not list:
|
|
Packit Service |
f88c7f |
worklist[parent] = [worklist[parent], []]
|
|
Packit Service |
f88c7f |
if not(reminder):
|
|
Packit Service |
f88c7f |
worklist[parent][1].append(item) # reverses the order!
|
|
Packit Service |
f88c7f |
#worklist[parent][1][:0] = [item]
|
|
Packit Service |
f88c7f |
else:
|
|
Packit Service |
f88c7f |
if type(worklist[parent][0]) is not list:
|
|
Packit Service |
f88c7f |
worklist[parent][0] = [worklist[parent][0]]
|
|
Packit Service |
f88c7f |
#worklist[parent][0].append(item) # reverses the order
|
|
Packit Service |
f88c7f |
worklist[parent][0][1:1] = [item] # parent itself the 1st element
|
|
Packit Service |
f88c7f |
#pprint(worklist)
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
width = int(floor(log10(CALLSITE_COUNT))) + 1
|
|
Packit Service |
f88c7f |
print('\n'.join([
|
|
Packit Service |
f88c7f |
"/* compile with -lqb OR with -DQB_KILL_ATTRIBUTE_SECTION -l:libqb.so.0 */",
|
|
Packit Service |
f88c7f |
"#include <qb/qblog.h>",
|
|
Packit Service |
f88c7f |
] + list_to_c_source(worklist, FNC_PREFIX, width) + [
|
|
Packit Service |
f88c7f |
"int main(int argc, char *argv[]) {",
|
|
Packit Service |
f88c7f |
"\tqb_log_init(\"log_gen_test\", LOG_DAEMON, LOG_INFO);",
|
|
Packit Service |
f88c7f |
"\tqb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);",
|
|
Packit Service |
f88c7f |
"\tqb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, \"*\", LOG_ERR);",
|
|
Packit Service |
f88c7f |
"\tqb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);",
|
|
Packit Service |
f88c7f |
"\tfor (int i = 0; i < {0}; i++) {{".format(ROUND_COUNT),
|
|
Packit Service |
f88c7f |
"\t\t{0}_{1:0{2}}(argc);".format(FNC_PREFIX, first, width),
|
|
Packit Service |
f88c7f |
"\t}",
|
|
Packit Service |
f88c7f |
"\tqb_log_fini();",
|
|
Packit Service |
f88c7f |
"\treturn !argc;",
|
|
Packit Service |
f88c7f |
"}"
|
|
Packit Service |
f88c7f |
]
|
|
Packit Service |
f88c7f |
))
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
if __name__ == '__main__':
|
|
Packit Service |
f88c7f |
# Full trees for CALLSITES_PER_FNC == 1 (can be trivially extrapolated):
|
|
Packit Service |
f88c7f |
# BF = 2 (binary trees)
|
|
Packit Service |
f88c7f |
# --> C = 7 (3 steps), 15 (4 steps), ..., 127 (6 steps), ...
|
|
Packit Service |
f88c7f |
# (see https://en.wikipedia.org/wiki/Binary_tree#Properties_of_binary_trees)
|
|
Packit Service |
f88c7f |
# BF = 3 (ternary trees)
|
|
Packit Service |
f88c7f |
# --> C = 13 (3 steps), 40 (4 steps), ..., 1093 (6 steps), ...
|
|
Packit Service |
f88c7f |
# (see https://en.wikipedia.org/wiki/Ternary_tree#Properties_of_ternary_trees)
|
|
Packit Service |
f88c7f |
# ...
|
|
Packit Service |
f88c7f |
BRANCHING_FACTOR = 3
|
|
Packit Service |
f88c7f |
CALLSITES_PER_FNC = 10
|
|
Packit Service |
f88c7f |
CALLSITE_COUNT = 3640
|
|
Packit Service |
f88c7f |
ROUND_COUNT = 1000
|
|
Packit Service |
f88c7f |
try:
|
|
Packit Service |
f88c7f |
opts, args = getopt(argv[1:],
|
|
Packit Service |
f88c7f |
"hc:b:f:r:",
|
|
Packit Service |
f88c7f |
("help", "callsite-count=", "branching-factor=",
|
|
Packit Service |
f88c7f |
"callsites-per-fnc=", "round-count="))
|
|
Packit Service |
f88c7f |
for o, a in opts:
|
|
Packit Service |
f88c7f |
if o in ("-h", "--help"):
|
|
Packit Service |
f88c7f |
raise GetoptError("__justhelp__")
|
|
Packit Service |
f88c7f |
elif o in ("-c", "--callsite-count"): CALLSITE_COUNT = a
|
|
Packit Service |
f88c7f |
elif o in ("-b", "--branching-factor"): BRANCHING_FACTOR = a
|
|
Packit Service |
f88c7f |
elif o in ("-f", "--callsites-per-fnc"): CALLSITES_PER_FNC = a
|
|
Packit Service |
f88c7f |
elif o in ("-r", "--round-count"): ROUND_COUNT = a
|
|
Packit Service |
f88c7f |
except GetoptError as err:
|
|
Packit Service |
f88c7f |
if err.msg != "__justhelp__":
|
|
Packit Service |
f88c7f |
print(str(err))
|
|
Packit Service |
f88c7f |
print("Usage:\n{0} -h|--help\n"
|
|
Packit Service |
f88c7f |
"{0} [-c X|--callsite-count={CALLSITE_COUNT}]"
|
|
Packit Service |
f88c7f |
" [-b Y|--branching-factor={BRANCHING_FACTOR}]\n"
|
|
Packit Service |
f88c7f |
"{1:{2}} [-f Z|--callsites-per-fnc={CALLSITES_PER_FNC}]"
|
|
Packit Service |
f88c7f |
" [-r R|--round-count={ROUND_COUNT}]"
|
|
Packit Service |
f88c7f |
.format(argv[0], '', len(argv[0]), **locals()))
|
|
Packit Service |
f88c7f |
exit(0 if err.msg == "__justhelp__" else 2)
|
|
Packit Service |
f88c7f |
|
|
Packit Service |
f88c7f |
opts = dict(CALLSITE_COUNT=CALLSITE_COUNT,
|
|
Packit Service |
f88c7f |
BRANCHING_FACTOR=BRANCHING_FACTOR,
|
|
Packit Service |
f88c7f |
CALLSITES_PER_FNC=CALLSITES_PER_FNC,
|
|
Packit Service |
f88c7f |
ROUND_COUNT=ROUND_COUNT)
|
|
Packit Service |
f88c7f |
main(opts, args)
|