#!/usr/bin/python3

from bcc import BPF
from time import sleep
import argparse

parser = argparse.ArgumentParser(
	description="Measure time interval between using the sending API for a message and handling it in a gdbus thread in glib",
	formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("interval", nargs="?", default=2,
	help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=-1,
	help="number of outputs")

args = parser.parse_args()
interval = int(args.interval)
loop = 0
count = int(args.count)

b = BPF(src_file="dbus-glib-client-sending.c")

# Setup uprobes

# ****** General
b.attach_uprobe(name="gio-2.0", sym="g_dbus_connection_send_message_unlocked", fn_name="handle_send_message")
b.attach_uprobe(name="gio-2.0", sym="_g_dbus_worker_send_message", fn_name="handle_worker_send_message")
# this uprobe function detects destroying of a message and removes any existing references
b.attach_uprobe(name="gio-2.0", sym="g_dbus_message_finalize", fn_name="handle_message_delete")

# GO!
print("Hit Ctrl-C to end.")

while (1):
	sleep(interval)
	loop = loop + 1
	print("\n%d:" % loop)
	b["timings"].print_log2_hist("us")

	# Kinda debug part, but important - it shows any leftovers in hashmaps.
	# This way, if it shows up, we can tell how bad it is.
	msgs = len(b["msg_sending"].items())

	if msgs > 0:
		print(" containers stats:")
		print('     msg_sending:', msgs)

	if b["count_averages"][1].value > 0:
		print('Average:', (b["count_averages"][0].value // b["count_averages"][1].value) // 1000)

	if count == loop:
		print('Finished')
		break
