const std = @import("std"); const os = std.os; const mem = std.mem; const meta = std.meta; const atomic = std.atomic; const builtin = std.builtin; const testing = std.testing; const assert = std.debug.assert; const mpsc = @This(); pub const cache_line_length = switch (@import("builtin").target.cpu.arch) { .x86_64, .aarch64, .powerpc64 => 128, .arm, .mips, .mips64, .riscv64 => 32, .s390x => 256, else => 64, }; pub fn UnboundedQueue(comptime T: type, comptime next_field: meta.FieldEnum(T)) type { const next_name = meta.fieldInfo(T, next_field).name; return struct { const Self = @This(); pub const Batch = struct { pub const Iterator = struct { batch: Self.Batch, pub fn next(self: *Self.Batch.Iterator) ?*T { if (self.batch.count == 0) return null; const front = self.batch.front orelse unreachable; self.batch.front = @field(front, next_name); self.batch.count -= 1; return front; } }; front: ?*T = null, last: ?*T = null, count: usize = 0, pub fn iterator(self: Self.Batch) Self.Batch.Iterator { return .{ .batch = self }; } }; const next = next_name; pub const queue_padding_length = cache_line_length / 2; back: ?*T align(queue_padding_length) = null, count: usize = 0, front: T align(queue_padding_length) = init: { var stub: T = undefined; @field(stub, next) = null; break :init stub; }, pub fn push(self: *Self, src: *T) void { assert(@atomicRmw(usize, &self.count, .Add, 1, .Release) >= 0); @field(src, next) = null; const old_back = @atomicRmw(?*T, &self.back, .Xchg, src, .AcqRel) orelse &self.front; @field(old_back, next) = src; } pub fn pushBatch(self: *Self, first: *T, last: *T, count: usize) void { assert(@atomicRmw(usize, &self.count, .Add, count, .Release) >= 0); @field(last, next) = null; const old_back = @atomicRmw(?*T, &self.back, .Xchg, last, .AcqRel) orelse &self.front; @field(old_back, next) = first; } pub fn pop(self: *Self) ?*T { const first = @atomicLoad(?*T, &@field(self.front, next), .Acquire) orelse return null; if (@atomicLoad(?*T, &@field(first, next), .Acquire)) |next_item| { @atomicStore(?*T, &@field(self.front, next), next_item, .Monotonic); assert(@atomicRmw(usize, &self.count, .Sub, 1, .Monotonic) >= 1); return first; } const last = @atomicLoad(?*T, &self.back, .Acquire) orelse &self.front; if (first != last) return null; @atomicStore(?*T, &@field(self.front, next), null, .Monotonic); if (@cmpxchgStrong(?*T, &self.back, last, &self.front, .AcqRel, .Acquire) == null) { assert(@atomicRmw(usize, &self.count, .Sub, 1, .Monotonic) >= 1); return first; } var next_item = @atomicLoad(?*T, &@field(first, next), .Acquire); while (next_item == null) : (atomic.spinLoopHint()) { next_item = @atomicLoad(?*T, &@field(first, next), .Acquire); } @atomicStore(?*T, &@field(self.front, next), next_item, .Monotonic); assert(@atomicRmw(usize, &self.count, .Sub, 1, .Monotonic) >= 1); return first; } pub fn popBatch(self: *Self) Self.Batch { var batch: Self.Batch = .{}; var front = @atomicLoad(?*T, &@field(self.front, next), .Acquire) orelse return batch; batch.front = front; var next_item = @atomicLoad(?*T, &@field(front, next), .Acquire); while (next_item) |next_node| : (next_item = @atomicLoad(?*T, &@field(next_node, next), .Acquire)) { batch.count += 1; batch.last = front; front = next_node; } const last = @atomicLoad(?*T, &self.back, .Acquire) orelse &self.front; if (front != last) { @atomicStore(?*T, &@field(self.front, next), front, .Release); assert(@atomicRmw(usize, &self.count, .Sub, batch.count, .Monotonic) >= batch.count); return batch; } @atomicStore(?*T, &@field(self.front, next), null, .Monotonic); if (@cmpxchgStrong(?*T, &self.back, last, &self.front, .AcqRel, .Acquire) == null) { batch.count += 1; batch.last = front; assert(@atomicRmw(usize, &self.count, .Sub, batch.count, .Monotonic) >= batch.count); return batch; } next_item = @atomicLoad(?*T, &@field(front, next), .Acquire); while (next_item == null) : (atomic.spinLoopHint()) { next_item = @atomicLoad(?*T, &@field(front, next), .Acquire); } batch.count += 1; @atomicStore(?*T, &@field(self.front, next), next_item, .Monotonic); batch.last = front; assert(@atomicRmw(usize, &self.count, .Sub, batch.count, .Monotonic) >= batch.count); return batch; } pub fn peek(self: *Self) usize { const count = @atomicLoad(usize, &self.count, .Acquire); assert(count >= 0); return count; } pub fn isEmpty(self: *Self) bool { return self.peek() == 0; } }; } ics Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/bench/snippets/blob.mjs (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2023-02-17use `bun.logger` instead of `bun.Output` (#2099)Gravatar Alex Lam S.L 4-99/+181
2023-02-17Fix flaky testGravatar Jarred Sumner 1-18/+19
2023-02-17Fix #1602 (#2066)Gravatar Justin Whear 12-94/+228
2023-02-17[install] support git dependencies (#2094)Gravatar Alex Lam S.L 9-279/+1020
2023-02-17Fix #2005 (#2096)Gravatar Justin Whear 2-1/+60
2023-02-17allow `bun add` of packages with capital letters (#2095)Gravatar Alex Lam S.L 3-2/+53
2023-02-16faster Buffer.byteLength("latin1")Gravatar Jarred Sumner 1-36/+28
2023-02-16Support yarn-like `"workspaces"."packages": string[]` (#2086)Gravatar Jarred Sumner 2-97/+253
2023-02-16Implement `machine` for Linux (#2088)Gravatar Justin Whear 3-0/+19
2023-02-16Fix #1516 (#2089)Gravatar Justin Whear 3-7/+14
2023-02-16Update globals.d.tsGravatar Jarred Sumner 1-0/+15
2023-02-16Add missing type definitionGravatar Jarred Sumner 1-0/+2
2023-02-16[napi] Fix crash in creating arrays > 8 elements longGravatar Jarred Sumner 1-10/+9
2023-02-16Clarify and clean up macOS build process (#2087)Gravatar Luke Deen Taylor 2-4/+4
2023-02-15Don't crash on null version stringGravatar Jarred Sumner 1-1/+1
2023-02-15Add disabled optimizationGravatar Jarred Sumner 1-0/+51
2023-02-15Add more logging to napiGravatar Jarred Sumner 1-30/+150
2023-02-15Incorrect implementation of `napi_create_threadsafe_function`Gravatar Jarred Sumner 1-21/+43
2023-02-15feat(fetch) AbortSignal (#2019)Gravatar Ciro Spaciari 17-58/+443
2023-02-15fix(webcrypto): fix ed25519 CryptoKey.algorithm (#2082)Gravatar Derrick Farris 2-9/+28
2023-02-15Fix 2063 (#2079)Gravatar Justin Whear 2-2/+11
2023-02-15Make sure we test * in tesconfigGravatar Jarred Sumner 2-1/+3
2023-02-15don't return an error thereGravatar Jarred Sumner 2-1/+3
2023-02-15Fix castGravatar Jarred Sumner 1-15/+17
2023-02-15ensure we allocate for > 6 argumentsGravatar Jarred Sumner 1-6/+13
2023-02-15Update async_hooks.exports.jsGravatar Jarred Sumner 1-2/+2
2023-02-15workaround prisma's usage of `eval("__dirname")`Gravatar Jarred Sumner 1-1/+23
2023-02-15some cleanupGravatar Jarred Sumner 2-15/+9
2023-02-15ED25519 WebCrypto (#1971)Gravatar Jarred Sumner 12-11/+1167
2023-02-14Fix up async_hooks polyfillGravatar Jarred Sumner 2-8/+63
2023-02-14Add temporary polyfill for async_hooksGravatar Jarred Sumner 5-108/+324
2023-02-14:mask: async_hooksGravatar Jarred Sumner 1-0/+4
2023-02-14[install] link network-delayed `.bin` scripts correctly (#2076)Gravatar Alex Lam S.L 3-16/+21
2023-02-14don't break esbuildGravatar Jarred Sumner 7-75/+50
2023-02-14Add workaround for `tls` and `worker_threads`Gravatar Jarred Sumner 3-1/+64
2023-02-14[install] improve `package.json` validation (#2074)Gravatar Alex Lam S.L 6-104/+342
2023-02-14[WIP] fix(node:fs): export `fs.ReadStream` and `fs.WriteStream` (#1798)Gravatar Derrick Farris 4-72/+326
2023-02-14Reject with error when invalid fetch() body (#2047)Gravatar Eric Zhang 2-12/+44
2023-02-13fix(FormData): make String explicit, thanks @dylan-conway (#2065)Gravatar Derrick Farris 1-1/+1
2023-02-13fix(FormData): add string literal operator (#2064)Gravatar Derrick Farris 1-2/+2
2023-02-13Add pretty printer for FormDataGravatar Jarred Sumner 5-1/+101
2023-02-13Add dynamic port assigning to Bun.serve (#2062)Gravatar MichaƂ Warda 3-5/+40
2023-02-13feat(napi): add `napi_get_value_bigint_words` (#2061)Gravatar Derrick Farris 3-0/+44
2023-02-13Fixes https://github.com/oven-sh/bun/issues/1456Gravatar Jarred Sumner 8-1/+148