#include <stdio.h>
#include <sys/ipc.h>
#include <sys/mutex.h>
#include <sys/shm.h>
#include <xparameters.h>
// #include <xuartlite_l.h>

void consumer( int b ) ;
void producer (int b);

mutex *sem, *empty ;
int flag = 0 ;
int shmid ;

main() {
	char i,j = 0 ;
  	char *mem ;
	
	mutex_init( &sem ) ;
	//mutex_init( &empty ) ;

	shmid = shmget( 5, 100, IPC_CREAT ) ;
	if( shmid == -1 ) {
		print("Error creating shared memory\r\n") ;
		process_exit() ;
	}
	print("Got the Shm ID\r\n") ;

  	j = thread_create( producer ,2,8  ) ; 
        i = thread_create( consumer,1,8  ) ;

        while(flag !=2);
        print("Parent\r\n");
        // mutex_destroy( sem ) ;
 process_exit();
}

void producer( int b ) 
{
	char i = 0 ;
	char *mem ;
	char j ;
        char repeat = 0;

	/*
	 * Producer
	 */
	mem = (char*)shmat( shmid, 0, 0 ) ;
	if( mem == NULL ){
		print("Error atttaching shared memory\r\n") ;
		process_exit() ;
	}
	i = 0 ;
  	while(i<6) { // send 6 items of data to consumer
         
	    	mutex_lock( sem ) ;	
					
		if( flag == 0 ){/* Produce the resource */
		print("P: ") ;
	   	// XUartLite_SendByte(XPAR_MYUART_BASEADDR, i+'a') ;
                outbyte((i+'a'));
		print("\r\n") ;
		*(mem + i) = i+'a' ;
		flag = 1 ;
                i++ ; repeat = 0;
		}
                else {/* Wait for consumer to consume */
                  if (repeat == 0) {
		print("P :-(\r\n") ;
                repeat = 1;
                  }
                }
		mutex_unlock( sem ) ;	/* Signal the consumer - resource */
		if (repeat)
                  process_yield(); // should be thread_yield
  	}
	thread_exit() ;
} 

void consumer( int b ) 
{
	char i = 0 ;
	char *mem ;
	char j ;
	char repeat = 0;

	mem = (char *)shmat( shmid, 0, 0 ) ;
	if( mem == NULL ){
		print("Error atttaching shared memory\r\n") ;
		process_exit() ;
	}
	print("Consumer awake..\r\n") ;
  	while(i<6) {
	    	mutex_lock( sem ) ;	/* Wait for resource by producer */
					/* Consume the resource */
		if( flag == 1 ){
		j = *(mem+i) ;
		print("C: ") ;
	   	// XUartLite_SendByte(XPAR_MYUART_BASEADDR, j) ;
                outbyte(j);
		print("\r\n") ;
		flag = 0 ;
                i++; repeat = 0;
		}
                else {
                  if (repeat == 0) {
		print("C :-(\r\n") ;
                repeat = 1;
                  }
                }
		mutex_unlock( sem ) ;	/* Signal the producer */
                if(repeat)
                  process_yield(); // should be thread_yield()
  	}
	flag = 2; // at this point nobody else is using flag so there is no need to wait for mutex semaphore
        thread_exit() ;
} 

