| ... | @@ -330,10 +330,12 @@ test "Condition - wait and signal" { | ... | @@ -330,10 +330,12 @@ test "Condition - wait and signal" { |
| 330 | mutex: Mutex = .{}, | 330 | mutex: Mutex = .{}, |
| 331 | cond: Condition = .{}, | 331 | cond: Condition = .{}, |
| 332 | threads: [num_threads]std.Thread = undefined, | 332 | threads: [num_threads]std.Thread = undefined, |
| | 333 | spawn_count: std.math.IntFittingRange(0, num_threads) = 0, |
| 333 | | 334 | |
| 334 | fn run(self: *@This()) void { | 335 | fn run(self: *@This()) void { |
| 335 | self.mutex.lock(); | 336 | self.mutex.lock(); |
| 336 | defer self.mutex.unlock(); | 337 | defer self.mutex.unlock(); |
| | 338 | self.spawn_count += 1; |
| 337 | | 339 | |
| 338 | self.cond.wait(&self.mutex); | 340 | self.cond.wait(&self.mutex); |
| 339 | self.cond.timedWait(&self.mutex, std.time.ns_per_ms) catch {}; | 341 | self.cond.timedWait(&self.mutex, std.time.ns_per_ms) catch {}; |
| ... | @@ -346,7 +348,14 @@ test "Condition - wait and signal" { | ... | @@ -346,7 +348,14 @@ test "Condition - wait and signal" { |
| 346 | t.* = try std.Thread.spawn(.{}, MultiWait.run, .{&multi_wait}); | 348 | t.* = try std.Thread.spawn(.{}, MultiWait.run, .{&multi_wait}); |
| 347 | } | 349 | } |
| 348 | | 350 | |
| 349 | std.time.sleep(100 * std.time.ns_per_ms); | 351 | while (true) { |
| | 352 | std.time.sleep(100 * std.time.ns_per_ms); |
| | 353 | |
| | 354 | multi_wait.mutex.lock(); |
| | 355 | defer multi_wait.mutex.unlock(); |
| | 356 | // Make sure all of the threads have finished spawning to avoid a deadlock. |
| | 357 | if (multi_wait.spawn_count == num_threads) break; |
| | 358 | } |
| 350 | | 359 | |
| 351 | multi_wait.cond.signal(); | 360 | multi_wait.cond.signal(); |
| 352 | for (multi_wait.threads) |t| { | 361 | for (multi_wait.threads) |t| { |
| ... | @@ -367,10 +376,12 @@ test "Condition - signal" { | ... | @@ -367,10 +376,12 @@ test "Condition - signal" { |
| 367 | cond: Condition = .{}, | 376 | cond: Condition = .{}, |
| 368 | notified: bool = false, | 377 | notified: bool = false, |
| 369 | threads: [num_threads]std.Thread = undefined, | 378 | threads: [num_threads]std.Thread = undefined, |
| | 379 | spawn_count: std.math.IntFittingRange(0, num_threads) = 0, |
| 370 | | 380 | |
| 371 | fn run(self: *@This()) void { | 381 | fn run(self: *@This()) void { |
| 372 | self.mutex.lock(); | 382 | self.mutex.lock(); |
| 373 | defer self.mutex.unlock(); | 383 | defer self.mutex.unlock(); |
| | 384 | self.spawn_count += 1; |
| 374 | | 385 | |
| 375 | // Use timedWait() a few times before using wait() | 386 | // Use timedWait() a few times before using wait() |
| 376 | // to test multiple threads timing out frequently. | 387 | // to test multiple threads timing out frequently. |
| ... | @@ -394,10 +405,16 @@ test "Condition - signal" { | ... | @@ -394,10 +405,16 @@ test "Condition - signal" { |
| 394 | t.* = try std.Thread.spawn(.{}, SignalTest.run, .{&signal_test}); | 405 | t.* = try std.Thread.spawn(.{}, SignalTest.run, .{&signal_test}); |
| 395 | } | 406 | } |
| 396 | | 407 | |
| 397 | { | 408 | while (true) { |
| 398 | // Wait for a bit in hopes that the spawned threads start queuing up on the condvar | | |
| 399 | std.time.sleep(10 * std.time.ns_per_ms); | 409 | std.time.sleep(10 * std.time.ns_per_ms); |
| 400 | | 410 | |
| | 411 | signal_test.mutex.lock(); |
| | 412 | defer signal_test.mutex.unlock(); |
| | 413 | // Make sure at least one thread has finished spawning to avoid testing nothing. |
| | 414 | if (signal_test.spawn_count > 0) break; |
| | 415 | } |
| | 416 | |
| | 417 | { |
| 401 | // Wake up one of them (outside the lock) after setting notified=true. | 418 | // Wake up one of them (outside the lock) after setting notified=true. |
| 402 | defer signal_test.cond.signal(); | 419 | defer signal_test.cond.signal(); |
| 403 | | 420 | |