|
|
|
@ -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, "};" |
|
|
|
|