authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2025-08-25 20:30:20+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2025-08-26 09:39:09+02:00
log6d4dbf05effa3afeb650aeea17683d5de4e6429c
tree29458c85d0cb2cd28a48c2c7f0c47d07222f978b
parent3e77317261e3da50ac55be0c14bc00192ee93166
signaturelock-open Commit is signed but in an unrecognized format.

Compilation: use std.Deque

And delete DeprecatedLinearFifo from the source tree.

3 files changed, 22 insertions(+), 192 deletions(-)

lib/std/deque.zig+1-1
...@@ -143,7 +143,7 @@ pub fn Deque(comptime T: type) type {...@@ -143,7 +143,7 @@ pub fn Deque(comptime T: type) type {
143 deque.len += 1;143 deque.len += 1;
144 }144 }
145145
146 /// Add one item to the front of the deque.146 /// Add one item to the back of the deque.
147 ///147 ///
148 /// Invalidates element pointers if additional memory is needed.148 /// Invalidates element pointers if additional memory is needed.
149 pub fn pushBack(deque: *Self, gpa: Allocator, item: T) error{OutOfMemory}!void {149 pub fn pushBack(deque: *Self, gpa: Allocator, item: T) error{OutOfMemory}!void {
src/Compilation.zig+21-22
...@@ -45,8 +45,6 @@ const Builtin = @import("Builtin.zig");...@@ -45,8 +45,6 @@ const Builtin = @import("Builtin.zig");
45const LlvmObject = @import("codegen/llvm.zig").Object;45const LlvmObject = @import("codegen/llvm.zig").Object;
46const dev = @import("dev.zig");46const dev = @import("dev.zig");
4747
48const DeprecatedLinearFifo = @import("deprecated.zig").LinearFifo;
49
50pub const Config = @import("Compilation/Config.zig");48pub const Config = @import("Compilation/Config.zig");
5149
52/// General-purpose allocator. Used for both temporary and long-term storage.50/// General-purpose allocator. Used for both temporary and long-term storage.
...@@ -124,20 +122,21 @@ work_queues: [...@@ -124,20 +122,21 @@ work_queues: [
124 }122 }
125 break :len len;123 break :len len;
126 }124 }
127]DeprecatedLinearFifo(Job),125]std.Deque(Job),
128126
129/// These jobs are to invoke the Clang compiler to create an object file, which127/// These jobs are to invoke the Clang compiler to create an object file, which
130/// gets linked with the Compilation.128/// gets linked with the Compilation.
131c_object_work_queue: DeprecatedLinearFifo(*CObject),129c_object_work_queue: std.Deque(*CObject),
132130
133/// These jobs are to invoke the RC compiler to create a compiled resource file (.res), which131/// These jobs are to invoke the RC compiler to create a compiled resource file (.res), which
134/// gets linked with the Compilation.132/// gets linked with the Compilation.
135win32_resource_work_queue: if (dev.env.supports(.win32_resource)) DeprecatedLinearFifo(*Win32Resource) else struct {133win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.Deque(*Win32Resource) else struct {
136 pub fn ensureUnusedCapacity(_: @This(), _: u0) error{}!void {}134 pub const empty: @This() = .{};
137 pub fn readItem(_: @This()) ?noreturn {135 pub fn ensureUnusedCapacity(_: @This(), _: Allocator, _: u0) error{}!void {}
136 pub fn popFront(_: @This()) ?noreturn {
138 return null;137 return null;
139 }138 }
140 pub fn deinit(_: @This()) void {}139 pub fn deinit(_: @This(), _: Allocator) void {}
141},140},
142141
143/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.142/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.
...@@ -2231,9 +2230,9 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options...@@ -2231,9 +2230,9 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
2231 .root_mod = options.root_mod,2230 .root_mod = options.root_mod,
2232 .config = options.config,2231 .config = options.config,
2233 .dirs = options.dirs,2232 .dirs = options.dirs,
2234 .work_queues = @splat(.init(gpa)),2233 .work_queues = @splat(.empty),
2235 .c_object_work_queue = .init(gpa),2234 .c_object_work_queue = .empty,
2236 .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) .init(gpa) else .{},2235 .win32_resource_work_queue = .empty,
2237 .c_source_files = options.c_source_files,2236 .c_source_files = options.c_source_files,
2238 .rc_source_files = options.rc_source_files,2237 .rc_source_files = options.rc_source_files,
2239 .cache_parent = cache,2238 .cache_parent = cache,
...@@ -2699,9 +2698,9 @@ pub fn destroy(comp: *Compilation) void {...@@ -2699,9 +2698,9 @@ pub fn destroy(comp: *Compilation) void {
2699 if (comp.zcu) |zcu| zcu.deinit();2698 if (comp.zcu) |zcu| zcu.deinit();
2700 comp.cache_use.deinit();2699 comp.cache_use.deinit();
27012700
2702 for (&comp.work_queues) |*work_queue| work_queue.deinit();2701 for (&comp.work_queues) |*work_queue| work_queue.deinit(gpa);
2703 comp.c_object_work_queue.deinit();2702 comp.c_object_work_queue.deinit(gpa);
2704 comp.win32_resource_work_queue.deinit();2703 comp.win32_resource_work_queue.deinit(gpa);
27052704
2706 for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);2705 for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
2707 comp.windows_libs.deinit(gpa);2706 comp.windows_libs.deinit(gpa);
...@@ -3016,17 +3015,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3016,17 +3015,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
30163015
3017 // For compiling C objects, we rely on the cache hash system to avoid duplicating work.3016 // For compiling C objects, we rely on the cache hash system to avoid duplicating work.
3018 // Add a Job for each C object.3017 // Add a Job for each C object.
3019 try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count());3018 try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count());
3020 for (comp.c_object_table.keys()) |c_object| {3019 for (comp.c_object_table.keys()) |c_object| {
3021 comp.c_object_work_queue.writeItemAssumeCapacity(c_object);3020 comp.c_object_work_queue.pushBackAssumeCapacity(c_object);
3022 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));3021 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));
3023 }3022 }
30243023
3025 // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work.3024 // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work.
3026 // Add a Job for each Win32 resource file.3025 // Add a Job for each Win32 resource file.
3027 try comp.win32_resource_work_queue.ensureUnusedCapacity(comp.win32_resource_table.count());3026 try comp.win32_resource_work_queue.ensureUnusedCapacity(gpa, comp.win32_resource_table.count());
3028 for (comp.win32_resource_table.keys()) |win32_resource| {3027 for (comp.win32_resource_table.keys()) |win32_resource| {
3029 comp.win32_resource_work_queue.writeItemAssumeCapacity(win32_resource);3028 comp.win32_resource_work_queue.pushBackAssumeCapacity(win32_resource);
3030 switch (win32_resource.src) {3029 switch (win32_resource.src) {
3031 .rc => |f| {3030 .rc => |f| {
3032 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{f.src_path}));3031 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{f.src_path}));
...@@ -4869,14 +4868,14 @@ fn performAllTheWork(...@@ -4869,14 +4868,14 @@ fn performAllTheWork(
4869 }4868 }
4870 }4869 }
48714870
4872 while (comp.c_object_work_queue.readItem()) |c_object| {4871 while (comp.c_object_work_queue.popFront()) |c_object| {
4873 comp.link_task_queue.startPrelinkItem();4872 comp.link_task_queue.startPrelinkItem();
4874 comp.thread_pool.spawnWg(&comp.link_task_wait_group, workerUpdateCObject, .{4873 comp.thread_pool.spawnWg(&comp.link_task_wait_group, workerUpdateCObject, .{
4875 comp, c_object, main_progress_node,4874 comp, c_object, main_progress_node,
4876 });4875 });
4877 }4876 }
48784877
4879 while (comp.win32_resource_work_queue.readItem()) |win32_resource| {4878 while (comp.win32_resource_work_queue.popFront()) |win32_resource| {
4880 comp.link_task_queue.startPrelinkItem();4879 comp.link_task_queue.startPrelinkItem();
4881 comp.thread_pool.spawnWg(&comp.link_task_wait_group, workerUpdateWin32Resource, .{4880 comp.thread_pool.spawnWg(&comp.link_task_wait_group, workerUpdateWin32Resource, .{
4882 comp, win32_resource, main_progress_node,4881 comp, win32_resource, main_progress_node,
...@@ -4996,7 +4995,7 @@ fn performAllTheWork(...@@ -4996,7 +4995,7 @@ fn performAllTheWork(
4996 }4995 }
49974996
4998 work: while (true) {4997 work: while (true) {
4999 for (&comp.work_queues) |*work_queue| if (work_queue.readItem()) |job| {4998 for (&comp.work_queues) |*work_queue| if (work_queue.popFront()) |job| {
5000 try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job);4999 try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job);
5001 continue :work;5000 continue :work;
5002 };5001 };
...@@ -5025,7 +5024,7 @@ fn performAllTheWork(...@@ -5025,7 +5024,7 @@ fn performAllTheWork(
5025const JobError = Allocator.Error;5024const JobError = Allocator.Error;
50265025
5027pub fn queueJob(comp: *Compilation, job: Job) !void {5026pub fn queueJob(comp: *Compilation, job: Job) !void {
5028 try comp.work_queues[Job.stage(job)].writeItem(job);5027 try comp.work_queues[Job.stage(job)].pushBack(comp.gpa, job);
5029}5028}
50305029
5031pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {5030pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
src/deprecated.zig deleted-169
...@@ -1,169 +0,0 @@
1//! Deprecated. Stop using this API
2
3const std = @import("std");
4const math = std.math;
5const mem = std.mem;
6const Allocator = mem.Allocator;
7const assert = std.debug.assert;
8const testing = std.testing;
9
10pub fn LinearFifo(comptime T: type) type {
11 return struct {
12 allocator: Allocator,
13 buf: []T,
14 head: usize,
15 count: usize,
16
17 const Self = @This();
18
19 pub fn init(allocator: Allocator) Self {
20 return .{
21 .allocator = allocator,
22 .buf = &.{},
23 .head = 0,
24 .count = 0,
25 };
26 }
27
28 pub fn deinit(self: *Self) void {
29 self.allocator.free(self.buf);
30 self.* = undefined;
31 }
32
33 pub fn realign(self: *Self) void {
34 if (self.buf.len - self.head >= self.count) {
35 mem.copyForwards(T, self.buf[0..self.count], self.buf[self.head..][0..self.count]);
36 self.head = 0;
37 } else {
38 var tmp: [4096 / 2 / @sizeOf(T)]T = undefined;
39
40 while (self.head != 0) {
41 const n = @min(self.head, tmp.len);
42 const m = self.buf.len - n;
43 @memcpy(tmp[0..n], self.buf[0..n]);
44 mem.copyForwards(T, self.buf[0..m], self.buf[n..][0..m]);
45 @memcpy(self.buf[m..][0..n], tmp[0..n]);
46 self.head -= n;
47 }
48 }
49 { // set unused area to undefined
50 const unused = mem.sliceAsBytes(self.buf[self.count..]);
51 @memset(unused, undefined);
52 }
53 }
54
55 /// Ensure that the buffer can fit at least `size` items
56 pub fn ensureTotalCapacity(self: *Self, size: usize) !void {
57 if (self.buf.len >= size) return;
58 self.realign();
59 const new_size = math.ceilPowerOfTwo(usize, size) catch return error.OutOfMemory;
60 self.buf = try self.allocator.realloc(self.buf, new_size);
61 }
62
63 /// Makes sure at least `size` items are unused
64 pub fn ensureUnusedCapacity(self: *Self, size: usize) error{OutOfMemory}!void {
65 if (self.writableLength() >= size) return;
66
67 return try self.ensureTotalCapacity(math.add(usize, self.count, size) catch return error.OutOfMemory);
68 }
69
70 /// Returns a writable slice from the 'read' end of the fifo
71 fn readableSliceMut(self: Self, offset: usize) []T {
72 if (offset > self.count) return &[_]T{};
73
74 var start = self.head + offset;
75 if (start >= self.buf.len) {
76 start -= self.buf.len;
77 return self.buf[start .. start + (self.count - offset)];
78 } else {
79 const end = @min(self.head + self.count, self.buf.len);
80 return self.buf[start..end];
81 }
82 }
83
84 /// Discard first `count` items in the fifo
85 pub fn discard(self: *Self, count: usize) void {
86 assert(count <= self.count);
87 { // set old range to undefined. Note: may be wrapped around
88 const slice = self.readableSliceMut(0);
89 if (slice.len >= count) {
90 const unused = mem.sliceAsBytes(slice[0..count]);
91 @memset(unused, undefined);
92 } else {
93 const unused = mem.sliceAsBytes(slice[0..]);
94 @memset(unused, undefined);
95 const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);
96 @memset(unused2, undefined);
97 }
98 }
99 var head = self.head + count;
100 // Note it is safe to do a wrapping subtract as
101 // bitwise & with all 1s is a noop
102 head &= self.buf.len -% 1;
103 self.head = head;
104 self.count -= count;
105 }
106
107 /// Read the next item from the fifo
108 pub fn readItem(self: *Self) ?T {
109 if (self.count == 0) return null;
110
111 const c = self.buf[self.head];
112 self.discard(1);
113 return c;
114 }
115
116 /// Returns number of items available in fifo
117 pub fn writableLength(self: Self) usize {
118 return self.buf.len - self.count;
119 }
120
121 /// Returns the first section of writable buffer.
122 /// Note that this may be of length 0
123 pub fn writableSlice(self: Self, offset: usize) []T {
124 if (offset > self.buf.len) return &[_]T{};
125
126 const tail = self.head + offset + self.count;
127 if (tail < self.buf.len) {
128 return self.buf[tail..];
129 } else {
130 return self.buf[tail - self.buf.len ..][0 .. self.writableLength() - offset];
131 }
132 }
133
134 /// Update the tail location of the buffer (usually follows use of writable/writableWithSize)
135 pub fn update(self: *Self, count: usize) void {
136 assert(self.count + count <= self.buf.len);
137 self.count += count;
138 }
139
140 /// Appends the data in `src` to the fifo.
141 /// You must have ensured there is enough space.
142 pub fn writeAssumeCapacity(self: *Self, src: []const T) void {
143 assert(self.writableLength() >= src.len);
144
145 var src_left = src;
146 while (src_left.len > 0) {
147 const writable_slice = self.writableSlice(0);
148 assert(writable_slice.len != 0);
149 const n = @min(writable_slice.len, src_left.len);
150 @memcpy(writable_slice[0..n], src_left[0..n]);
151 self.update(n);
152 src_left = src_left[n..];
153 }
154 }
155
156 /// Write a single item to the fifo
157 pub fn writeItem(self: *Self, item: T) !void {
158 try self.ensureUnusedCapacity(1);
159 return self.writeItemAssumeCapacity(item);
160 }
161
162 pub fn writeItemAssumeCapacity(self: *Self, item: T) void {
163 var tail = self.head + self.count;
164 tail &= self.buf.len - 1;
165 self.buf[tail] = item;
166 self.update(1);
167 }
168 };
169}