mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 15:03:34 +00:00
93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
#include <pthread.h>
|
|
#include <stdatomic.h>
|
|
#include <stdio.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
|
|
int main() {
|
|
int ws;
|
|
FILE *f;
|
|
pid_t pid;
|
|
pthread_condattr_t ca;
|
|
pthread_mutexattr_t ma;
|
|
struct Shared {
|
|
atomic_int state;
|
|
pthread_cond_t cond;
|
|
pthread_mutex_t lock;
|
|
} *s;
|
|
if (!(f = tmpfile()))
|
|
return 0;
|
|
if (ftruncate(fileno(f), 512))
|
|
return 1;
|
|
if ((s = (struct Shared *)mmap(0, 512, PROT_READ | PROT_WRITE,
|
|
MAP_SHARED | MAP_ANONYMOUS, -1, 0)) ==
|
|
MAP_FAILED)
|
|
return 2;
|
|
if (pthread_condattr_init(&ca))
|
|
return 3;
|
|
if (pthread_mutexattr_init(&ma))
|
|
return 4;
|
|
if (pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED))
|
|
return 5;
|
|
if (pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED))
|
|
return 6;
|
|
if (pthread_cond_init(&s->cond, &ca))
|
|
return 7;
|
|
if (pthread_mutex_init(&s->lock, &ma))
|
|
return 8;
|
|
if (pthread_mutexattr_destroy(&ma))
|
|
return 9;
|
|
if (pthread_condattr_destroy(&ca))
|
|
return 10;
|
|
if ((pid = fork()) == -1)
|
|
return 11;
|
|
if (!pid) {
|
|
alarm(2);
|
|
if (pthread_mutex_lock(&s->lock))
|
|
return 12;
|
|
s->state = 1;
|
|
if (pthread_cond_wait(&s->cond, &s->lock))
|
|
return 13;
|
|
if (pthread_mutex_unlock(&s->lock))
|
|
return 14;
|
|
for (;;)
|
|
if (s->state == 2)
|
|
break;
|
|
if (pthread_mutex_lock(&s->lock))
|
|
return 15;
|
|
if (pthread_cond_signal(&s->cond))
|
|
return 16;
|
|
if (pthread_mutex_unlock(&s->lock))
|
|
return 17;
|
|
_exit(0);
|
|
}
|
|
alarm(2);
|
|
for (;;)
|
|
if (s->state == 1)
|
|
break;
|
|
if (pthread_mutex_lock(&s->lock))
|
|
return 18;
|
|
if (pthread_cond_signal(&s->cond))
|
|
return 19;
|
|
if (pthread_mutex_unlock(&s->lock))
|
|
return 20;
|
|
if (pthread_mutex_lock(&s->lock))
|
|
return 21;
|
|
s->state = 2;
|
|
if (pthread_cond_wait(&s->cond, &s->lock))
|
|
return 22;
|
|
if (pthread_mutex_unlock(&s->lock))
|
|
return 23;
|
|
if (wait(&ws) != pid)
|
|
return 24;
|
|
if (!WIFEXITED(ws))
|
|
return 25;
|
|
if (WEXITSTATUS(ws))
|
|
return 26;
|
|
if (pthread_mutex_destroy(&s->lock))
|
|
return 27;
|
|
if (pthread_cond_destroy(&s->cond))
|
|
return 28;
|
|
return 0;
|
|
}
|