Computer Science 354
Operating Systems
Dickinson College
Spring Semester 2000
Grant Braught
/*
* terror.c
* Example program that demonstrates
* critical sections and the existence
* of a race condition.
*
* Compile with:
* cc terror.c -o terror -lpthread -lm
*
* Grant Braught
* Dickinson College
* (c) 2000
*/
#define _REENTRANT
#include
#include
#include
#include
#include
void *Thread_Func1(void *);
void *Thread_Func2(void *);
// Define some global variables that the threads will use.
int Global_Var;
double Global_Var2 = 7.6789;
double Global_Var3 = 3.21234;
double Global_Var4 = 7.6789;
double Global_Var5 = 3.21234;
int main()
{
pthread_t tid1, tid2;
void *arg;
int i;
printf("\nterror.c\n\n");
printf("Demonstrate the thread synchronization problem.\n");
printf("Create 2 threads:\n");
printf("\tOne adds 1 to a global variable 10,000 times.\n");
printf("\tOne subtracts 1 from the same globla variable 10,000 times.\n");
printf("The process is repeated 40 times to increase the likelyhood\n");
printf("of seeing an error.\n");
printf("If the threads are synchronized the value should always\n");
printf("be zero. However, that is not the case...\n\n");
printf("Global Variable Values\n");
printf("-----------------------------------------------------------------------\n");
for (i=1; i<=40; i++)
{
// Initialize the global variable.
Global_Var = 0;
// Create the two threads...
pthread_create(&tid1, NULL, Thread_Func1, arg);
pthread_create(&tid2, NULL, Thread_Func2, arg);
// Wait for the threads to finish...
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
// Write out the value of the global variable.
printf("%d\t\t",Global_Var);
if (i % 5 == 0)
printf("\n");
}
}
void *Thread_Func1(void *junk)
{
int i;
// Each thread will do the addition or subtraction 10,000 times.
// This is done because it is very unlikely that the thread will
// be interrupted at a point where an error will be created.
// However, it is not impossible. Therefore, repeating the instr.
// lots of times will increase the likelyhood of seeing an error.
// The pow instructions are included to make the addition and
// subtraction operations take more time. This increases the
// likelyhood of a thread being interrupted.
for (i=1; i<=10000; i++)
{
Global_Var = Global_Var +
(int) pow(Global_Var2,Global_Var3) -
(int) pow(Global_Var4,Global_Var5) +
(int) pow(Global_Var3,Global_Var2) -
(int) pow(Global_Var5,Global_Var4) +
1;
}
}
void *Thread_Func2(void *junk)
{
int i;
for (i=1; i<=10000; i++)
{
Global_Var = Global_Var +
(int) pow(Global_Var2,Global_Var3) -
(int) pow(Global_Var4,Global_Var5) +
(int) pow(Global_Var3,Global_Var2) -
(int) pow(Global_Var5,Global_Var4) -
1;
}
}