#include #include #include #include #include #include #include #include #include #include struct cond { struct umtx lock; int count; }; int main() { int error; int pid; long tid; struct cond *p = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); if (p == MAP_FAILED) err(1, "mmap"); /* set shared before fork()ing and doing any locking on the area. */ if (minherit(p, 4096, INHERIT_SHARE) == -1) err(2, "minherit"); p->lock.u_owner = 0; /* * We will let thread sleep on the address, * however the count value is not used by kernel, * kernel only use the address. */ p->count = 0; thr_self(&tid); umtx_lock(&p->lock, tid); pid = fork(); if (pid == -1) err(3, "fork"); if (pid == 0) { /* parent */ printf("parent hold lock, sleep 3 seconds\n"); sleep(3); printf("parent unlocks lock\n"); umtx_unlock(&p->lock, tid); sleep(3); umtx_lock(&p->lock, tid); printf("parent is signaling condition variable.\n"); umtx_wake(&p->count, 0); umtx_unlock(&p->lock, tid); } else { /* child */ thr_self(&tid); error = umtx_lock(&p->lock, tid); if (error) err(3, "umtx_lock returns: %d", error); printf("child locked mutex, sleeps on condition variable...\n"); error = umtx_wait(&p->lock, tid, &p->count); if (error) err(4, "umtx_wait returns: %d", error); printf("child return\n"); } return (0); }