From 818ce700109c959bb670b48e2b6a7e2adaafeb1c Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Tue, 3 Sep 2019 22:41:26 +0200 Subject: GL and SDL does not mixup. Add mmap-sem.c example to fork this in separate processes. --- examples/mmap-sem.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 examples/mmap-sem.c 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 // 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; +} -- cgit v1.2.3