diff options
author | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2019-09-03 22:41:26 +0200 |
---|---|---|
committer | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2019-09-03 22:41:26 +0200 |
commit | 818ce700109c959bb670b48e2b6a7e2adaafeb1c (patch) | |
tree | 38d0a9bb88cf817f9073791928ee104696411322 /examples/mmap-sem.c | |
parent | e17f14db7213fd27c4fa864ca57e6c2b4dbd79ec (diff) | |
download | demoscene-eo-818ce700109c959bb670b48e2b6a7e2adaafeb1c.tar.gz demoscene-eo-818ce700109c959bb670b48e2b6a7e2adaafeb1c.tar.bz2 demoscene-eo-818ce700109c959bb670b48e2b6a7e2adaafeb1c.zip |
GL and SDL does not mixup. Add mmap-sem.c example to fork this in separate processes.
Diffstat (limited to 'examples/mmap-sem.c')
-rw-r--r-- | examples/mmap-sem.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/examples/mmap-sem.c b/examples/mmap-sem.c new file mode 100644 index 0000000..d5a887d --- /dev/null +++ b/examples/mmap-sem.c @@ -0,0 +1,140 @@ +#include <sys/mman.h> // mmap() +#include <unistd.h> // fork() +#include <sys/wait.h> // wait() +#include <semaphore.h> // sem_init(), Link with -pthread +#include <errno.h> // errno +#include <stdint.h> // uint32_t +#include <stdio.h> // 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; +} |