Skip to content

Commit c77d919

Browse files
committed
feat: add analysis instrument
1 parent 3f1a166 commit c77d919

File tree

5 files changed

+148
-18
lines changed

5 files changed

+148
-18
lines changed

src/instruments/analysis.zig

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const std = @import("std");
2+
const runner_fifo = @import("../runner_fifo.zig");
3+
const shared = @import("../shared.zig");
4+
5+
pub const AnalysisInstrument = struct {
6+
fifo: runner_fifo.RunnerFifo,
7+
8+
const Self = @This();
9+
10+
pub fn init(allocator: std.mem.Allocator) !Self {
11+
var fifo = try runner_fifo.RunnerFifo.init(allocator);
12+
13+
// Get the instrumentation mode from the runner
14+
const mode = fifo.get_integration_mode() catch |err| {
15+
fifo.deinit();
16+
return err;
17+
};
18+
19+
// Only accept if the runner is in Analysis mode
20+
if (mode != .Analysis) {
21+
fifo.deinit();
22+
return error.NotAnalysisMode;
23+
}
24+
25+
return Self{ .fifo = fifo };
26+
}
27+
28+
pub fn deinit(self: *Self) void {
29+
self.fifo.deinit();
30+
}
31+
32+
pub fn send_version(self: *Self, protocol_version: u64) !void {
33+
try self.fifo.send_version(protocol_version);
34+
}
35+
36+
pub fn start_benchmark(self: *Self) !void {
37+
try self.fifo.start_benchmark();
38+
}
39+
40+
pub fn stop_benchmark(self: *Self) !void {
41+
try self.fifo.stop_benchmark();
42+
}
43+
44+
pub fn set_executed_benchmark(self: *Self, pid: u32, uri: [*c]const u8) !void {
45+
try self.fifo.set_executed_benchmark(pid, uri);
46+
}
47+
48+
pub fn set_integration(self: *Self, name: [*c]const u8, version: [*c]const u8) !void {
49+
try self.fifo.set_integration(name, version);
50+
}
51+
52+
pub fn add_marker(self: *Self, pid: u32, marker: shared.MarkerType) !void {
53+
try self.fifo.add_marker(pid, marker);
54+
}
55+
};

src/instruments/perf.zig

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,55 @@
11
const std = @import("std");
2-
const fifo = @import("../fifo.zig");
3-
const shared = @import("../shared.zig");
42
const runner_fifo = @import("../runner_fifo.zig");
3+
const shared = @import("../shared.zig");
4+
5+
pub const PerfInstrument = struct {
6+
fifo: runner_fifo.RunnerFifo,
7+
8+
const Self = @This();
9+
10+
pub fn init(allocator: std.mem.Allocator) !Self {
11+
var fifo = try runner_fifo.RunnerFifo.init(allocator);
12+
13+
// Get the instrumentation mode from the runner
14+
const mode = fifo.get_integration_mode() catch |err| {
15+
fifo.deinit();
16+
return err;
17+
};
18+
19+
// Only accept if the runner is in Perf mode
20+
if (mode != .Perf) {
21+
fifo.deinit();
22+
return error.NotPerfMode;
23+
}
24+
25+
return Self{ .fifo = fifo };
26+
}
27+
28+
pub fn deinit(self: *Self) void {
29+
self.fifo.deinit();
30+
}
31+
32+
pub fn send_version(self: *Self, protocol_version: u64) !void {
33+
try self.fifo.send_version(protocol_version);
34+
}
35+
36+
pub fn start_benchmark(self: *Self) !void {
37+
try self.fifo.start_benchmark();
38+
}
39+
40+
pub fn stop_benchmark(self: *Self) !void {
41+
try self.fifo.stop_benchmark();
42+
}
43+
44+
pub fn set_executed_benchmark(self: *Self, pid: u32, uri: [*c]const u8) !void {
45+
try self.fifo.set_executed_benchmark(pid, uri);
46+
}
47+
48+
pub fn set_integration(self: *Self, name: [*c]const u8, version: [*c]const u8) !void {
49+
try self.fifo.set_integration(name, version);
50+
}
551

6-
pub const PerfInstrument = runner_fifo.RunnerFifo;
52+
pub fn add_marker(self: *Self, pid: u32, marker: shared.MarkerType) !void {
53+
try self.fifo.add_marker(pid, marker);
54+
}
55+
};

src/instruments/root.zig

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
11
const std = @import("std");
2-
const builtin = @import("builtin");
32
const perf = @import("perf.zig");
3+
const analysis = @import("analysis.zig");
44
const valgrind = @import("valgrind.zig");
55
const shared = @import("../shared.zig");
66
const ValgrindInstrument = valgrind.ValgrindInstrument;
7+
const PerfInstrument = perf.PerfInstrument;
8+
const AnalysisInstrument = analysis.AnalysisInstrument;
79

