summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/mmap-sem.c140
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;
+}