
#include "producer_consumer_20011119.h"

int semid;
int shmid;

struct sembuf sops[SEM_NUM];

int inserted_item = 0;

int producer_id;

int main(int argc, char **argv) {

    char myString[MY_STRING_LEN];
    prod_con_shm_t *shmPtr;

    if ( 1 < argc ) {
	producer_id = atoi(argv[1]);
    }
    else producer_id = 0;

    printf("THIS IS PRODUCER %d\n",producer_id);


    if ( 0 > ( shmid = shmget(SHM_KEY,
                              sizeof(prod_con_shm_t),
                              (IPC_CREAT | SHM_PERM)) ) ) {
       perror("consumer: problem with shmget()");
       exit(1);
    }

    if ( 0 > ( shmPtr = shmat(shmid,0,0) ) ) {
       perror("consumer: problem with shmat()");
       exit(1);
    }

    printf("POINTER VALUE shmPtr %04X \n",(int)shmPtr);

    
 

    /*
    semget() - Befehl entspricht dem open(),
    semid (int) entspricht dem Filedescriptor
    SEM_KEY (int) entspricht dem Dateinamen

    mit SEM_NUM wird die # der Semaphoren angegeben,
    die mit semid angesprochen werden sollen.
    SEMAPHORE-SET. Diese werden durch
    (semid,semnum:0..SEM_NUM-1) identifiziert.

    IPC_CREAT heisst "neu ANlegen falls nicht schon
    vorhanden

    SEM_PERM = 0777 bedeutet Zugriffsrechte fuer
    owner group others

    write-permission ist notwendig fuer up/down-ops
    execute-perm. ohne Bedeutung
    */

    if ( 0 > (semid = semget(SEM_KEY,
                             SEM_NUM,
                             (IPC_CREAT | SEM_PERM))) ) {
	perror("producer: problem with semget()");
        exit(1);
    }

    while (1 ) {

        sleep(2); /*--- zur besseren Sichtbarkeit der Abläufe ---*/

	printf("producer: wait for DOWN FULL\n");

        /*
        semop() nimmt array von Befehlen fuer
        die anzusprechenden Semaphoren aus dem Set.
   
	*/
	sops[0].sem_num = SEM_FULL; /* identifiziert Semaphore
                                       aus set */ 
	sops[0].sem_op = -1; /* DOWN um -1 */
	sops[0].sem_flg = 0; /* warte falls blockiert */ 
     
	if ( 0 > semop(semid,&(sops[0]),1) ) {
	    perror("producer: problem with semop()");
	    exit(1);
	}

	printf("producer: FULL DOWN'ed\n");
	printf("producer: wait for DOWN MUTEX\n");

	sops[0].sem_num = SEM_MUTEX;
	sops[0].sem_op = -1;
	sops[0].sem_flg = 0;
     
	if ( 0 > semop(semid,&(sops[0]),1) ) {
	    perror("producer: problem with semop()");
	    exit(1);
	}

	printf("producer: MUTEX DOWN'ed\n");

        /*--- produziere einen neuen String als Item
	  und lege ihn ins Shm auf den STack ---*/ 
        sprintf(myString,"PRODUCER %d : ITEM %d",producer_id,inserted_item++);
        strcpy(&(shmPtr->userData[(shmPtr->numItemsInBuffer)++][0]),
               myString);

        printf("%s\n",myString);
 
	printf("producer: UP MUTEX\n");
    
	sops[0].sem_num = SEM_MUTEX;
	sops[0].sem_op = 1;
	sops[0].sem_flg = 0;
     
	if ( 0 > semop(semid,&(sops[0]),1) ) {
	    perror("producer: problem with semop()");
	    exit(1);
	}    

	printf("producer: UP EMPTY\n");
    
	sops[0].sem_num = SEM_EMPTY;
	sops[0].sem_op = 1;
	sops[0].sem_flg = 0;
     
	if ( 0 > semop(semid,&(sops[0]),1) ) {
	    perror("producer: problem with semop()");
	    exit(1);
	} 

    }
   
    exit(0);

}













