/* * This file is part of Jehanne. * * Copyright (C) 2015 Giacomo Tesio * * Jehanne is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2 of the License. * * Jehanne is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jehanne. If not, see . */ #include #include QLock rl; Rendez rStart; Rendez rCompleted; int64_t elapsedInWaiter, resInWaiter; int verbose = 0; int failOnTimeout(void *v, char *s) { if(strncmp(s, "alarm", 4) == 0){ if(verbose) print("%d: noted: %s\n", getpid(), s); print("FAIL: timeout\n"); exits("FAIL"); } return 0; } void spawnWaiter(Lock *l) { int pid; int64_t start; switch((pid = rfork(RFMEM|RFPROC|RFNOWAIT))) { case 0: /* wait for the alwaysLocked to be locked by the main process */ qlock(&rl); while(resInWaiter == 0xff) rsleep(&rStart); start = nsec(); resInWaiter = lockt(l, 6000); elapsedInWaiter = (nsec() - start) / (1000 * 1000); if(verbose) print("lockt returned %d, elapsed = %d ms\n", resInWaiter, elapsedInWaiter); rwakeup(&rCompleted); qunlock(&rl); exits(0); break; case -1: print("spawnWaiter: %r\n"); exits("rfork fails"); break; default: if(verbose) print("spawn waiter %d\n", pid); break; } } void main(void) { int64_t start, elapsed, res; static Lock l; rfork(RFNOTEG|RFREND); rStart.l = &rl; rCompleted.l = &rl; resInWaiter = 0xff; spawnWaiter(&l); jehanne_lock(&l); alarm(20000); /* global timeout, FAIL if reached */ if (!atnotify(failOnTimeout, 1)){ fprint(2, "%r\n"); exits("atnotify fails"); } /* verify that lockt returns 0 on timeout */ start = nsec(); res = lockt(&l, 1000); elapsed = (nsec() - start) / (1000 * 1000); if(verbose) print("lockt returned %d, elapsed = %d ms\n", res, elapsed); if(res != 0 || elapsed < 900 || elapsed > 1300){ print("FAIL: lockt timeout\n"); exits("FAIL"); } /* verify that lockt returns 1 if the lock is released and * it can take it */ resInWaiter = -1; qlock(&rl); rwakeupall(&rStart); qunlock(&rl); sleep(1200); jehanne_unlock(&l); qlock(&rl); while(elapsedInWaiter == 0) rsleep(&rCompleted); qunlock(&rl); if(resInWaiter != 1 || elapsedInWaiter < 1100 || elapsedInWaiter > 1500){ print("FAIL: lockt delayed acquisition\n"); exits("FAIL"); } print("PASS\n"); exits("PASS"); }