Skip to content

Commit d41fac8

Browse files
authored
Merge pull request #1 from Aandreba/wasm
Add support for Wasm atomics
2 parents 34cdb56 + f0b60c4 commit d41fac8

File tree

2 files changed

+90
-24
lines changed

2 files changed

+90
-24
lines changed

build.zig

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
const std = @import("std");
2+
const builtin = @import("builtin");
3+
4+
const Builder = if (builtin.zig_version.minor <= 10) std.build.Builder else std.Build;
5+
const Mode = if (builtin.zig_version.minor <= 10) std.builtin.Mode else std.builtin.OptimizeMode;
26

37
const Target = std.Target;
48
const CrossTarget = std.zig.CrossTarget;
59

610
const Arch = Target.Cpu.Arch;
711
const Os = Target.Os.Tag;
812

9-
pub fn build(b: *std.build.Builder) void {
13+
pub fn build(b: *Builder) void {
14+
if (comptime builtin.zig_version.minor <= 10) {
15+
build_v10(b);
16+
} else {
17+
build_v11(b);
18+
}
19+
}
20+
21+
fn build_v10(b: *std.build.Builder) void {
1022
// Standard release options allow the person running `zig build` to select
1123
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
1224
const mode = b.standardReleaseOptions();
1325
const coverage = b.option(bool, "coverage", "Generate test coverage") orelse false;
1426

1527
// Docs
16-
const linux_64 = build_target(b, mode, Arch.x86_64, Os.linux);
17-
linux_64.install();
28+
const docs = b.addStaticLibrary("zig-rc", "src/main.zig");
29+
docs.emit_docs = .emit;
30+
docs.setBuildMode(mode);
31+
docs.install();
1832

1933
// Tests
2034
const main_tests = b.addTest("src/tests.zig");
@@ -39,12 +53,55 @@ pub fn build(b: *std.build.Builder) void {
3953
example_step.dependOn(&example.step);
4054
}
4155

42-
fn build_target(b: *std.build.Builder, mode: std.builtin.Mode, arch: Target.Cpu.Arch, os_tag: Target.Os.Tag) *std.build.LibExeObjStep {
43-
const lib = b.addStaticLibrary("zig-rc", "src/main.zig");
44-
lib.emit_docs = .emit;
45-
lib.setBuildMode(mode);
46-
lib.setTarget(CrossTarget.fromTarget(default_target(arch, os_tag)));
47-
return lib;
56+
fn build_v11(b: *std.Build) void {
57+
// Standard target options allows the person running `zig build` to choose
58+
// what target to build for. Here we do not override the defaults, which
59+
// means any target is allowed, and the default is native. Other options
60+
// for restricting supported target set are available.
61+
const target = b.standardTargetOptions(.{});
62+
63+
// Standard optimization options allow the person running `zig build` to select
64+
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
65+
// set a preferred release mode, allowing the user to decide how to optimize.
66+
const optimize = b.standardOptimizeOption(.{});
67+
68+
const coverage = b.option(bool, "coverage", "Generate test coverage") orelse false;
69+
70+
// Docs
71+
const docs = b.addStaticLibrary(.{
72+
.name = "zig-rc",
73+
.root_source_file = .{ .path = "src/main.zig" },
74+
.target = target,
75+
.optimize = optimize,
76+
});
77+
docs.emit_docs = .emit;
78+
b.installArtifact(docs);
79+
80+
// Tests
81+
const main_tests = b.addTest(.{
82+
.root_source_file = .{ .path = "src/tests.zig" },
83+
});
84+
const run_main_tests = b.addRunArtifact(main_tests);
85+
86+
if (coverage) {
87+
main_tests.setExecCmd(&[_]?[]const u8{
88+
"kcov",
89+
"--include-pattern=src/main.zig,src/tests.zig",
90+
"kcov-out",
91+
null, // to get zig to use the --test-cmd-bin flag
92+
});
93+
}
94+
95+
const test_step = b.step("test", "Run library tests");
96+
test_step.dependOn(&run_main_tests.step);
97+
98+
// Examples
99+
const example = b.addTest(.{
100+
.root_source_file = .{ .path = "src/example.zig" },
101+
});
102+
const run_example = b.addRunArtifact(example);
103+
const example_step = b.step("example", "Run library example");
104+
example_step.dependOn(&run_example.step);
48105
}
49106

50107
fn default_target(arch: Target.Cpu.Arch, os_tag: Target.Os.Tag) Target {

src/main.zig

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
const std = @import("std");
22
const builtin = @import("builtin");
33

4+
/// This variable is `true` if an atomic reference-counter is used for `Arc`, `false` otherwise.
5+
///
6+
/// If the target is single-threaded, `Arc` is optimized to a regular `Rc`.
7+
pub const atomic_arc = !builtin.single_threaded or (builtin.target.isWasm() and std.Target.wasm.featureSetHas(builtin.cpu.features, .atomics));
8+
49
/// A single threaded, strong reference to a reference-counted value.
510
pub fn Rc(comptime T: type) type {
611
return struct {
@@ -128,15 +133,13 @@ pub fn Rc(comptime T: type) type {
128133
}
129134

130135
/// Total size (in bytes) of the reference counted value on the heap.
131-
/// This value accounts for the extra memory required to count the references,
132-
/// and is valid for single and multi-threaded refrence counters.
136+
/// This value accounts for the extra memory required to count the references.
133137
pub fn innerSize() comptime_int {
134138
return Inner.innerSize();
135139
}
136140

137141
/// Alignment (in bytes) of the reference counted value on the heap.
138-
/// This value accounts for the extra memory required to count the references,
139-
/// and is valid for single and multi-threaded refrence counters.
142+
/// This value accounts for the extra memory required to count the references.
140143
pub fn innerAlign() comptime_int {
141144
return Inner.innerAlign();
142145
}
@@ -147,7 +150,7 @@ pub fn Rc(comptime T: type) type {
147150

148151
/// A single threaded, weak reference to a reference-counted value.
149152
pub const Weak = struct {
150-
inner: ?*align(@alignOf(Inner)) anyopaque = null,
153+
inner: ?*Inner = null,
151154
alloc: std.mem.Allocator,
152155

153156
/// Creates a new weak reference.
@@ -236,7 +239,7 @@ pub fn Rc(comptime T: type) type {
236239

237240
/// A multi-threaded, strong reference to a reference-counted value.
238241
pub fn Arc(comptime T: type) type {
239-
if (builtin.single_threaded) {
242+
if (!atomic_arc) {
240243
return Rc(T);
241244
}
242245

@@ -355,15 +358,13 @@ pub fn Arc(comptime T: type) type {
355358
}
356359

357360
/// Total size (in bytes) of the reference counted value on the heap.
358-
/// This value accounts for the extra memory required to count the references,
359-
/// and is valid for single and multi-threaded refrence counters.
361+
/// This value accounts for the extra memory required to count the references.
360362
pub fn innerSize() comptime_int {
361363
return Inner.innerSize();
362364
}
363365

364366
/// Alignment (in bytes) of the reference counted value on the heap.
365-
/// This value accounts for the extra memory required to count the references,
366-
/// and is valid for single and multi-threaded refrence counters.
367+
/// This value accounts for the extra memory required to count the references.
367368
pub fn innerAlign() comptime_int {
368369
return Inner.innerAlign();
369370
}
@@ -374,7 +375,7 @@ pub fn Arc(comptime T: type) type {
374375

375376
/// A multi-threaded, weak reference to a reference-counted value.
376377
pub const Weak = struct {
377-
inner: ?*align(@alignOf(Inner)) anyopaque = null,
378+
inner: ?*Inner = null,
378379
alloc: std.mem.Allocator,
379380

380381
/// Creates a new weak reference.
@@ -449,15 +450,13 @@ pub fn Arc(comptime T: type) type {
449450
}
450451

451452
/// Total size (in bytes) of the reference counted value on the heap.
452-
/// This value accounts for the extra memory required to count the references,
453-
/// and is valid for single and multi-threaded refrence counters.
453+
/// This value accounts for the extra memory required to count the references.
454454
pub fn innerSize() comptime_int {
455455
return Inner.innerSize();
456456
}
457457

458458
/// Alignment (in bytes) of the reference counted value on the heap.
459-
/// This value accounts for the extra memory required to count the references,
460-
/// and is valid for single and multi-threaded refrence counters.
459+
/// This value accounts for the extra memory required to count the references.
461460
pub fn innerAlign() comptime_int {
462461
return Inner.innerAlign();
463462
}
@@ -468,3 +467,13 @@ pub fn Arc(comptime T: type) type {
468467
};
469468
};
470469
}
470+
471+
/// Creates a new `Rc` inferring the type of `value`
472+
pub fn rc(alloc: std.mem.Allocator, value: anytype) std.mem.Allocator.Error!Rc(@TypeOf(value)) {
473+
return Rc(@TypeOf(value)).init(alloc, value);
474+
}
475+
476+
/// Creates a new `Arc` inferring the type of `value`
477+
pub fn arc(alloc: std.mem.Allocator, value: anytype) std.mem.Allocator.Error!Arc(@TypeOf(value)) {
478+
return Arc(@TypeOf(value)).init(alloc, value);
479+
}

0 commit comments

Comments
 (0)