diff --git a/include/shared.h b/include/shared.h index f42ff0c..e6b4317 100644 --- a/include/shared.h +++ b/include/shared.h @@ -8,11 +8,16 @@ typedef struct SharedStruct { int buffer[10]; int count[10]; + int producerCount; + int consumerCount; sem_t mutex; sem_t empty; sem_t full; } SharedStruct; -void SharedStructInit(SharedStruct* sharedMem); +int IsProductionFinished(SharedStruct* sharedMem); +void SharedStructInit(SharedStruct* sharedMem, int producers, int consumers); +void PrintBuffer(SharedStruct* sharedMem); +void PrintNumberCount(SharedStruct* sharedMem); #endif \ No newline at end of file diff --git a/src/consumer.c b/src/consumer.c index a73365e..228233d 100644 --- a/src/consumer.c +++ b/src/consumer.c @@ -6,6 +6,8 @@ void StartConsumer(SharedStruct* sharedMem); void Consume(SharedStruct* sharedMem); +int GetNextUsedSlot(SharedStruct* sharedMem); +void SemaphoreCleanup(SharedStruct* sharedMem); void consume_item(int item, SharedStruct* sharedMem); int remove_item(SharedStruct* sharedMem); @@ -20,18 +22,20 @@ int main(int argc, char* argv[]) int sharedID = StringToNumber(argv[1]); SharedStruct* sharedMem = shmat(sharedID, NULL, 0); StartConsumer(sharedMem); + PrintNumberCount(sharedMem); return 0; } // Starts the consumer process. void StartConsumer(SharedStruct* sharedMem) { - for (int i = 0; i < 5; i++) + while (!IsProductionFinished(sharedMem)) { sem_wait(&sharedMem->full); Consume(sharedMem); sem_post(&sharedMem->empty); } + SemaphoreCleanup(sharedMem); } // Takes a number from the shared memory and consumes it. @@ -40,12 +44,52 @@ void Consume(SharedStruct* sharedMem) int consumeNum; sem_wait(&sharedMem->mutex); consumeNum = remove_item(sharedMem); - consume_item(consumeNum, sharedMem); - printf("%d was consumed.\n", consumeNum); + if (consumeNum >= 0) + consume_item(consumeNum, sharedMem); sem_post(&sharedMem->mutex); return; } +int GetNextUsedSlot(SharedStruct* sharedMem) +{ + int slot = -1; + for (int i = 0; i < 10; i++) + { + if (sharedMem->buffer[i] > -1) + { + slot = i; + return slot; + } + } + return slot; +} + +// Weird semaphore math that cleans up the stuck forks +void SemaphoreCleanup(SharedStruct* sharedMem) +{ + int semMath = 2*(sharedMem->consumerCount) + (sharedMem->producerCount) - 1; + // int semCheckMutex; + int semCheckEmpty; + // int semCheckFull; + // sem_getvalue(&sharedMem->mutex, &semCheckMutex); + sem_getvalue(&sharedMem->empty, &semCheckEmpty); + // sem_getvalue(&sharedMem->full, &semCheckFull); + // if (semCheckMutex > 0) + // sem_post(&sharedMem->mutex); + if (semCheckEmpty < semMath) + { + sem_post(&sharedMem->full); + exit(0); + } + // sem_post(&sharedMem->empty); + // if (semCheckFull > 0) + // sem_post(&sharedMem->full); + // printf("Value of semCheckMutex: %d\n", semCheckMutex); + // printf("Value of semCheckEmpty: %d\n", semCheckEmpty); + // printf("Value of semCheckFull: %d\n", semCheckFull); + return; +} + // Increments the count of numbers generated so far in shared memory. void consume_item(int item, SharedStruct* sharedMem) { @@ -56,7 +100,10 @@ void consume_item(int item, SharedStruct* sharedMem) // Take item out of shared memory. int remove_item(SharedStruct* sharedMem) { - int item = sharedMem->buffer[0]; - sharedMem->buffer[0] = -1; + int slot = GetNextUsedSlot(sharedMem); + if (slot < 0) + return -1; + int item = sharedMem->buffer[slot]; + sharedMem->buffer[slot] = -1; return item; } \ No newline at end of file diff --git a/src/driver.c b/src/driver.c index d9326ef..b2d93ef 100644 --- a/src/driver.c +++ b/src/driver.c @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) exit(1); } SharedStruct* sharedMem = shmat(sharedID, NULL, 0); - SharedStructInit(sharedMem); + SharedStructInit(sharedMem, producerAmount, consumerAmount); CreateChildForks(producerAmount, 0, sharedID); CreateChildForks(consumerAmount, 1, sharedID); return 0; diff --git a/src/producer.c b/src/producer.c index 44711ec..a28fba8 100644 --- a/src/producer.c +++ b/src/producer.c @@ -9,7 +9,7 @@ int GetNextFreeSlot(SharedStruct* sharedMem); void StartProducer(SharedStruct* sharedMem); void Produce(SharedStruct* sharedMem); int produce_item(void); -int insert_item(int item, SharedStruct* sharedMem); +void insert_item(int item, SharedStruct* sharedMem); // Checks for SharedID, then begins producing numbers into shared memory. int main(int argc, char* argv[]) @@ -31,12 +31,15 @@ int main(int argc, char* argv[]) int GetNextFreeSlot(SharedStruct* sharedMem) { int slot = -1; - for (int i = 0; i < 10; i++) + while(1) { - if ((sharedMem->buffer[i] != -1) && (sharedMem->buffer[(i+1)%10] == -1)) + for (int i = 0; i < 10; i++) { - slot = (i+1)%10; - return slot; + if (sharedMem->buffer[i] == -1) + { + slot = i; + return slot; + } } } return slot; @@ -45,8 +48,7 @@ int GetNextFreeSlot(SharedStruct* sharedMem) // Starts the producer process. void StartProducer(SharedStruct* sharedMem) { - // TODO: For testing purposes, revert max to 100 - for (int i = 0; i < 5; i++) + for (int i = 0; i < 100; i++) { sem_wait(&sharedMem->empty); Produce(sharedMem); @@ -61,7 +63,6 @@ void Produce(SharedStruct* sharedMem) sem_wait(&sharedMem->mutex); insertNum = produce_item(); insert_item(insertNum, sharedMem); - printf("%d is inserted.\n", insertNum); sem_post(&sharedMem->mutex); return; } @@ -73,9 +74,7 @@ int produce_item(void) } // Insert a number into the shared memory. -// TODO: Reimplement insertion using the next slot from GetNextFreeSlot(). -int insert_item(int item, SharedStruct* sharedMem) +void insert_item(int item, SharedStruct* sharedMem) { - sharedMem->buffer[0] = item; - return 1; + sharedMem->buffer[GetNextFreeSlot(sharedMem)] = item; } \ No newline at end of file diff --git a/src/shared.c b/src/shared.c index a375a41..4f85e03 100644 --- a/src/shared.c +++ b/src/shared.c @@ -1,17 +1,48 @@ #include #include "shared.h" +int IsProductionFinished(SharedStruct* sharedMem) +{ + int producedTotal = 0; + int potentitalTotal = (sharedMem->producerCount)*100; + for (int i = 0; i < 10; i++) + producedTotal += sharedMem->count[i]; + return (producedTotal == potentitalTotal); +} + +void PrintBuffer(SharedStruct* sharedMem) +{ + for (int i = 0; i < 10; i++) + printf("Buffer slot %d: %d\n", i, sharedMem->buffer[i]); + return; +} + +void PrintNumberCount(SharedStruct* sharedMem) +{ + int consumedTotal = 0; + for (int i = 0; i < 10; i++) + { + consumedTotal += sharedMem->count[i]; + printf("Number %d: %d time(s)\n", i, sharedMem->count[i]); + } + printf("Total produced: %d\n", (sharedMem->producerCount)*100); + printf("Total consumed: %d\n", consumedTotal); + return; +} + // Initializes the struct in shared memory -void SharedStructInit(SharedStruct* sharedMem) +void SharedStructInit(SharedStruct* sharedMem, int producers, int consumers) { for (int i = 0; i < 10; i++) { sharedMem->buffer[i] = -1; sharedMem->count[i] = 0; } + sharedMem->producerCount = producers; + sharedMem->consumerCount = consumers; sem_init(&sharedMem->mutex, 1, 1); - sem_init(&sharedMem->empty, 1, 1); - sem_init(&sharedMem->full, 1, 1); + sem_init(&sharedMem->empty, 1, producers+consumers); + sem_init(&sharedMem->full, 1, 0); } // Takes array of letters and turns it into a number