this repo has no description

rework: process info storage

altagos.dev 1e51f073 15b8533f

verified
+124 -10
+22
.tangled/workflows/build.yaml
··· 1 + when: 2 + - event: ["push", "pull_request"] 3 + branch: ["main"] 4 + - event: ["manual"] 5 + 6 + dependencies: 7 + ## from nixpkgs 8 + nixpkgs: 9 + - curl 10 + - jq 11 + - busybox 12 + 13 + steps: 14 + - name: "Install zig" 15 + command: "./scripts/install-zig.sh" 16 + - name: "Build ReleaseFast" 17 + command: "./zig/zig build -Doptimize=ReleaseFast --summary all" 18 + 19 + clone: 20 + skip: false 21 + depth: 1 22 + submodules: true
+9
.zed/tasks.json
··· 1 + [ 2 + { 3 + "label": "Build ReleaseFast", 4 + "command": "zig build -Doptimize=ReleaseFast --summary all", 5 + "use_new_terminal": false, 6 + "allow_concurrent_runs": false, 7 + "reveal": "always" 8 + } 9 + ]
+2 -2
build.zig.zon
··· 5 5 .minimum_zig_version = "0.15.0-dev.876+8eca338c2", 6 6 .dependencies = .{ 7 7 .args = .{ 8 - .url = "git+https://github.com/ikskuh/zig-args?ref=master#9425b94c103a031777fdd272c555ce93a7dea581", 9 - .hash = "args-0.0.0-CiLiqv_NAAC97fGpk9hS2K681jkiqPsWP6w3ucb_ctGH", 8 + .url = "git+https://github.com/altagos/zig-args?ref=master#2d5a8debad37f8e0afbfcbf9c9b6f4a13a53f6aa", 9 + .hash = "args-0.0.0-CiLiqjHPAAAbcho-tUvfMLs0mFvfzPESWdxHlHQ7Fhmp", 10 10 }, 11 11 }, 12 12 .paths = .{
+49
scripts/install-zig.sh
··· 1 + #!/bin/bash 2 + 3 + JSON=$(curl -s https://ziglang.org/download/index.json) 4 + 5 + # Determine the architecture: 6 + if [ "$(uname -m)" = 'arm64' ] || [ "$(uname -m)" = 'aarch64' ]; then 7 + ZIG_ARCH="aarch64" 8 + else 9 + ZIG_ARCH="x86_64" 10 + fi 11 + 12 + # Determine the operating system: 13 + case "$(uname)" in 14 + Linux) 15 + ZIG_OS="linux" 16 + ;; 17 + Darwin) 18 + ZIG_OS="macos" 19 + ;; 20 + CYGWIN*) 21 + ZIG_OS="windows" 22 + ;; 23 + *) 24 + echo "Unknown OS" 25 + exit 1 26 + ;; 27 + esac 28 + 29 + ZIG_TARGET="$ZIG_ARCH-$ZIG_OS" 30 + 31 + URL=$(echo "$JSON" | jq -r ".master.\"$ZIG_TARGET\".tarball") 32 + EXPECTED_SHA=$(echo "$JSON" | jq -r ".master.\"$ZIG_TARGET\".shasum") 33 + 34 + curl -O "$URL" 35 + 36 + ACTUAL_SHA=$(sha256sum zig*.tar.xz | awk '{print $1}') 37 + if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 38 + echo "SHA checksum verification failed." 39 + echo "Expected: $EXPECTED_SHA" 40 + echo "Actual: $ACTUAL_SHA" 41 + exit 1 42 + fi 43 + 44 + if [ ! -d "zig" ]; then 45 + mkdir zig 46 + fi 47 + 48 + tar -xf zig*.tar.xz -C zig --strip-components=1 49 + rm zig*.tar.xz
+29 -4
src/austin.zig
··· 12 12 tid: usize, 13 13 }; 14 14 15 + pub const ProcessID = usize; 16 + 15 17 pub const Frame = struct { 16 18 module: []const u8 = undefined, 17 19 function: []const u8 = undefined, ··· 35 37 }; 36 38 37 39 pub const Sample = struct { 38 - process: Process, 40 + process: ProcessID, 39 41 frames: []FrameWrapper, 40 42 metric: Metric, 41 43 }; 42 44 43 45 pub const PartialSample = struct { 44 - process: Process, 46 + process: ProcessID, 45 47 frames: []FrameWrapper, 46 48 }; 47 49 ··· 101 103 meta: Metadata = .{}, 102 104 frames: []Frame = undefined, 103 105 samples: []SampleWrapper = undefined, 106 + processes: []Process = undefined, 107 + 104 108 arena: mem.Allocator, 105 109 106 110 pub fn deinit(self: *Profile) void { ··· 120 124 121 125 self.arena.free(self.frames); 122 126 self.arena.free(self.samples); 127 + self.arena.free(self.processes); 123 128 } 124 129 125 130 pub fn getFrame(self: *const Profile, id: FrameID) ?Frame { ··· 153 158 profile: Profile, 154 159 frames: std.ArrayList(Frame), 155 160 samples: std.ArrayList(SampleWrapper), 161 + processes: std.ArrayList(Process), 156 162 157 163 pub fn init(arena: mem.Allocator) !Parser { 158 164 return .{ ··· 160 166 .profile = .{ .arena = arena }, 161 167 .frames = try .initCapacity(arena, 100), 162 168 .samples = try .initCapacity(arena, 1_000), 169 + .processes = try .initCapacity(arena, 1), 163 170 }; 164 171 } 165 172 166 173 pub fn parse(self: *Parser, raw_reader: anytype, progress: *std.Progress.Node) !Profile { 167 174 defer self.samples.deinit(); 168 175 defer self.frames.deinit(); 176 + defer self.processes.deinit(); 169 177 170 178 var buffered_reader = std.io.bufferedReader(raw_reader); 171 179 var reader = buffered_reader.reader(); ··· 223 231 224 232 self.profile.frames = try self.frames.toOwnedSlice(); 225 233 self.profile.samples = try self.samples.toOwnedSlice(); 234 + self.profile.processes = try self.processes.toOwnedSlice(); 226 235 return self.profile; 227 236 } 228 237 ··· 331 340 // TID 332 341 const tid = thread.next() orelse return ParseError.NoTID; 333 342 334 - sample.process = .{ 343 + sample.process = try self.storeProcess(.{ 335 344 .pid = std.fmt.parseUnsigned(usize, pid[1..], 0) catch return ParseError.InvalidPID, 336 345 .iid = std.fmt.parseUnsigned(usize, iid[1..], 0) catch return ParseError.InvalidIID, 337 346 .tid = std.fmt.parseUnsigned(usize, tid, 0) catch return ParseError.InvalidTID, 338 - }; 347 + }); 339 348 340 349 // Frames 341 350 var frames: std.ArrayList(FrameWrapper) = try .initCapacity(self.arena, 1); ··· 397 406 ) catch return ParseError.InvalidLineNumber; 398 407 399 408 return try self.storeFrame(module, function, line_number); 409 + } 410 + 411 + fn storeProcess( 412 + self: *Parser, 413 + process: Process, 414 + ) !ProcessID { 415 + var count: usize = 0; 416 + for (self.processes.items, 0..) |*p, id| { 417 + if (p.pid == process.pid and p.iid == process.iid and p.tid == process.tid) { 418 + return id; 419 + } 420 + count += 1; 421 + } 422 + 423 + try self.processes.append(process); 424 + return count + 1; 400 425 } 401 426 402 427 fn storeFrame(
+12 -3
src/main.zig
··· 59 59 try args.printHelp( 60 60 Options, 61 61 Options.meta.name, 62 - std.io.getStdOut().writer(), 62 + std.fs.File.stderr().deprecatedWriter(), 63 63 ); 64 64 return; 65 65 } ··· 80 80 defer node.end(); 81 81 82 82 if (opts.positionals.len == 0) { 83 - profile = try parser.parse(std.io.getStdIn().reader(), &node); 83 + profile = try parser.parse(std.fs.File.stdin().deprecatedReader(), &node); 84 84 } else { 85 85 const path = std.fs.cwd().realpathAlloc(allocator, opts.positionals[0]) catch |err| { 86 86 std.log.err("Invalid file path ({}): {s}", .{ err, opts.positionals[0] }); ··· 91 91 const file = try std.fs.openFileAbsolute(path, .{}); 92 92 defer file.close(); 93 93 94 - profile = try parser.parse(file.reader(), &node); 94 + profile = try parser.parse(file.deprecatedReader(), &node); 95 95 } 96 96 } 97 97 ··· 102 102 ); 103 103 } 104 104 105 + for (profile.processes, 0..) |*process, id| { 106 + std.log.debug( 107 + "Process ID: {} => {{\n\tPID = {}\n\tIID = {}\n\tTID = {}\n}}\n", 108 + .{ id, process.pid, process.iid, process.tid }, 109 + ); 110 + } 111 + 105 112 std.log.info( 106 113 "num samples: {} - num frames: {} - meta: {}", 107 114 .{ profile.samples.len, profile.frames.len, profile.meta }, 108 115 ); 116 + 117 + while (true) {} 109 118 }
+1 -1
src/util.zig
··· 33 33 break :blk level_text ++ scope_prefix ++ "\x1b[90m \x1b[0m"; 34 34 }; 35 35 36 - const stderr = std.io.getStdErr().writer(); 36 + const stderr = std.fs.File.stderr().deprecatedWriter(); 37 37 var bw = std.io.bufferedWriter(stderr); 38 38 const writer = bw.writer(); 39 39