import re,bisect,collections,sys exec(open('parse.py').read().split("cpu = []")[0]) # reuse loaders/sym lines=open(sys.argv[1],encoding='utf-8',errors='replace').read().splitlines() # per-sample: t, is main thread in a turn-processing / server / client-update frame? marks=collections.OrderedDict() for l in lines: if not l.startswith('S '): continue p=l.split(' ',4); t=int(p[1]); tid=p[2] if tid!='3568': continue frames=p[4].split(' < |scan| ')[0].split(' < ') if len(p)>4 else [] names_=[sym(f)[0] for f in frames] tags=set() for n in names_: if 'ProcessTurn' in n or 'StrategyServer' in n or 'StrategyNetworkServer' in n or 'RunAI' in n or 'GenerateTurnEvents' in n or 'DispatchTurnResults' in n: tags.add('SERVER') if 'StrategyClient' in n and 'Update' not in n: tags.add('CLIENT') if 'BackgroundWorker' in n or 'BuildBlobMesh' in n: tags.add('MESH') if 'NtWaitForAlertByThreadId' in n: tags.add('dxvkwait') if 'ZwDelayExecution' in n: tags.add('sleep') marks[t]=(tags, names_[0] if names_ else '?', next((n for n in names_ if '(@' in n), '?')) # print timeline of non-render samples prev=None for t,(tags,top,ex) in marks.items(): key=(tuple(sorted(tags))) if 'SERVER' in tags or 'CLIENT' in tags or 'MESH' in tags: print(t, sorted(tags), top, ex)