I have a thread queue similar to what Casey does in Handmade hero and I would like to be able to pause the main thread while other threads are working. More precisely I want the main thread to wake up when all other threads are paused in WaitForSingleObjectEx on the queue semaphore. At the moment the code looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | uint32_t thread_queue_work( thread_queue_t* queue, ... ) {
uint32_t result = 0;
...
ReleaseSemaphore( queue->semaphore, 1, 0 );
...
return result;
}
DWORD thread_main( void* thread_data ) {
thread_queue_t* queue = ( thread_queue_t* ) thread_data;
while ( !queue->terminate ) {
if ( !thread_do_work( queue ) ) {
WaitForSingleObjectEx( queue->semaphore, INFINITE, 0 );
}
}
return 0;
}
void thread_complete_queue( thread_queue_t* queue ) {
while ( queue->completion_count != queue->completion_goal ) {
thread_do_work( queue );
}
}
int main( int argc, char** argv ) {
thread_queue_t queue = thread_queue_init( );
thread_queue_work( &queue, ... );
thread_queue_work( &queue, ... );
thread_complete_queue( &queue );
thread_queue_work( &queue, ... );
thread_queue_work( &queue, ... );
thread_complete_queue( &queue );
return 0;
}
|
But if there is only two tasks to do and they take some time, thread_complete_queue is mostly a busy loop which I would like to avoid. Also not all program will use thread_complete_queue, so the thread must not do something that would fail if thread_complete_queue is not called.
Is there a good way to do this ? Is it possible to wait for the semaphore to "be 0" ? Should I use CreateEvent to create an event for each thread and use WaitForMultipleObjects ? Would that work if thread_complete_queue isn't called ? Would it work if I have several hundred threads ?