diff options
-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; +} |