#include <stdio.h>
#include <pthread.h>

pthread_t th[2];
pthread_mutex_t mutex;
int thread_nr=1;
int i=1;

void thread1(void *name)
{
 int a;
 /*Mutex setzen*/
 for(a=0;a<10; a++)
  {
   while(thread_nr != 1);
   if(pthread_mutex_lock(&mutex) == 0)
    {
     printf("%d+%d=%d ",i,i,i+i);
     thread_nr = 2;
    }
   else
    {
      printf("locking -> fehlgeschlagen\n");
      exit(0);
    }
 /*Mutex wieder aufheben*/
   if(pthread_mutex_unlock(&mutex) != 0)
    {
      printf("Konnte locking von Thread %ld nicht mehr aufheben\n",pthread_self());
      exit(0);
    }
  }
 pthread_exit((void *) 0);
}


void thread2(void *name)
{
 int b;
 /*Mutex setzen*/
 for(b=0;b<10; b++)
  {
   while(thread_nr != 2);
 /*Mutex setzen*/
   if(pthread_mutex_lock(&mutex)==0)
    {
      printf("\t%d*%d=%d\n",i,i,i*i);
      thread_nr=3;
    }
   else
    {
      printf("locking -> fehlgeschlagen\n");
      exit(0);
    }
 /*Mutex wieder aufheben*/
   if(pthread_mutex_unlock(&mutex) != 0)
    {
      printf("Konnte locking von Thread %ld nicht mehr aufheben\n",pthread_self());
      exit(0);
    }
  }
 pthread_exit((void *) 0);
}


void thread3(void *name)
{
 int c;
 /*Mutex setzen*/
 for(c=0;c<10; c++)
  {
   while(thread_nr != 3);
 /*Mutex setzen*/
   if(pthread_mutex_lock(&mutex)==0)
    {
     i++;
     thread_nr=1;
    }
   else
    {
      printf("locking -> fehlgeschlagen\n");
      exit(0);
    }
 /*Mutex wieder aufheben*/
   if(pthread_mutex_unlock(&mutex) != 0)
    {
      printf("Konnte locking von Thread %ld nicht mehr aufheben\n",pthread_self());
      exit(0);
    }
  }
 pthread_exit((void *) 0);
}


int main()
{
  pthread_t th[3];
  int i;

  /*einen Mutex erzeugen*/
  pthread_mutex_init(&mutex, NULL);

  if(pthread_create(&th[0], NULL, (void *)&thread1, (void *)NULL) != 0)
    {
      fprintf(stderr, "Fehler beim Erzeugen eines Threads.!?!?!\n");
      exit(0);
    }

  if(pthread_create(&th[1], NULL, (void *)&thread2, (void *)NULL) != 0)
    {
      fprintf(stderr, "Fehler beim Erzeugen eines Threads.!?!?!\n");
      exit(0);
    }
  if(pthread_create(&th[2], NULL, (void *)&thread3, (void *)NULL) != 0)
    {
      fprintf(stderr, "Fehler beim Erzeugen eines Threads.!?!?!\n");
      exit(0);
    }

  pthread_join(th[0], NULL);
  pthread_join(th[1], NULL);
  pthread_join(th[2], NULL);

  return 0;
}