#include <stdio.h> /* printf */
#include <stdlib.h> /* atoi */
#include <pthread.h> /* thread create/join/exit */
int Loops;
int Count;
int turn;
int ready[2] = {0, 0};
int lock;
typedef void (*LockFn)(int);
LockFn LOCK;
LockFn UNLOCK;
void Lock0(int me)
{
}
void Unlock0(int me)
{
}
void Lock1(int me)
{
while (lock == 1)
continue;
lock = 1;
}
void Unlock1(int me)
{
lock = 0;
}
void Lock2(int me)
{
while (turn != me)
continue;
}
void Unlock2(int me)
{
turn = 1 - me;
}
void Lock3(int me)
{
ready[me] = 1;
while (ready[1 - me])
continue;
}
void Unlock3(int me)
{
ready[me] = 0;
}
void Lock4(int me)
{
int you = 1 - me;
turn = you;
ready[me] = 1;
while (ready[you] && (turn == (you)))
continue;
}
void Unlock4(int me)
{
ready[me] = 0;
}
void Lock5(int me)
{
int you = 1 - me;
turn = you;
ready[me] = 1;
__sync_synchronize();
while (ready[you] && (turn == you))
continue;
}
void Unlock5(int me)
{
ready[me] = 0;
}
void *Increment(void *p)
{
int i, id = *(int *)p;
for (i = 0; i < Loops; i++)
{
LOCK(id);
Count++;
UNLOCK(id);
}
return 0;
}
int main(int argc, char **argv)
{
pthread_t thread_id0, thread_id1;
int id0 = 0, id1 = 1;
LockFn locks[] = {Lock0, Lock1, Lock2, Lock3, Lock4, Lock5};
LockFn unlocks[] = {Unlock0, Unlock1, Unlock2, Unlock3, Unlock4, Unlock5};
LOCK = locks[0];
UNLOCK = unlocks[0];
if (argc < 3)
{
printf("Usage: %s <LOCK_FN> <ITERATIONS>\n", argv[0]);
printf("\n");
printf("where: LOCK_FN is the lock function to test:\n");
printf(" 0 - No locking at all\n");
printf(" 1 - Uses a single global lock variable, no mutual exclusion.\n");
printf(" 2 - Taking turns, no shared memory, mutual exclusion but non-bounded waiting.\n");
printf(" 3 - Yielding to other thread. Causes a race condition and will likely hang.\n");
printf(" 4 - Peterson's Solution. Fails on modern architectures.\n");
printf(" 5 - Peterson's Solution with a memory barrier. Works but the barrier isn't implemented in all systems.\n");
printf("\n");
printf(" ITERATIONS is the number of times each thread will increment the shared variable x 1,000,000\n");
printf("\n");
printf("Example: lock_test 5 10 \n");
printf(" runs Lock5/Unlock5 test with 10,000,000 iterations.\n");
return -1;
}
LOCK = locks[atoi(argv[1])];
UNLOCK = unlocks[atoi(argv[1])];
Loops = 1000 * 1000 * atoi(argv[2]);
pthread_create(&thread_id0, 0, Increment, &id0);
pthread_create(&thread_id1, 0, Increment, &id1);
pthread_join(thread_id0, 0);
pthread_join(thread_id1, 0);
printf("------------------\n");
printf("Count = %i\n", Count);
return 0;
}