aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/codegen
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-07-20 16:02:24 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-07-20 16:02:24 -0700
commit33aeabad66e8083d47f47ddc4bafa4483f1585f8 (patch)
tree0394fe35d6f8437da6522860d9726510952aa6ff /tools/codegen
parentb4bb1cdce48abb7492b33cd2dced14689da67e2b (diff)
begin building out histogram support
Diffstat (limited to 'tools/codegen')
-rwxr-xr-xtools/codegen/core/gen_stats_data.py90
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, "};"