Files
c3c/test/unit/stdlib/threads/simple_thread.c3
Sander van den Bosch 3f20e5af1d add join for ThreadPool without destroying the threads (#2579)
* add join for ThreadPool without destroying the threads
* Make the main Thread block waiting for the worker threads to finish instead of buzy looping and do proper initialization and freeing of all variables.
* Updated test to use `atomic_store` and  take into account the maximum queue size of the threadpool.
* - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
- Return of Thread/Mutex/CondVar `destroy()` is now "@maydiscard" and should be ignored. It will return void in 0.8.0.
- Return of Mutex `unlock()` and `lock()` is now "@maydiscard" and should be ignored. They will return void in 0.8.0.
- Return of ConditionVariable `signal()` `broadcast()` and `wait()` are now "@maydiscard". They will return void in 0.8.0.
- Return of Thread `detatch()` is now "@maydiscard". It will return void in 0.8.0.
- Buffered/UnbufferedChannel, and both ThreadPools have `@maydiscard` on a set of functions. They will retunr void in 0.8.0.
- Pthread bindings correctly return Errno instead of CInt.
- Return of Thread `join()` is now "@maydiscard".

---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
2025-12-06 23:54:04 +01:00

105 lines
1.5 KiB
Plaintext

import std::thread;
import std::io;
int a;
fn void testrun() @test
{
Thread t;
a = 0;
t.create(fn int(void* arg) { a++; return 0; }, null)!!;
assert(t.join()!! == 0);
assert(a == 1);
t.create(fn int(void* arg) { return 10; }, null)!!;
assert(t.join()!! == 10);
}
Mutex m_global;
fn void testrun_mutex()
{
Thread[20] ts;
a = 0;
m_global.init()!!;
foreach (&t : ts)
{
t.create(fn int(void* arg) {
m_global.lock();
defer m_global.unlock();
a += 10;
thread::sleep_ms(5);
a *= 10;
thread::sleep_ms(5);
a /= 10;
thread::sleep_ms(5);
a -= 10;
thread::sleep_ms(5);
a++;
return 0;
}, null)!!;
}
foreach (&t : ts)
{
assert(t.join()!! == 0);
}
assert(a == ts.len);
m_global.destroy();
}
fn void testrun_mutex_try() @test
{
Mutex m;
m.init()!!;
m.lock();
assert(m.try_lock() == false);
m.unlock();
assert(m.try_lock() == true);
m.unlock();
}
int val_mutex = 0;
fn void testrun_mutex_timeout() @test
{
TimedMutex m;
m.init()!!;
m.lock();
Thread t;
val_mutex = 0;
t.create(fn int(void* arg) {
TimedMutex* m = arg;
if (try m.lock_timeout(20))
{
val_mutex = 1;
}
else
{
val_mutex = 2;
}
return 0;
}, &m)!!;
t.join();
assert(val_mutex == 2);
m.unlock();
m.lock_timeout(20)!!;
m.unlock();
}
int x_once = 100;
fn void call_once()
{
x_once += 100;
}
fn void testrun_once() @test
{
OnceFlag once;
once.call(&call_once);
assert(x_once == 200);
once.call(&call_once);
assert(x_once == 200);
}