I think the question was about whose responsibility is it to manage threads. Is it the platform layer, or the game layer.
If it's the responsibility of the platform, you have code that 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 | /* In the platform layer */
void thread_execute( ){
while ( true ){
wait_for_work( );
game_function( game_data ); /* This executes game code from the platform layer */
signal_finished( );
}
}
int platform_main( ){
threads t[ x ] = { 0 };
for ( int i = 0; i < x; i++ ) {
t[ i ] = thread_create( );
}
...
while ( running ) {
game_update_and_render( );
}
}
/* In the game layer*/
int game_main( ){
...
platform_add_work_in_thread_queue( game_function, game_data );
...
}
|
If it's the responsibility of the game:
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 | /* In the platform layer*/
int thread_create( void thread_function( thread_data* ) ){ ... }
int platform_main( ) {
while ( running ) {
game_update_and_render( );
}
}
/* In the game layer */
void game_thread_function( ) {
while ( true ) {
thread_wait_for_work( );
game_func( game_data );
thread_signal_finished( );
}
}
int game_main( ) {
...
/* executed once */
thread t[x] = { 0 };
for ( int i = 0; i < x; i++ ) {
thread_create( game_thread_function );
}
/* when needed */
add_work_in_work_queue( game_func, game_data );
...
}
|
The second case looks very similar to the first one, the changes are basically that some code switched from the platform layer to the game layer. But to allow that, the platform layer has to abstract how threads work on every platform we want the application to run on to provide a common API. Creating, waiting and signaling thread is pretty different on each platform, so it adds complexity when none is necessary.
Threading is used in two cases: when you need more performance and want to execute more instructions at the same time, or when you want to do some work without blocking the main thread. I/O is in that second case. You don't want your application to stop while you're loading your textures, or waiting for a network response. Here once again, the API between platform for asynchronous I/O is different so you don't want to abstract that.