#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <pthread.h> 
#include <semaphore.h> 
void * thread_func_A(void *arg);
void * thread_func_B(void *arg);
void * thread_func_C(void *arg);
void * thread_func_D(void *arg);
void * thread_func_E(void *arg);
void * thread_func_F(void *arg);
sem_t sem_A, sem_B, sem_C, sem_D, sem_E, sem_F; 

int rc; 
int b=0,c=0,d=0, e=0;

pthread_t thread_A, thread_B, thread_C, thread_D, thread_E, thread_F; 

void * thread_func_A(void *arg) 
{ float A=1, i; 
printf("A stream Started\n"); 
	for (i=1;i<6;i++) 
	A*=i; 

sem_post(&sem_A); 
//pthread_create(&thread_C, NULL, thread_func_C,NULL);
{ 
rc = pthread_create(&thread_C, NULL, thread_func_C, NULL); 
if (rc != 0) { perror("Error: cann't be created C"); 
return EXIT_FAILURE; 
}
} 
//pthread_create(&thread_B, NULL, thread_func_B,NULL);
{ 
rc = pthread_create(&thread_B, NULL, thread_func_B, NULL); 
if (rc != 0) { perror("Error: cann't be created B"); 
return EXIT_FAILURE; 
}
}
//pthread_create(&thread_D, NULL, thread_func_D,NULL);
{ 
rc = pthread_create(&thread_D, NULL, thread_func_D, NULL); 
if (rc != 0) { perror("Error: cann't be created D"); 
return EXIT_FAILURE; 
} 
}
}
void * thread_func_B(void *arg) 
{float B=1, i;
printf("B stream Started\n"); 
	for (i=1;i<10;i++) 
	B*=i; 
sem_post(&sem_B);
b=1;
sem_wait(&sem_C); 
if ((b==1 && c==0)||(b==1 && c==1))
{
//pthread_create(&thread_E, NULL, thread_func_E,NULL);
{ 
rc = pthread_create(&thread_E, NULL, thread_func_E, NULL); 
if (rc != 0) { perror("Error: cann't be created E"); 
return EXIT_FAILURE; 
}
} 
printf("B Generates a stream in E\n");
}
}
void * thread_func_C(void *arg) 
{float C=1, i;
printf("C stream Started\n"); 
	for (i=1;i<15;i++) 
	C*=i; 
sem_post(&sem_C); 
c=1;
sem_wait(&sem_B);
if (b==0 && c==1)
{
//pthread_create(&thread_E, NULL, thread_func_E,NULL);
{ 
rc = pthread_create(&thread_E, NULL, thread_func_E, NULL); 
if (rc != 0) { perror("Error: cann't be created E"); 
return EXIT_FAILURE; 
}
} 
printf("Ñ Generates a stream in E\n");
}
}
void * thread_func_E(void *arg) 
{float E=1, i;
printf("E stream Started\n"); 
	for (i=1;i<13;i++) 
	E*=i; 

sem_post(&sem_E); 
e=1;
sem_wait(&sem_D);
if ((e==1 && d==0)||(e==1 && d==1))
{
//pthread_create(&thread_F, NULL, thread_func_F,NULL);
{ 
rc = pthread_create(&thread_F, NULL, thread_func_F, NULL); 
if (rc != 0) { perror("Error: cann't be created F"); 
return EXIT_FAILURE; 
}
}
printf("E Generates a stream in F\n"); 
}
}
void * thread_func_D(void *arg) 
{float D=1, i; 
printf("D stream Started\n"); 
	for (i=1;i<20;i++) 
	D*=i; 

sem_post(&sem_D); 
d=1;
sem_wait(&sem_E);
if (e==0 && d==1) 
{
//pthread_create(&thread_F, NULL, thread_func_F,NULL);
{ 
rc = pthread_create(&thread_F, NULL, thread_func_F, NULL); 
if (rc != 0) { perror("Error: cann't be created F"); 
return EXIT_FAILURE; 
}
}
printf("D Generates a stream in F\n");
}
}
void * thread_func_F(void *arg) 
{ float F=1, i;
printf("F stream Started\n"); 

	for (i=1;i<6;i++) 
	F*=i; 
sem_post(&sem_F); 
}
main(int argc, char * argv[]) 
{ 
printf ("\033[0d\033[2J"); 

sem_init(&sem_A, 0, 0 ); 
sem_init(&sem_B,0,0 ); 
sem_init(&sem_C,0,0 ); 
sem_init(&sem_D,0,0);
sem_init(&sem_E,0,0 ); 
sem_init(&sem_F,0,0);

//pthread_create(&thread_A, NULL, thread_func_A,NULL);
{ 
rc = pthread_create(&thread_A, NULL, thread_func_A, NULL); 
if (rc != 0) { 
perror("Error: cann't be created A"); 
return EXIT_FAILURE; 
} 
sem_wait(&sem_F); 
} 
}
