#include // mmap() #include // fork() #include // wait() #include // sem_init(), Link with -pthread #include // errno #include // uint32_t #include // printf() int do_fork1(); int do_fork2(); int parent(); int worker_gl(); int worker_sdl(); typedef struct { sem_t worker_gl_can_render, worker_sdl_can_render, parent_can_read_result; int scene; uint32_t framebuf[256*256]; } shm_t; shm_t *shm; int main() { shm = mmap(NULL, sizeof(shm_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0); if (sem_init(&shm->worker_gl_can_render, 1, 0) < 0) return 1; if (sem_init(&shm->worker_sdl_can_render, 1, 0) < 0) return 2; if (sem_init(&shm->parent_can_read_result, 1, 0) < 0) return 3; shm->scene = 0; return do_fork1(); } int do_fork1() { switch (fork()) { case -1: return 4; break; case 0: return worker_gl(); break; default: return do_fork2(); break; } } int do_fork2() { switch (fork()) { case -1: return 5; break; case 0: return worker_sdl(); break; default: return parent(); break; } } int parent() { int i, child_status; shm->scene++; printf("parent1 %i\n", shm->scene); for(i=0;i<4;i++) { if ( sem_post(&shm->worker_sdl_can_render) == -1 ) { return 6; } while ( sem_wait(&shm->parent_can_read_result) == -1 ) { switch(errno) { case EINTR: case EAGAIN: break; default: return 7; } } printf("parent2 %i\n", shm->scene); if ( sem_post(&shm->worker_gl_can_render) == -1 ) { return 6; } while ( sem_wait(&shm->parent_can_read_result) == -1 ) { switch(errno) { case EINTR: case EAGAIN: break; default: return 8; } } printf("parent3 %i\n", shm->scene); } if ( wait(&child_status) != -1 ) { if ( child_status > 0 ) return child_status; } if ( wait(&child_status) != -1 ) { if ( child_status > 0 ) return child_status; } return 0; } int worker_gl() { int done=0; while ( !done ) { while ( sem_wait(&shm->worker_gl_can_render) == -1 ) { switch(errno) { case EINTR: case EAGAIN: break; default: return 10; } } printf("worker_gl %i\n", shm->scene); shm->scene++; if ( sem_post(&shm->parent_can_read_result) == -1 ) { return 11; } } return 0; } int worker_sdl() { int done=0; while ( !done ) { while ( sem_wait(&shm->worker_sdl_can_render) == -1 ) { switch(errno) { case EINTR: case EAGAIN: break; default: return 20; } } printf("worker_sdl %i\n", shm->scene); shm->scene++; if ( sem_post(&shm->parent_can_read_result) == -1 ) { return 21; } } return 0; }