#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
sem_t mutex;
sem_t empty;
sem_t full;
sem_t limit;
int p_shared_value = 0;
int *buffer;
int in = 0;
int out = 0;
typedef struct _data_t {
int tid;
int buffer_size;
int upper_limit;
} data_t;
void *produce(void *arg) {
data_t *passedData = (data_t *) arg;
while (1) {
sem_wait(&limit);
if (passedData->upper_limit == p_shared_value) {
printf("Producer[#%d] terminated\n", passedData
->tid
); sem_post(&limit);
pthread_exit(NULL);
} else {
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = p_shared_value;
printf("[PRODUCED] at index : %d, by TID : %d VALUE : %d\n", in
, passedData
->tid
, p_shared_value
); p_shared_value++;
in = (in + 1) % passedData->buffer_size;
sem_post(&mutex);
sem_post(&limit);
sem_post(&full);
}
}
}
void *consume(void *arg) {
data_t *passedData = (data_t *) arg;
while (1) {
if (passedData->upper_limit == p_shared_value) {
printf("Consumer[#%d] terminated\n", passedData
->tid
); pthread_exit(NULL);
} else {
sem_wait(&full);
sem_wait(&mutex);
printf("[CONSUMED] at index : %d, by TID : %d VALUE : %d\n", out
, passedData
->tid
, buffer
[out
]); out = (out + 1) % passedData->buffer_size;
sem_post(&mutex);
sem_post(&empty);
}
}
}
int main(int argc, char *argv[]) {
unsigned int buffer_size
= (unsigned int) atoi(argv
[1]); int num_producers
= atoi(argv
[2]); int num_consumers
= atoi(argv
[3]); int upper_limit
= atoi(argv
[4]);
buffer
= malloc(buffer_size
* sizeof(int));
sem_init(&empty, 0, buffer_size);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
sem_init(&limit, 0, 1);
pthread_t c_threads[num_consumers];
pthread_t p_threads[num_producers];
puts("Passed arguments"); printf("%d - %d - %d - %d\n", buffer_size
, num_producers
, num_consumers
, upper_limit
); puts("************************");
data_t p_structs[num_producers];
data_t c_structs[num_consumers];
for (int i = 0; i < num_producers; i++) {
p_structs[i].buffer_size = buffer_size;
p_structs[i].tid = i;
p_structs[i].upper_limit = upper_limit;
pthread_create(&(p_threads[i]), NULL, &produce, ((void *) (&p_structs[i])));
}
for (int i = 0; i < num_consumers; i++) {
c_structs[i].buffer_size = buffer_size;
c_structs[i].tid = i;
c_structs[i].upper_limit = upper_limit;
pthread_create(&c_threads[i], NULL, &consume, ((void *) (&c_structs[i])));
}
for (int i = 0; i < num_producers; i++) {
pthread_join(p_threads[i], NULL);
}
for (int i = 0; i < num_consumers; i++) {
pthread_join(c_threads[i], NULL);
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzZW1hcGhvcmUuaD4KI2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKc2VtX3QgbXV0ZXg7CnNlbV90IGVtcHR5OwpzZW1fdCBmdWxsOwpzZW1fdCBsaW1pdDsKCmludCBwX3NoYXJlZF92YWx1ZSA9IDA7CgppbnQgKmJ1ZmZlcjsKaW50IGluID0gMDsKaW50IG91dCA9IDA7Cgp0eXBlZGVmIHN0cnVjdCBfZGF0YV90IHsKCiAgICBpbnQgdGlkOwogICAgaW50IGJ1ZmZlcl9zaXplOwogICAgaW50IHVwcGVyX2xpbWl0OwoKfSBkYXRhX3Q7Cgp2b2lkICpwcm9kdWNlKHZvaWQgKmFyZykgewoKICAgIGRhdGFfdCAqcGFzc2VkRGF0YSA9IChkYXRhX3QgKikgYXJnOwoKICAgIHdoaWxlICgxKSB7CgoKICAgICAgICBzZW1fd2FpdCgmbGltaXQpOwoKICAgICAgICBpZiAocGFzc2VkRGF0YS0+dXBwZXJfbGltaXQgPT0gcF9zaGFyZWRfdmFsdWUpIHsKICAgICAgICAgICAgcHJpbnRmKCJQcm9kdWNlclsjJWRdIHRlcm1pbmF0ZWRcbiIsIHBhc3NlZERhdGEtPnRpZCk7CiAgICAgICAgICAgIHNlbV9wb3N0KCZsaW1pdCk7CiAgICAgICAgICAgIHB0aHJlYWRfZXhpdChOVUxMKTsKICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgc2VtX3dhaXQoJmVtcHR5KTsKICAgICAgICAgICAgc2VtX3dhaXQoJm11dGV4KTsKCiAgICAgICAgICAgIGJ1ZmZlcltpbl0gPSBwX3NoYXJlZF92YWx1ZTsKICAgICAgICAgICAgcHJpbnRmKCJbUFJPRFVDRURdIGF0IGluZGV4IDogJWQsIGJ5IFRJRCA6ICVkIFZBTFVFIDogJWRcbiIsIGluLCBwYXNzZWREYXRhLT50aWQsIHBfc2hhcmVkX3ZhbHVlKTsKICAgICAgICAgICAgcF9zaGFyZWRfdmFsdWUrKzsKICAgICAgICAgICAgaW4gPSAoaW4gKyAxKSAlIHBhc3NlZERhdGEtPmJ1ZmZlcl9zaXplOwoKICAgICAgICAgICAgc2VtX3Bvc3QoJm11dGV4KTsKICAgICAgICAgICAgc2VtX3Bvc3QoJmxpbWl0KTsKICAgICAgICAgICAgc2VtX3Bvc3QoJmZ1bGwpOwogICAgICAgIH0KICAgIH0KfQoKdm9pZCAqY29uc3VtZSh2b2lkICphcmcpIHsKCiAgICBkYXRhX3QgKnBhc3NlZERhdGEgPSAoZGF0YV90ICopIGFyZzsKCiAgICB3aGlsZSAoMSkgewoKCiAgICAgICAgaWYgKHBhc3NlZERhdGEtPnVwcGVyX2xpbWl0ID09IHBfc2hhcmVkX3ZhbHVlKSB7CiAgICAgICAgICAgIHByaW50ZigiQ29uc3VtZXJbIyVkXSB0ZXJtaW5hdGVkXG4iLCBwYXNzZWREYXRhLT50aWQpOwogICAgICAgICAgICBwdGhyZWFkX2V4aXQoTlVMTCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VtX3dhaXQoJmZ1bGwpOwogICAgICAgICAgICBzZW1fd2FpdCgmbXV0ZXgpOwoKICAgICAgICAgICAgcHJpbnRmKCJbQ09OU1VNRURdIGF0IGluZGV4IDogJWQsIGJ5IFRJRCA6ICVkIFZBTFVFIDogJWRcbiIsIG91dCwgcGFzc2VkRGF0YS0+dGlkLCBidWZmZXJbb3V0XSk7CiAgICAgICAgICAgIG91dCA9IChvdXQgKyAxKSAlIHBhc3NlZERhdGEtPmJ1ZmZlcl9zaXplOwoKICAgICAgICAgICAgc2VtX3Bvc3QoJm11dGV4KTsKICAgICAgICAgICAgc2VtX3Bvc3QoJmVtcHR5KTsKICAgICAgICB9CiAgICB9Cn0KCgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CgogICAgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gKHVuc2lnbmVkIGludCkgYXRvaShhcmd2WzFdKTsKICAgIGludCBudW1fcHJvZHVjZXJzID0gYXRvaShhcmd2WzJdKTsKICAgIGludCBudW1fY29uc3VtZXJzID0gYXRvaShhcmd2WzNdKTsKICAgIGludCB1cHBlcl9saW1pdCA9IGF0b2koYXJndls0XSk7CgogICAgYnVmZmVyID0gbWFsbG9jKGJ1ZmZlcl9zaXplICogc2l6ZW9mKGludCkpOwoKICAgIHNlbV9pbml0KCZlbXB0eSwgMCwgYnVmZmVyX3NpemUpOwogICAgc2VtX2luaXQoJmZ1bGwsIDAsIDApOwogICAgc2VtX2luaXQoJm11dGV4LCAwLCAxKTsKICAgIHNlbV9pbml0KCZsaW1pdCwgMCwgMSk7CgogICAgcHRocmVhZF90IGNfdGhyZWFkc1tudW1fY29uc3VtZXJzXTsKICAgIHB0aHJlYWRfdCBwX3RocmVhZHNbbnVtX3Byb2R1Y2Vyc107CgoKICAgIHB1dHMoIlBhc3NlZCBhcmd1bWVudHMiKTsKICAgIHByaW50ZigiJWQgLSAlZCAtICVkIC0gJWRcbiIsIGJ1ZmZlcl9zaXplLCBudW1fcHJvZHVjZXJzLCBudW1fY29uc3VtZXJzLCB1cHBlcl9saW1pdCk7CiAgICBwdXRzKCIqKioqKioqKioqKioqKioqKioqKioqKioiKTsKCiAgICBkYXRhX3QgcF9zdHJ1Y3RzW251bV9wcm9kdWNlcnNdOwogICAgZGF0YV90IGNfc3RydWN0c1tudW1fY29uc3VtZXJzXTsKCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1fcHJvZHVjZXJzOyBpKyspIHsKICAgICAgICBwX3N0cnVjdHNbaV0uYnVmZmVyX3NpemUgPSBidWZmZXJfc2l6ZTsKICAgICAgICBwX3N0cnVjdHNbaV0udGlkID0gaTsKICAgICAgICBwX3N0cnVjdHNbaV0udXBwZXJfbGltaXQgPSB1cHBlcl9saW1pdDsKCiAgICAgICAgcHRocmVhZF9jcmVhdGUoJihwX3RocmVhZHNbaV0pLCBOVUxMLCAmcHJvZHVjZSwgKCh2b2lkICopICgmcF9zdHJ1Y3RzW2ldKSkpOwogICAgfQoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtX2NvbnN1bWVyczsgaSsrKSB7CiAgICAgICAgY19zdHJ1Y3RzW2ldLmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CiAgICAgICAgY19zdHJ1Y3RzW2ldLnRpZCA9IGk7CiAgICAgICAgY19zdHJ1Y3RzW2ldLnVwcGVyX2xpbWl0ID0gdXBwZXJfbGltaXQ7CgogICAgICAgIHB0aHJlYWRfY3JlYXRlKCZjX3RocmVhZHNbaV0sIE5VTEwsICZjb25zdW1lLCAoKHZvaWQgKikgKCZjX3N0cnVjdHNbaV0pKSk7CiAgICB9CgoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtX3Byb2R1Y2VyczsgaSsrKSB7CiAgICAgICAgcHRocmVhZF9qb2luKHBfdGhyZWFkc1tpXSwgTlVMTCk7CiAgICB9CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1fY29uc3VtZXJzOyBpKyspIHsKICAgICAgICBwdGhyZWFkX2pvaW4oY190aHJlYWRzW2ldLCBOVUxMKTsKICAgIH0KCgogICAgcmV0dXJuIDA7Cn0=