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