const std = @import("std"); const Atomic = std.atomic.Atomic; const Futex = @import("./futex.zig"); // Credit: this is copypasta from @kprotty. Thank you @kprotty! pub const Mutex = struct { state: Atomic(u32) = Atomic(u32).init(UNLOCKED), const UNLOCKED = 0; const LOCKED = 0b01; const CONTENDED = 0b11; const is_x86 = @import("builtin").target.cpu.arch.isX86(); pub fn tryAcquire(self: *Mutex) bool { return self.acquireFast(true); } pub fn acquire(self: *Mutex) void { if (!self.acquireFast(false)) { self.acquireSlow(); } } inline fn acquireFast(self: *Mutex, comptime strong: bool) bool { // On x86, "lock bts" uses less i-cache & can be faster than "lock cmpxchg" below. if (comptime is_x86) { return self.state.bitSet(@ctz(@as(u32, LOCKED)), .Acquire) == UNLOCKED; } const cas_fn = comptime switch (strong) { true => Atomic(u32).compareAndSwap, else => Atomic(u32).tryCompareAndSwap, }; return cas_fn( &self.state, UNLOCKED, LOCKED, .Acquire, .Monotonic, ) == null; } noinline fn acquireSlow(self: *Mutex) void { // Spin a little bit on the Mutex state in the hopes that // we can acquire it without having to call Futex.wait(). // Give up spinning if the Mutex is contended. // This helps acquire() latency under micro-contention. // var spin: u8 = 100; while (spin > 0) : (spin -= 1) { std.atomic.spinLoopHint(); switch (self.state.load(.Monotonic)) { UNLOCKED => _ = self.state.tryCompareAndSwap( UNLOCKED, LOCKED, .Acquire, .Monotonic, ) orelse return, LOCKED => continue, CONTENDED => break, else => unreachable, // invalid Mutex state } } // Make sure the state is CONTENDED before sleeping with Futex so release() can wake us up. // Transitioning to CONTENDED may also acquire the mutex in the process. // // If we sleep, we must acquire the Mutex with CONTENDED to ensure that other threads // sleeping on the Futex having seen CONTENDED before are eventually woken up by release(). // This unfortunately ends up in an extra Futex.wake() for the last thread but that's ok. while (true) : (Futex.wait(&self.state, CONTENDED, null) catch unreachable) { // On x86, "xchg" can be faster than "lock cmpxchg" below. if (comptime is_x86) { switch (self.state.swap(CONTENDED, .Acquire)) { UNLOCKED => return, LOCKED, CONTENDED => continue, else => unreachable, // invalid Mutex state } } var state = self.state.load(.Monotonic); while (state != CONTENDED) { state = switch (state) { UNLOCKED => self.state.tryCompareAndSwap(state, CONTENDED, .Acquire, .Monotonic) orelse return, LOCKED => self.state.tryCompareAndSwap(state, CONTENDED, .Monotonic, .Monotonic) orelse break, CONTENDED => unreachable, // checked above else => unreachable, // invalid Mutex state }; } } } pub fn release(self: *Mutex) void { switch (self.state.swap(UNLOCKED, .Release)) { UNLOCKED => unreachable, // released without being acquired LOCKED => {}, CONTENDED => Futex.wake(&self.state, 1), else => unreachable, // invalid Mutex state } } }; pub const Lock = struct { mutex: Mutex, pub fn init() Lock { return Lock{ .mutex = Mutex{} }; } pub inline fn lock(this: *Lock) void { this.mutex.acquire(); } pub inline fn unlock(this: *Lock) void { this.mutex.release(); } }; pub fn spinCycle() void {} xports Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/JSDOMGlobalObject.cpp (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2023-10-09fix(AbortSignal/fetch) fix AbortSignal.timeout, fetch lock behavior and fetch...Gravatar Ciro Spaciari 29-61/+303
2023-10-09Fix npm tag for canary bun-types, againGravatar Ashcon Partovi 2-56/+10
2023-10-09Add Fedora build instructions to development.md (#6359)Gravatar otterDeveloper 1-0/+10
2023-10-09added commands (#6314)Gravatar babar 1-1/+2
2023-10-09Update README.md (#6291)Gravatar TPLJ 1-1/+1
2023-10-09docs: fixing a couple typos (#6331)Gravatar Michael Di Prisco 2-2/+2
2023-10-09fix: support uint8 exit code range (#6303)Gravatar Liz 2-2/+11
2023-10-09Fix array variables preview in debugger (#6379)Gravatar 2hu 1-1/+4
2023-10-07feat(KeyObject) (#5940)Gravatar Ciro Spaciari 106-67/+9342
2023-10-07Exclude more filesGravatar Jarred Sumner 1-1/+1
2023-10-07Exclude more filesGravatar Jarred Sumner 1-1/+2
2023-10-07Update settings.jsonGravatar Jarred Sumner 1-1/+2
2023-10-07Update settings.jsonGravatar Jarred Sumner 1-2/+3
2023-10-06fix a couple install testsGravatar Dylan Conway 1-8/+8
2023-10-06formatGravatar Dylan Conway 1-1/+2
2023-10-06Fix memory leak in fetch() (#6350)Gravatar Jarred Sumner 1-2/+0
2023-10-06[types] allow onLoad plugin callbacks to return undefined (#6346)Gravatar Silver 1-1/+1
2023-10-06docs: `file.stream()` is not a promise (#6337)Gravatar Paul Nodet 1-1/+1