#include #include /* bzero */ #include #include #include #define NPROC 2 int inter[NPROC]; int cnt[NPROC]; int turn; /* Stolen from BSD libkern */ #define timevalcmp(tvp, uvp, cmp) \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_sec cmp (uvp)->tv_sec)) static void timevalfix(t1) struct timeval *t1; { if (t1->tv_usec < 0) { t1->tv_sec--; t1->tv_usec += 1000000; } if (t1->tv_usec >= 1000000) { t1->tv_sec++; t1->tv_usec -= 1000000; } } void timevalsub(t1, t2) struct timeval *t1, *t2; { t1->tv_sec -= t2->tv_sec; t1->tv_usec -= t2->tv_usec; timevalfix(t1); } /* end stolen */ void finish(void) { register int i; putchar('\n'); for (i = 0; i < NPROC; ++i) printf("proc %d: %d\n", i, cnt[i]); exit(0); } void catch_intr(int sig) { finish(); } void enter_crit(int pn) { inter[pn] = 1; turn = pn; while (turn == pn && inter[1 - pn]) ; } void leave_crit(int pn) { inter[pn] = 0; } /* Not sure how well this actually works - */ void synch(int pn) { inter[pn] = 0; while (inter[1 - pn]) ; /*printf("synch\n");*/ } void busy_sleep(long usecs) { long stime; struct timeval tv, itv, stv, ztv; itv.tv_usec = usecs; itv.tv_sec = 0; gettimeofday(&stv, NULL); do { gettimeofday(&tv, NULL); timevalsub(&tv, &itv); } while (timevalcmp(&tv, &stv, <)); } void *run(void *ppn) { int pn = (int)ppn; synch(pn); /*printf("Starting thread %d\n", pn);*/ while (cnt[pn] < 10000) { enter_crit(pn); ++cnt[pn]; leave_crit(pn); busy_sleep(250); } finish(); } int main(int ac, char *av[]) { pthread_t pt1, pt2; turn = 0; inter[0] = inter[1] = 1; bzero(cnt, sizeof(cnt)); signal(SIGINT, catch_intr); pthread_create(&pt1, NULL, run, (void *)0); pthread_create(&pt2, NULL, run, (void *)1); pthread_exit(NULL); return 0; /* NOTREACHED */ }