| ... | @@ -11,6 +11,7 @@ const windows = std.os.windows; | ... | @@ -11,6 +11,7 @@ const windows = std.os.windows; |
| 11 | const linux = std.os.linux; | 11 | const linux = std.os.linux; |
| 12 | const Mutex = std.Thread.Mutex; | 12 | const Mutex = std.Thread.Mutex; |
| 13 | const assert = std.debug.assert; | 13 | const assert = std.debug.assert; |
| | 14 | const testing = std.testing; |
| 14 | | 15 | |
| 15 | pub fn wait(cond: *Condition, mutex: *Mutex) void { | 16 | pub fn wait(cond: *Condition, mutex: *Mutex) void { |
| 16 | cond.impl.wait(mutex); | 17 | cond.impl.wait(mutex); |
| ... | @@ -193,3 +194,47 @@ pub const AtomicCondition = struct { | ... | @@ -193,3 +194,47 @@ pub const AtomicCondition = struct { |
| 193 | waiter.data.notify(); | 194 | waiter.data.notify(); |
| 194 | } | 195 | } |
| 195 | }; | 196 | }; |
| | 197 | |
| | 198 | test "Thread.Condition" { |
| | 199 | if (builtin.single_threaded) { |
| | 200 | return error.SkipZigTest; |
| | 201 | } |
| | 202 | |
| | 203 | const TestContext = struct { |
| | 204 | cond: *Condition, |
| | 205 | cond_main: *Condition, |
| | 206 | mutex: *Mutex, |
| | 207 | n: *i32, |
| | 208 | fn worker(ctx: *@This()) void { |
| | 209 | ctx.mutex.lock(); |
| | 210 | ctx.n.* += 1; |
| | 211 | ctx.cond_main.signal(); |
| | 212 | ctx.cond.wait(ctx.mutex); |
| | 213 | ctx.n.* -= 1; |
| | 214 | ctx.cond_main.signal(); |
| | 215 | ctx.mutex.unlock(); |
| | 216 | } |
| | 217 | }; |
| | 218 | const num_threads = 3; |
| | 219 | var threads: [num_threads]std.Thread = undefined; |
| | 220 | var cond = Condition{}; |
| | 221 | var cond_main = Condition{}; |
| | 222 | var mut = Mutex{}; |
| | 223 | var n: i32 = 0; |
| | 224 | var ctx = TestContext{ .cond = &cond, .cond_main = &cond_main, .mutex = &mut, .n = &n }; |
| | 225 | |
| | 226 | mut.lock(); |
| | 227 | for (threads) |*t| t.* = try std.Thread.spawn(.{}, TestContext.worker, .{&ctx}); |
| | 228 | cond_main.wait(&mut); |
| | 229 | while (n < num_threads) cond_main.wait(&mut); |
| | 230 | |
| | 231 | cond.signal(); |
| | 232 | cond_main.wait(&mut); |
| | 233 | try testing.expect(n == (num_threads - 1)); |
| | 234 | |
| | 235 | cond.broadcast(); |
| | 236 | while (n > 0) cond_main.wait(&mut); |
| | 237 | try testing.expect(n == 0); |
| | 238 | |
| | 239 | for (threads) |t| t.join(); |
| | 240 | } |