cosmopolitan/test/posix/pthread_process_shared_test.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

94 lines
2.1 KiB
C
Raw Permalink Normal View History

#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;
}