810
pub const InstrumentHooks = union(enum) {
911
valgrind: ValgrindInstrument,
10-
perf: perf.PerfInstrument,
12+
perf: PerfInstrument,
13+
analysis: AnalysisInstrument,
1114
none: void,
1215

1316
const Self = @This();
1417

1518
pub fn init(allocator: std.mem.Allocator) !Self {
16-
if (ValgrindInstrument.is_instrumented()) {
17-
return Self{ .valgrind = ValgrindInstrument.init(allocator) };
18-
}
19+
if (ValgrindInstrument.init(allocator)) |valgrind_inst| {
20+
return Self{ .valgrind = valgrind_inst };
21+
} else |_| {}
1922

20-
var perf_inst = perf.PerfInstrument.init(allocator) catch {
21-
return Self{ .none = {} };
22-
};
23-
if (perf_inst.is_instrumented()) {
23+
if (AnalysisInstrument.init(allocator)) |analysis_inst| {
24+
return Self{ .analysis = analysis_inst };
25+
} else |_| {}
26+
27+
if (PerfInstrument.init(allocator)) |perf_inst| {
2428
return Self{ .perf = perf_inst };
25-
}
29+
} else |_| {}
2630

2731
return Self{ .none = {} };
2832
}
@@ -31,17 +35,16 @@ pub const InstrumentHooks = union(enum) {
3135
switch (self.*) {
3236
.valgrind => {},
3337
.perf => self.perf.deinit(),
38+
.analysis => self.analysis.deinit(),
3439
.none => {},
3540
}
3641
}
3742

3843
pub inline fn is_instrumented(self: *Self) bool {
3944
return switch (self.*) {
4045
.valgrind => ValgrindInstrument.is_instrumented(),
41-
.perf => |perf_inst| {
42-
var mutable_perf = perf_inst;
43-
return mutable_perf.is_instrumented();
44-
},
46+
.perf => true,
47+
.analysis => true,
4548
.none => false,
4649
};
4750
}
@@ -51,6 +54,8 @@ pub const InstrumentHooks = union(enum) {
5154
return self.perf.start_benchmark();
5255
} else if (self.* == .valgrind) {
5356
return ValgrindInstrument.start_benchmark();
57+
} else if (self.* == .analysis) {
58+
return self.analysis.start_benchmark();
5459
}
5560
}
5661

@@ -59,13 +64,16 @@ pub const InstrumentHooks = union(enum) {
5964
return ValgrindInstrument.stop_benchmark();
6065
} else if (self.* == .perf) {
6166
return self.perf.stop_benchmark();
67+
} else if (self.* == .analysis) {
68+
return self.analysis.stop_benchmark();
6269
}
6370
}
6471

6572
pub inline fn set_executed_benchmark(self: *Self, pid: u32, uri: [*c]const u8) !void {
6673
switch (self.*) {
6774
.valgrind => ValgrindInstrument.set_executed_benchmark(pid, uri),
6875
.perf => try self.perf.set_executed_benchmark(pid, uri),
76+
.analysis => try self.analysis.set_executed_benchmark(pid, uri),
6977
.none => {},
7078
}
7179
}
@@ -74,13 +82,16 @@ pub const InstrumentHooks = union(enum) {
7482
switch (self.*) {
7583
.valgrind => try self.valgrind.set_integration(name, version),
7684
.perf => try self.perf.set_integration(name, version),
85+
.analysis => try self.analysis.set_integration(name, version),
7786
.none => {},
7887
}
7988
}
8089

8190
pub inline fn add_marker(self: *Self, pid: u32, marker: shared.MarkerType) !void {
8291
if (self.* == .perf) {
8392
return self.perf.add_marker(pid, marker);
93+
} else if (self.* == .analysis) {
94+
return self.analysis.add_marker(pid, marker);
8495
}
8596
}
8697
};

src/instruments/valgrind.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ pub const ValgrindInstrument = struct {
66
allocator: std.mem.Allocator,
77
const Self = @This();
88

9-
pub fn init(allocator: std.mem.Allocator) Self {
9+
pub fn init(allocator: std.mem.Allocator) !Self {
10+
if (!ValgrindInstrument.is_instrumented()) {
11+
return error.NotInstrumented;
12+
}
13+
1014
return Self{
1115
.allocator = allocator,
1216
};

src/runner_fifo.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ pub const RunnerFifo = struct {
9191
try self.writer.sendCmd(fifo.Command{ .SetVersion = protocol_version });
9292
try self.reader.waitForAck(null);
9393
}
94+
95+
pub fn get_integration_mode(self: *Self) !shared.IntegrationMode {
96+
try self.send_cmd(fifo.Command.GetIntegrationMode);
97+
const response = try self.reader.waitForResponse(null);
98+
defer response.deinit(self.allocator);
99+
100+
if (response == .IntegrationModeResponse) {
101+
return response.IntegrationModeResponse;
102+
}
103+
return error.UnexpectedResponse;
104+
}
94105
};
95106

96107
test "test runner fifo" {

0 commit comments

Comments
 (0)