#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// use 4 cons 4 prod
// instead of random number, use 1000 for all prod
// real time lib is optional
// Due thurs 11pm
#define BSIZE 10
#define NUM_ITEMS 20
#define NUM_THREADS 8
#define NUM_PRODUCERS 4
#define NUM_CONSUMERS 4
typedef enum { false, true } bool;
int buf[BSIZE];
int nextin=0, nextout=0;
pthread_mutex_t lock; // a shared lock veriale
pthread_cond_t empty, full;
bool isFull = false, isEmpty = false;
int bufCounter = 0;
void * producer(void *); // function for producer thread
void * consumer(void *); // function for consumer thread
pthread_t tid[NUM_THREADS]; // array of thread IDs
int main( int argc, char *argv[] )
{
int i;
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
printf("\n **** Main Program creating threads **** \n");
for (i = 0; i < NUM_PRODUCERS; i++)
pthread_create(&tid[i], NULL, producer, NULL); // Creating producers
for (i = NUM_PRODUCERS; i < NUM_THREADS; i++)
pthread_create(&tid[i], NULL, consumer, NULL); // Creating consumers
for ( i = 0; i < NUM_THREADS; i++)
pthread_join(tid[i], NULL);
printf("\n *** main() reporting: all %d threads have terminated ***\n\n ", i
);
return 0;
} /* main */
void * producer(void * parm)
{
int i, num;
printf("\n ++++ Producer started ++++ \n");
for(i=0; i < NUM_ITEMS; i++)
{ // produce items
pthread_mutex_lock(&lock); // lock the buffer when adding num
if (isFull == true)
pthread_cond_wait(&empty, &lock);
buf[nextin++] = num;
nextin %= BSIZE; // make the buffer circular
bufCounter++; // Increment bufCounter
isEmpty = false;
if (bufCounter == BSIZE){
isFull = true;
pthread_cond_signal(&full);
}
pthread_mutex_unlock(&lock); // get out the critical section
}
printf("\n ++++ Producer exiting ++++\n"); pthread_exit(0);
}
void * consumer(void * parm)
{
int i, num;
printf("\n ==== Consumer started ==== \n");
for(i=0; i < NUM_ITEMS; i++)
{
// get item from the buffer and consume it
pthread_mutex_lock(&lock); // lock the buffer when removing item
if (isEmpty == true)
pthread_cond_wait(&full, &lock);
num = buf[nextout++];
nextout %= BSIZE; // make the buffer circular
bufCounter--;
printf(" Consuming item #[%d]: %d\n", i
, num
);
isFull = false;
pthread_cond_signal(&full);
if (bufCounter == 0){
isEmpty = true;
}
pthread_mutex_unlock(&lock); // unlock the buffer and get out CS
}
printf("\n ==== Consumer exiting ====\n"); pthread_exit(0);
}
I2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHRpbWUuaD4KCi8vIHVzZSA0IGNvbnMgNCBwcm9kCi8vIGluc3RlYWQgb2YgcmFuZG9tIG51bWJlciwgdXNlIDEwMDAgZm9yIGFsbCBwcm9kCi8vIHJlYWwgdGltZSBsaWIgaXMgb3B0aW9uYWwKLy8gRHVlIHRodXJzIDExcG0KCgojZGVmaW5lIEJTSVpFIDEwCiNkZWZpbmUgTlVNX0lURU1TIDIwCiNkZWZpbmUgTlVNX1RIUkVBRFMgOAojZGVmaW5lIE5VTV9QUk9EVUNFUlMgNAojZGVmaW5lIE5VTV9DT05TVU1FUlMgNAoKdHlwZWRlZiBlbnVtIHsgZmFsc2UsIHRydWUgfSBib29sOwoKaW50IGJ1ZltCU0laRV07CmludCBuZXh0aW49MCwgbmV4dG91dD0wOwoKcHRocmVhZF9tdXRleF90IGxvY2s7ICAgICAgIC8vIGEgc2hhcmVkIGxvY2sgdmVyaWFsZQpwdGhyZWFkX2NvbmRfdCBlbXB0eSwgZnVsbDsKYm9vbCBpc0Z1bGwgPSBmYWxzZSwgaXNFbXB0eSA9IGZhbHNlOwppbnQgYnVmQ291bnRlciA9IDA7Cgp2b2lkICogcHJvZHVjZXIodm9pZCAqKTsgICAgLy8gZnVuY3Rpb24gZm9yIHByb2R1Y2VyIHRocmVhZAp2b2lkICogY29uc3VtZXIodm9pZCAqKTsgICAgLy8gZnVuY3Rpb24gZm9yIGNvbnN1bWVyIHRocmVhZAoKcHRocmVhZF90IHRpZFtOVU1fVEhSRUFEU107ICAgICAgLy8gYXJyYXkgb2YgdGhyZWFkIElEcwoKCmludCBtYWluKCBpbnQgYXJnYywgY2hhciAqYXJndltdICkgCnsKICAgIGludCBpOwoKICAgIHB0aHJlYWRfY29uZF9pbml0KCZmdWxsLCBOVUxMKTsKICAgIHB0aHJlYWRfY29uZF9pbml0KCZlbXB0eSwgTlVMTCk7CgogICAgcHJpbnRmKCJcbiAqKioqIE1haW4gUHJvZ3JhbSBjcmVhdGluZyB0aHJlYWRzICoqKiogXG4iKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1BST0RVQ0VSUzsgaSsrKQogICAgICAgIHB0aHJlYWRfY3JlYXRlKCZ0aWRbaV0sIE5VTEwsIHByb2R1Y2VyLCBOVUxMKTsgLy8gQ3JlYXRpbmcgcHJvZHVjZXJzIAogICAgZm9yIChpID0gTlVNX1BST0RVQ0VSUzsgaSA8IE5VTV9USFJFQURTOyBpKyspCiAgICAgICAgcHRocmVhZF9jcmVhdGUoJnRpZFtpXSwgTlVMTCwgY29uc3VtZXIsIE5VTEwpOyAvLyBDcmVhdGluZyBjb25zdW1lcnMKCiAgICBmb3IgKCBpID0gMDsgaSA8IE5VTV9USFJFQURTOyBpKyspCiAgICAgICAgcHRocmVhZF9qb2luKHRpZFtpXSwgTlVMTCk7CgogICAgcHJpbnRmKCJcbiAqKiogbWFpbigpIHJlcG9ydGluZzogYWxsICVkIHRocmVhZHMgaGF2ZSB0ZXJtaW5hdGVkICoqKlxuXG4gIiwgaSk7CgogICAgcmV0dXJuIDA7IAoKfSAgLyogbWFpbiAqLwoKCgp2b2lkICogcHJvZHVjZXIodm9pZCAqIHBhcm0pCnsKICAgIGludCBpLCBudW07CgogICAgcHJpbnRmKCJcbiArKysrIFByb2R1Y2VyIHN0YXJ0ZWQgKysrKyBcbiIpOwoKICAgIGZvcihpPTA7IGkgPCBOVU1fSVRFTVM7IGkrKykKICAgIHsgLy8gcHJvZHVjZSBpdGVtcyAgCgogICAgICAgIG51bSA9IHJhbmQoKSAlIDEwMDA7CgogICAgICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbG9jayk7ICAgICAgLy8gbG9jayB0aGUgYnVmZmVyIHdoZW4gYWRkaW5nIG51bQoKICAgICAgICBpZiAoaXNGdWxsID09IHRydWUpCiAgICAgICAgICAgIHB0aHJlYWRfY29uZF93YWl0KCZlbXB0eSwgJmxvY2spOwoKICAgICAgICBidWZbbmV4dGluKytdID0gbnVtOwoKICAgICAgICBuZXh0aW4gJT0gQlNJWkU7ICAgIC8vIG1ha2UgdGhlIGJ1ZmZlciBjaXJjdWxhcgogICAgICAgIGJ1ZkNvdW50ZXIrKzsgLy8gSW5jcmVtZW50IGJ1ZkNvdW50ZXIKCiAgICAgICAgaXNFbXB0eSA9IGZhbHNlOwogICAgICAgIGlmIChidWZDb3VudGVyID09IEJTSVpFKXsKICAgICAgICAgICAgaXNGdWxsID0gdHJ1ZTsKICAgICAgICAgICAgcHRocmVhZF9jb25kX3NpZ25hbCgmZnVsbCk7CiAgICAgICAgfQogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZsb2NrKTsgICAgLy8gZ2V0IG91dCB0aGUgY3JpdGljYWwgc2VjdGlvbiAKCiAgICB9CgoKICAgIHByaW50ZigiXG4gKysrKyBQcm9kdWNlciBleGl0aW5nICsrKytcbiIpOwogICAgcHRocmVhZF9leGl0KDApOwp9ICAgIAoKdm9pZCAqIGNvbnN1bWVyKHZvaWQgKiBwYXJtKQp7CiAgICBpbnQgaSwgbnVtOwoKICAgIHByaW50ZigiXG4gPT09PSBDb25zdW1lciBzdGFydGVkID09PT0gXG4iKTsKCiAgICBmb3IoaT0wOyBpIDwgTlVNX0lURU1TOyBpKyspCiAgICB7ICAgICAgIAogICAgICAgIC8vIGdldCBpdGVtIGZyb20gdGhlIGJ1ZmZlciBhbmQgY29uc3VtZSBpdAoKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJmxvY2spOyAgICAgIC8vIGxvY2sgdGhlIGJ1ZmZlciB3aGVuIHJlbW92aW5nIGl0ZW0KCiAgICAgICAgaWYgKGlzRW1wdHkgPT0gdHJ1ZSkKICAgICAgICAgICAgcHRocmVhZF9jb25kX3dhaXQoJmZ1bGwsICZsb2NrKTsKCiAgICAgICAgbnVtID0gYnVmW25leHRvdXQrK107CiAgICAgICAgbmV4dG91dCAlPSBCU0laRTsgICAgICAgLy8gbWFrZSB0aGUgYnVmZmVyIGNpcmN1bGFyCiAgICAgICAgYnVmQ291bnRlci0tOyAgICAgICAKCiAgICAgICAgcHJpbnRmKCIgQ29uc3VtaW5nIGl0ZW0gI1slZF06ICVkXG4iLCBpLCBudW0pOwoKICAgICAgICBpc0Z1bGwgPSBmYWxzZTsKICAgICAgICBwdGhyZWFkX2NvbmRfc2lnbmFsKCZmdWxsKTsKICAgICAgICBpZiAoYnVmQ291bnRlciA9PSAwKXsKICAgICAgICAgICAgaXNFbXB0eSA9IHRydWU7CiAgICAgICAgfSAgIAogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZsb2NrKTsgICAgICAvLyB1bmxvY2sgdGhlIGJ1ZmZlciBhbmQgZ2V0IG91dCBDUwoKICAgIH0KCgogICAgcHJpbnRmKCJcbiA9PT09IENvbnN1bWVyIGV4aXRpbmcgPT09PVxuIik7CiAgICBwdGhyZWFkX2V4aXQoMCk7Cn0K