Remove StaticallyInitializedMutex
This commit is contained in:
parent
0860b1919b
commit
bb6ad1a6c2
|
@ -1,105 +0,0 @@
|
|||
const std = @import("std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const AtomicOrder = builtin.AtomicOrder;
|
||||
const AtomicRmwOp = builtin.AtomicRmwOp;
|
||||
const assert = std.debug.assert;
|
||||
const expect = std.testing.expect;
|
||||
const windows = std.os.windows;
|
||||
|
||||
/// Lock may be held only once. If the same thread
|
||||
/// tries to acquire the same mutex twice, it deadlocks.
|
||||
/// This type is intended to be initialized statically. If you don't
|
||||
/// require static initialization, use std.Mutex.
|
||||
/// On Windows, this mutex allocates resources when it is
|
||||
/// first used, and the resources cannot be freed.
|
||||
/// On Linux, this is an alias of std.Mutex.
|
||||
pub const StaticallyInitializedMutex = switch (builtin.os) {
|
||||
builtin.Os.linux => std.Mutex,
|
||||
builtin.Os.windows => struct {
|
||||
lock: windows.CRITICAL_SECTION,
|
||||
init_once: windows.RTL_RUN_ONCE,
|
||||
|
||||
pub const Held = struct {
|
||||
mutex: *StaticallyInitializedMutex,
|
||||
|
||||
pub fn release(self: Held) void {
|
||||
windows.kernel32.LeaveCriticalSection(&self.mutex.lock);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn init() StaticallyInitializedMutex {
|
||||
return StaticallyInitializedMutex{
|
||||
.lock = undefined,
|
||||
.init_once = windows.INIT_ONCE_STATIC_INIT,
|
||||
};
|
||||
}
|
||||
|
||||
extern fn initCriticalSection(
|
||||
InitOnce: *windows.RTL_RUN_ONCE,
|
||||
Parameter: ?*c_void,
|
||||
Context: ?*c_void,
|
||||
) windows.BOOL {
|
||||
const lock = @ptrCast(*windows.CRITICAL_SECTION, @alignCast(@alignOf(windows.CRITICAL_SECTION), Parameter));
|
||||
windows.kernel32.InitializeCriticalSection(lock);
|
||||
return windows.TRUE;
|
||||
}
|
||||
|
||||
/// TODO: once https://github.com/ziglang/zig/issues/287 is solved and std.Mutex has a better
|
||||
/// implementation of a runtime initialized mutex, remove this function.
|
||||
pub fn deinit(self: *StaticallyInitializedMutex) void {
|
||||
windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
|
||||
windows.kernel32.DeleteCriticalSection(&self.lock);
|
||||
}
|
||||
|
||||
pub fn acquire(self: *StaticallyInitializedMutex) Held {
|
||||
windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
|
||||
windows.kernel32.EnterCriticalSection(&self.lock);
|
||||
return Held{ .mutex = self };
|
||||
}
|
||||
},
|
||||
else => std.Mutex,
|
||||
};
|
||||
|
||||
test "std.StaticallyInitializedMutex" {
|
||||
const TestContext = struct {
|
||||
data: i128,
|
||||
|
||||
const TestContext = @This();
|
||||
const incr_count = 10000;
|
||||
|
||||
var mutex = StaticallyInitializedMutex.init();
|
||||
|
||||
fn worker(ctx: *TestContext) void {
|
||||
var i: usize = 0;
|
||||
while (i != TestContext.incr_count) : (i += 1) {
|
||||
const held = mutex.acquire();
|
||||
defer held.release();
|
||||
|
||||
ctx.data += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var plenty_of_memory = try std.heap.direct_allocator.alloc(u8, 300 * 1024);
|
||||
defer std.heap.direct_allocator.free(plenty_of_memory);
|
||||
|
||||
var fixed_buffer_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(plenty_of_memory);
|
||||
var a = &fixed_buffer_allocator.allocator;
|
||||
|
||||
var context = TestContext{ .data = 0 };
|
||||
|
||||
if (builtin.single_threaded) {
|
||||
TestContext.worker(&context);
|
||||
expect(context.data == TestContext.incr_count);
|
||||
} else {
|
||||
const thread_count = 10;
|
||||
var threads: [thread_count]*std.Thread = undefined;
|
||||
for (threads) |*t| {
|
||||
t.* = try std.Thread.spawn(&context, TestContext.worker);
|
||||
}
|
||||
for (threads) |t|
|
||||
t.wait();
|
||||
|
||||
expect(context.data == thread_count * TestContext.incr_count);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ pub const Progress = @import("progress.zig").Progress;
|
|||
pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
|
||||
pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
|
||||
pub const SpinLock = @import("spinlock.zig").SpinLock;
|
||||
pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
|
||||
pub const StringHashMap = @import("hash_map.zig").StringHashMap;
|
||||
pub const TailQueue = @import("linked_list.zig").TailQueue;
|
||||
pub const Target = @import("target.zig").Target;
|
||||
|
|
Loading…
Reference in New Issue
Block a user