tiny.simd.AtomicBitSet
Defined in bitset.
Source
Source: lib/simd/src/bitset.zig:152
zig
pub fn AtomicBitSet(comptime size: usize) type { requireCapacity(size); const Word = usize; const word_bits: usize = @bitSizeOf(Word); const word_count = std.math.divCeil(usize, size, word_bits) catch unreachable; const AtomicWord = std.atomic.Value(Word); return struct { words: [word_count]AtomicWord = @as([word_count]AtomicWord, @splat(AtomicWord.init(0))), const Self = @This(); pub const capacity: usize = size; pub const max_size: usize = capacity; pub fn maxSize(_: *const Self) usize { return max_size; } pub fn set(self: *Self, index: usize) void { std.debug.assert(index < max_size); _ = self.words[atomicWordIndex(index)].fetchOr( atomicBit(atomicBitIndex(index)), .release, ); } pub fn clear(self: *Self, index: usize) void { std.debug.assert(index < max_size); _ = self.words[atomicWordIndex(index)].fetchAnd( ~atomicBit(atomicBitIndex(index)), .release, ); if (runtime_assertions) std.debug.assert(!self.get(index)); } pub fn get(self: *const Self, index: usize) bool { std.debug.assert(index < max_size); return self.words[atomicWordIndex(index)].load(.acquire) & atomicBit(atomicBitIndex(index)) != 0; } pub fn any(self: *const Self) bool { for (&self.words) |*word| { if (word.load(.acquire) != 0) return true; } return false; } pub fn all(self: *const Self) bool { for (self.words[0 .. word_count - 1]) |*word| { if (word.load(.acquire) != std.math.maxInt(Word)) return false; } const last = self.words[word_count - 1].load(.acquire); const remainder = max_size % word_bits; return if (remainder == 0) last == std.math.maxInt(Word) else @popCount(last) == remainder; } pub fn first(self: *const Self) usize { if (runtime_assertions) std.debug.assert(self.any()); for (&self.words, 0..) |*word, word_index| { const bits = word.load(.acquire); if (bits != 0) { return word_index * word_bits + atomicFirstBit(bits); } } unreachable; } pub fn first0(self: *const Self) usize { if (runtime_assertions) std.debug.assert(!self.all()); for (&self.words, 0..) |*word, word_index| { const inverted = ~word.load(.acquire); if (inverted != 0) { const index = word_index * word_bits + atomicFirstBit(inverted); std.debug.assert(index < max_size); return index; } } unreachable; } pub fn foreach(self: *const Self, function: anytype) void { for (&self.words, 0..) |*word, word_index| { visitAtomicWord( word.load(.acquire), word_index * word_bits, function, ); } } pub fn count(self: *const Self) usize { var total: usize = 0; for (&self.words) |*word| total += @popCount(word.load(.acquire)); std.debug.assert(total <= max_size); return total; } fn atomicWordIndex(index: usize) usize { return index / word_bits; } fn atomicBitIndex(index: usize) usize { return index % word_bits; } fn atomicBit(index: usize) Word { std.debug.assert(index < word_bits); return @as(Word, 1) << @intCast(index); } fn atomicFirstBit(bits: Word) usize { std.debug.assert(bits != 0); return @ctz(bits); } fn visitAtomicWord(bits: Word, base: usize, function: anytype) void { var remaining = bits; while (remaining != 0) { const index = atomicFirstBit(remaining); remaining &= remaining - 1; function.call(base + index); } } };}Source: lib/simd/src/root.zig:540
zig
pub const AtomicBitSet = bitset.AtomicBitSet;Audit
| Definitions | 1 |
|---|---|
| Public names | 2 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |