diff options
author | Craig Tiller <ctiller@google.com> | 2017-07-20 16:02:24 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2017-07-20 16:02:24 -0700 |
commit | 33aeabad66e8083d47f47ddc4bafa4483f1585f8 (patch) | |
tree | 0394fe35d6f8437da6522860d9726510952aa6ff /tools/codegen | |
parent | b4bb1cdce48abb7492b33cd2dced14689da67e2b (diff) |
begin building out histogram support
Diffstat (limited to 'tools/codegen')
-rwxr-xr-x | tools/codegen/core/gen_stats_data.py | 90 |
1 files changed, 75 insertions, 15 deletions
diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py index bc601a89a7..c56e1f2608 100755 --- a/tools/codegen/core/gen_stats_data.py +++ b/tools/codegen/core/gen_stats_data.py @@ -15,21 +15,70 @@ # limitations under the License. import collections +import ctypes +import math import sys import yaml with open('src/core/lib/debug/stats_data.yaml') as f: attrs = yaml.load(f.read()) -Counter = collections.namedtuple('Counter', 'name') +types = ( + (collections.namedtuple('Counter', 'name'), []), + (collections.namedtuple('Histogram', 'name max buckets'), []), +) -counters = [] +inst_map = dict((t[0].__name__, t[1]) for t in types) + +stats = [] for attr in attrs: - if 'counter' in attr: - counters.append(Counter(name=attr['counter'])) - else: - print 'Error: bad attr %r' % attr + found = False + for t, lst in types: + t_name = t.__name__.lower() + if t_name in attr: + name = attr[t_name] + del attr[t_name] + lst.append(t(name=name, **attr)) + found = True + break + assert found, "Bad decl: %s" % attr + +def dbl2u64(d): + return ctypes.c_ulonglong.from_buffer(ctypes.c_double(d)).value + +def shift_works(mapped_bounds, shift_bits): + for a, b in zip(mapped_bounds, mapped_bounds[1:]): + if (a >> shift_bits) == (b >> shift_bits): + return False + return True + +def find_max_shift(mapped_bounds): + for shift_bits in reversed(range(0,64)): + if shift_works(mapped_bounds, shift_bits): + return shift_bits + return -1 + +def gen_bucket_code(histogram): + bounds = [0, 1] + done_trivial = False + done_unmapped = False + first_nontrivial = None + first_unmapped = None + while len(bounds) < histogram.buckets: + mul = math.pow(float(histogram.max) / bounds[-1], + 1.0 / (histogram.buckets - len(bounds))) + nextb = bounds[-1] * mul + if nextb < bounds[-1] + 1: + nextb = bounds[-1] + 1 + elif not done_trivial: + done_trivial = True + first_nontrivial = len(bounds) + bounds.append(nextb) + if done_trivial: + code_bounds = [dbl2u64(x - first_nontrivial) for x in bounds] + shift_bits = find_max_shift(code_bounds[first_nontrivial:]) + print first_nontrivial, shift_bits, bounds, [hex(x >> shift_bits) for x in code_bounds[first_nontrivial:]] # utility: print a big comment block into a set of files def put_banner(files, banner): @@ -62,14 +111,25 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H: print >>H, "#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H" print >>H - print >>H, "typedef enum {" - for ctr in counters: - print >>H, " GRPC_STATS_COUNTER_%s," % ctr.name.upper() - print >>H, " GRPC_STATS_COUNTER_COUNT" - print >>H, "} grpc_stats_counters;" - - for ctr in counters: - print >>H, "#define GRPC_STATS_INC_%s(exec_ctx) GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_%s)" % (ctr.name.upper(), ctr.name.upper()) + for typename, instances in sorted(inst_map.items()): + print >>H, "typedef enum {" + for inst in instances: + print >>H, " GRPC_STATS_%s_%s," % (typename.upper(), inst.name.upper()) + print >>H, " GRPC_STATS_%s_COUNT" % (typename.upper()) + print >>H, "} grpc_stats_%ss;" % (typename.lower()) + + for ctr in inst_map['Counter']: + print >>H, ("#define GRPC_STATS_INC_%s(exec_ctx) " + + "GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_%s)") % ( + ctr.name.upper(), ctr.name.upper()) + for histogram in inst_map['Histogram']: + print >>H, ("#define GRPC_STATS_INC_%s(exec_ctx, value) " + + "GRPC_STATS_INC_HISTOGRAM((exec_ctx), " + + "GRPC_STATS_HISTOGRAM_%s," + + "%s)") % ( + histogram.name.upper(), + histogram.name.upper(), + gen_bucket_code(histogram)) print >>H, "extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT];" @@ -97,6 +157,6 @@ with open('src/core/lib/debug/stats_data.c', 'w') as C: print >>C, "#include \"src/core/lib/debug/stats_data.h\"" print >>C, "const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = {"; - for ctr in counters: + for ctr in inst_map['Counter']: print >>C, " \"%s\"," % ctr.name print >>C, "};" |