/** producer.c Benjamin Bertka - 23306103 CICS505 OS8 - OS8 - Shared Memory This is the producer. It it waits on the semaphore until room to produce. It is accessing a memory buffer which has a secret bit which saves the state of the producer as it finishes producing the binary file. Since there is no EOF for binary files, whis way we know how to read the end of a binary file. */ #include #include #include #include #include #include #include #include #include #include #define BUFFER_SIZE 10 /*The Default Buffer Size can be changed depending on desired shared memory buffer size */ using namespace std; /** * Writes data to the Sahred memory buffer, uses shared memory pointer, and key */ int writeData(char *filename, char *shm_ptr, key_t key); //Speed control void ptsleep(unsigned int mseconds){ if(mseconds > 0){ clock_t goal = mseconds + clock(); while (goal > clock()); } } /** * The main entry point to the program */ int main(int argc, char**argv){ int shm_handle; //The shared memory handle char* shm_ptr; //The shared memory pointer key_t key = ftok("/home/bbertka/Desktop/test/test.c", 'x'); /* Create the shared memory handle, use an extra byte to keep track of proucer's state */ shm_handle = shmget(key, BUFFER_SIZE + 1, IPC_CREAT | 0644); if(shm_handle == -1) { printf("shared memory creation failed\n"); exit(0); } /* Create the shared memory pointer*/ shm_ptr = (char*)shmat(shm_handle,0,0); if (shm_ptr == (char *) -1) { printf("Shared memory attach failed"); exit(0); } /* Check the args, and begin writing data */ if(argc == 2){ printf("writing... \"%s\"\n", argv[1]); writeData(argv[1], shm_ptr, key); }else{ printf("Usage: ./producer infile\n"); } //Done shmdt(shm_ptr); printf("Producer Closed\n"); return 0; } /** Stores the user supplied filename into main memory, saving into buffer checks the size of the data so producer knows when to stop. */ int writeData(char *filename, char *shm_ptr, key_t key){ FILE *file; char *buffer; size_t result; long lsize; char byte; file = fopen(filename, "rb"); if(file == NULL){ printf("File not opened\n"); exit(1); } fseek(file, 0, SEEK_END); lsize = ftell(file); rewind(file); buffer = (char *)malloc(sizeof(char)*(lsize)); if(buffer == NULL){ printf("Could not allocate buffer\n"); exit(1); } result = fread(buffer, 1, lsize, file); if(result != lsize){ printf("Error loading file\n"); exit(1); } fclose(file); //mutex sem_t *mutex; if((mutex = sem_open("benbertka_semaphore0", O_CREAT, 0644, 1)) == SEM_FAILED){ printf("error openeing semaphore\n"); } //full sem_t *full; if((full = sem_open("benbertka_semaphore1", O_CREAT, 0644, BUFFER_SIZE)) == SEM_FAILED){ printf("error openeing semaphore\n"); } //empty sem_t *empty; if((empty = sem_open("benbertka_semaphore2", O_CREAT, 0644, 0)) == SEM_FAILED){ printf("error openeing semaphore\n"); } //"done with producing" flag set to "not done producing" shm_ptr[BUFFER_SIZE] = 0; for(int i = 0; i < lsize; ++i){ sem_wait(full); //wait for hungry sem_wait(mutex); shm_ptr[i%BUFFER_SIZE] = buffer[i]; //eat byte, and put it in shared location printf("Produce: \t%d\t%c\n", i%BUFFER_SIZE, shm_ptr[i%BUFFER_SIZE] ); //Set secret byte to signal the consumer that producer is done if(i == lsize - 1){ shm_ptr[BUFFER_SIZE] = 1; } ptsleep(200); sem_post(empty); //signal done ptsleep(100); sem_post(mutex); } return 0; }