Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <semaphore.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define NUM_THREADS 30
- #define INITIAL_SIZE 1
- sem_t v1,v2,v3;
- struct buffer_batch_t *vault;//global buffer batch
- typedef struct buffer_t buffer_t;
- struct buffer_t{
- int length; /*actual size of buffer*/
- int n_items; /*actual number of items in buffer*/
- int first,last; /*indicates first and last items*/
- //char *itemBuffer; /*holds the item for the consumer*/
- struct char_t *itemBuffer; /*holds the item for the consumer*/
- };
- typedef struct char_t char_t;
- struct char_t{
- char item;
- //int producer_id;
- int prod_seq_num;
- };
- typedef struct buffer_batch_t buffer_batch_t;
- struct buffer_batch_t{
- buffer_t **bufferList;
- int counter;
- int inception;
- };
- /*
- void *printHello(void *threadid){
- long tid;
- tid = (long)threadid;//from the argument
- printf("Yo yo yo! world! Wutup? It's the threadid %ld!\n", tid);
- pthread_exit(NULL);
- }
- */
- char_t *allocBuffer(int size){/*allocates an item buffer with given size and initializes all values to 0 or NUL*/
- char_t* newItemBuff;
- int i;
- newItemBuff = (char_t*)malloc(sizeof(char_t)*size);
- for(i=0;i<size;i++){
- newItemBuff[i].item= 0;
- //newItemBuff[i].producer_id = -2;
- }
- return newItemBuff;
- }
- buffer_t *extendBuffer(buffer_t *oldBuff){/*takes old buffer length, extends it by 1000, copies the items to the new buffer and returns new extended buffer*/
- buffer_t *newBuffer = (buffer_t*)malloc(sizeof(buffer_t));
- int newSize,i,remainder;
- newSize = oldBuff->length + 1000;
- /*initialize new Buffer struct and copy only the spaces with items*/
- newBuffer->length = newSize;
- newBuffer->n_items = oldBuff->n_items;
- newBuffer->itemBuffer = allocBuffer(newSize);
- //printf("newBuff size: %i\n",newBuffer->length);
- for(i=0;i<oldBuff->n_items;i++){
- if(oldBuff->first+i > oldBuff->length-1){//if the case of a wrap-around is in hand, jump back to the 0 index and continue
- remainder = oldBuff->n_items - i;//ie:
- if(oldBuff->first == (remainder-oldBuff->n_items+i)){//checks to see if wrap around is trying reread in on itself.
- printf("ERROR: Wrap extension issue... running into first on wrap\n");
- return 0;
- }
- newBuffer->itemBuffer[i] = oldBuff->itemBuffer[remainder - oldBuff->n_items + i];
- }
- else{
- newBuffer->itemBuffer[i] = oldBuff->itemBuffer[oldBuff->first+i];
- }
- }
- newBuffer->first = 0; //resets first and last place markers
- newBuffer->last = newBuffer->n_items-1;
- return newBuffer;
- }
- buffer_t *shortenBuffer(buffer_t *oldBuff){
- buffer_t *newBuffer = (buffer_t*)malloc(sizeof(buffer_t));
- int newSize,i,remainder;
- newSize = INITIAL_SIZE;
- /*initialize new Buffer struct and copy only the spaces with items*/
- newBuffer->length = newSize;
- newBuffer->n_items = oldBuff->n_items;
- newBuffer->itemBuffer = allocBuffer(newSize);
- for(i=0;i<oldBuff->n_items;i++){
- if(oldBuff->first+i >= oldBuff->length-1){//if the case of a wrap-around is in hand, jump back to the 0 index and continue
- remainder = oldBuff->n_items - i;//ie:
- if(oldBuff->first == (remainder-oldBuff->n_items+i)){//checks to see if wrap around is trying reread in on itself.
- printf("ERROR: SHORTEN Wrap extension issue... running into first on wrap\n");
- return 0;
- }
- newBuffer->itemBuffer[i] = oldBuff->itemBuffer[remainder - oldBuff->n_items + i];
- }
- else{
- newBuffer->itemBuffer[i] = oldBuff->itemBuffer[oldBuff->first+i];
- }
- }
- newBuffer->first = 0; //resets first and last place markers
- newBuffer->last = newBuffer->n_items-1;
- return newBuffer;
- }
- buffer_t* setBuffer(int length, int n_items, char_t *itemBuffer){/*allows the setting of each var in the struct*/
- buffer_t *nbuffer = (buffer_t*)malloc(sizeof(buffer_t));
- nbuffer->length = length;
- nbuffer->n_items = n_items;
- nbuffer->itemBuffer = itemBuffer;
- nbuffer->first = 0;
- nbuffer->last = 0;
- return nbuffer;
- }
- void printInfo(buffer_t *buffer,int i){
- printf("START/////////////////////PRINTSTART/////////////////////START\n");
- printf("buffer->length = %i\n",buffer->length);
- printf("buffer->n_items = %i\n",buffer->n_items);
- printf("buffer->first = %i\n",buffer->first);
- printf("buffer->last = %i\n",buffer->last);
- //printf("buffer->item->prod_id = %i\n",buffer->itemBuffer[i].producer_id);
- printf("END/////////////////////PRINTEND/////////////////////END\n");
- }
- void* producer_lc(){/*produces random lower case letter and inserts it into lowerCase buffer*/
- char itemR = rand()%26+97;
- char_t item;
- item.item = itemR;
- //item.producer_id = (int)id;
- buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
- sem_wait(&v1);
- buffer = vault->bufferList[0];
- printf("INSERTED = %c\n",itemR);
- int insertIndex = buffer->last+1;//place item in next index
- if(buffer->n_items == 0){
- buffer->first = 0;
- insertIndex = 0;
- }
- else if(buffer->length==buffer->n_items){//extend if the buffer is full
- printf("EXTENDING ARRAY\n");
- buffer = extendBuffer(buffer);
- insertIndex = buffer->last+1;
- printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
- vault->bufferList[0] = buffer;
- }
- else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
- printf("WRAPPING TO FRONT");
- if(buffer->itemBuffer[0].item != 0){
- printf("Error: producer wrapping issue\n");
- return;
- }
- insertIndex = 0;//sets insert index back to the front of the array
- }
- buffer->itemBuffer[insertIndex] = item;
- buffer->last = insertIndex;
- buffer->n_items++;
- //printInfo(buffer,0);
- sem_post(&v3);
- sem_post(&v2);
- sem_post(&v1);
- return buffer;
- }
- void* producer_uc(){/*produces random upper case letter and inserts it into upperCase buffer*/
- char itemR = rand()%26+65;
- char_t item;
- item.item = itemR;
- //item.producer_id = (int)id;
- buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
- sem_wait(&v1);
- buffer = vault->bufferList[1];
- printf("INSERTED = %c\n",itemR);
- int insertIndex = buffer->last+1;//place item in next index
- if(buffer->n_items == 0){
- buffer->first = 0;
- insertIndex = 0;
- }
- else if(buffer->length==buffer->n_items){//extend if the buffer is full
- //sem_wait(&v4);
- printf("EXTENDING ARRAY\n");
- buffer = extendBuffer(buffer);
- insertIndex = buffer->last+1;
- printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
- vault->bufferList[1] = buffer;
- //sem_post(&v4);
- }
- else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
- if(buffer->itemBuffer[0].item != 0){
- printf("Error: producer wrapping issue\n");
- return;
- }
- insertIndex = 0;//sets insert index back to the front of the array
- }
- buffer->itemBuffer[insertIndex]=item;
- buffer->last = insertIndex;
- buffer->n_items++;
- sem_post(&v3);
- sem_post(&v2);
- sem_post(&v1);
- //printInfo(buffer,1);
- return buffer;
- }
- void* producer_num(){/*produces random number 0-9 and inserts it into numerical buffer*/
- char itemR = rand()%10+48;
- int insertIndex;
- char_t item;
- item.item = itemR;
- //item.producer_id = (int)id;
- buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
- sem_wait(&v1);
- buffer = vault->bufferList[2];
- printf("INSERTED = %c\n",itemR);
- insertIndex = buffer->last+1;//place item in next index
- if(buffer->n_items == 0){
- buffer->first = 0;
- insertIndex = 0;
- }
- else if(buffer->length==buffer->n_items){//extend if the buffer is full
- //sem_wait(&v4);
- printf("EXTENDING ARRAY\n");
- buffer = extendBuffer(buffer);
- insertIndex = buffer->last+1;
- printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
- vault->bufferList[2] = buffer;
- //sem_post(&v4);
- }
- else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
- if(buffer->itemBuffer[0].item != 0){
- printf("Error: producer wrapping issue\n");
- return;
- }
- insertIndex = 0;//sets insert index back to the front of the array
- }
- buffer->itemBuffer[insertIndex]=item;
- buffer->last = insertIndex;
- buffer->n_items++;
- sem_post(&v3);
- //printInfo(buffer,2);
- sem_post(&v2);
- sem_post(&v1);
- return;
- }
- buffer_t* checkItems(buffer_t* buffer){
- int i;
- int n_items=0;
- for(i=0;i<buffer->length;i++){
- if(buffer->itemBuffer[i].item=!0){
- n_items ++;
- }
- }
- buffer->n_items = n_items;
- return buffer;
- }
- void* consumer(){//consumer takes in all 3 buffer as an argument, then rolls the dice on which one it consumes
- int id,rolling, rolled;
- char_t item;
- buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
- buffer_batch_t *bbt = (buffer_batch_t*)malloc(sizeof(buffer_batch_t));
- rolling = rand()%3;
- sem_wait(&v2);
- sem_wait(&v3);
- sem_wait(&v1);
- bbt = vault;
- rolling = rand()%3;
- rolled = rolling;
- id=0;
- while(1){
- //bbt->counter = rolling;
- //printf("rolled %i\n",rolling);
- //int rolling = 0;
- //printf("bbt->bufferList[%i]->n_items = %i//////////////////////////////////\n", rolling,bbt->bufferList[rolling]->n_items);
- if(bbt->bufferList[rolled]->n_items ==0){
- if(rolled == 0){
- if(bbt->bufferList[1]->n_items==0){
- if(bbt->bufferList[2]->n_items==0){
- printf("**************SHOULD NOT EVEN GET HERE********************\n");
- continue;
- }
- //buffer = bbt->bufferList[2];
- rolling = 2;break;
- }
- //buffer = bbt->bufferList[1];
- rolling = 1;break;
- }
- if(rolled == 1){
- if(bbt->bufferList[0]->n_items==0){
- if(bbt->bufferList[2]->n_items==0){
- printf("**************SHOULD NOT EVEN GET HERE********************\n");
- continue;
- }
- //buffer = bbt->bufferList[2];
- rolling = 2;break;
- }
- //buffer = bbt->bufferList[0];
- rolling = 0;break;
- }
- if(rolled == 2){
- if(bbt->bufferList[0]->n_items==0){
- if(bbt->bufferList[1]->n_items==0){
- printf("**************SHOULD NOT EVEN GET HERE********************\n");
- continue;
- }
- //buffer = bbt->bufferList[1];
- rolling = 1;break;
- }
- //buffer = bbt->bufferList[0];
- rolling = 0;break;
- }
- printf("**************SHOULD NEVER GET HERE********************\n");
- //sem_post(&v1);
- continue;
- }break;
- }
- printf("------------------CONSUMING IN %i / rolled %i---------------------\n",rolling,rolled);
- //bbt->inception =0;
- buffer = bbt->bufferList[rolling];
- printf("Buffer = %i, first = %i, item = %c\n",rolling, buffer->first,buffer->itemBuffer[buffer->first].item);
- item = buffer->itemBuffer[buffer->first];
- buffer->itemBuffer[buffer->first].item = 0;
- if(buffer->first == buffer->length-1){
- /* //was going to shorten buffer when needed, but some more modifications would be needed
- if((buffer->length>INITIAL_SIZE) &&(buffer->n_items<((3*INITIAL_SIZE)/4))){//shortens buffer for to have some efficiency of memory
- buffer = shortenBuffer(buffer);
- buffer->n_items--;
- return item;
- }
- */
- buffer->first =0;
- buffer->n_items--;
- //sem_wait(&v3);
- //vault = bbt;
- sem_post(&v1);
- sem_post(&v2);
- printf("RC = %c\n",item.item);
- printInfo(buffer,rolling);
- return ;
- }
- buffer->first++;
- buffer->n_items--;
- printf("RC = %c\n",item.item);
- printInfo(buffer,rolling);
- //vault = bbt;
- sem_post(&v2);
- sem_post(&v1);
- return;
- }
- void* setBuff(size_t size){
- void *buff;
- buff =malloc(sizeof(size));
- return buff;
- }
- int main(int argc, char *argv[]){
- int t;
- pthread_t threads[NUM_THREADS];
- pthread_t threads_c[NUM_THREADS+1];
- size_t buffer_batch_t;
- //vault= (buffer_batch_t *)malloc(sizeof(buffer_batch_t));
- vault =setBuff(buffer_batch_t);
- char rc,rc1[NUM_THREADS];
- int initialSize = INITIAL_SIZE; /*initial size of buffers*/
- int i;
- srand(time(NULL));
- sem_init(&v1,0,1);
- sem_init(&v2,0,0);
- sem_init(&v3,0,0);
- //need 3 buffers that will not overflow - thus needing a function that extends the array.
- buffer_t *lowerCase = (buffer_t*)malloc(sizeof(buffer_t));
- buffer_t *upperCase = (buffer_t*)malloc(sizeof(buffer_t));
- buffer_t *numerical = (buffer_t*)malloc(sizeof(buffer_t));
- vault->bufferList = (buffer_t**)malloc(sizeof(buffer_t*)*3);
- vault->inception =-1;
- //allocating and initializing buffers
- lowerCase = setBuffer(initialSize, 0, allocBuffer(initialSize));
- upperCase = setBuffer(initialSize,0,allocBuffer(initialSize));
- numerical = setBuffer(initialSize,0,allocBuffer(initialSize));
- vault->bufferList[0] = lowerCase;
- vault->bufferList[1] = upperCase;
- vault->bufferList[2] = numerical;
- printf("In Main(): Creating 10 Consumers then 9 Prodcuers\n");
- for (t=0;t<10;t++){
- //printf("In main: CREATING CONSUMER THREAD %iid\n",t);
- //buffers->consumerid = t;
- rc = pthread_create(&threads_c[t],NULL,consumer,NULL);
- if(rc){
- printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
- exit(-1);
- }
- }
- for (t=0;t<3;t++){
- //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
- rc = pthread_create(&threads[t],NULL,(void*)producer_lc,NULL);
- if(rc){
- printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
- exit(-1);
- }
- }
- for (t=3;t<6;t++){
- //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
- rc = pthread_create(&threads[t],NULL,(void*)producer_uc,NULL);
- if(rc){
- printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
- exit(-1);
- }
- }
- for (t=6;t<9;t++){
- //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
- rc = pthread_create(&threads[t],NULL,(void*)producer_num,NULL);
- if(rc){
- printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
- exit(-1);
- }
- }
- /*
- for (t=0;t<9;t++){
- printf("In main: CREATING CONSUMER THREAD %iid\n",t);
- //buffers->consumerid = t;
- rc = pthread_create(&threads_c[t],NULL,(void*)consumer,NULL);
- if(rc){
- printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
- exit(-1);
- }
- }
- */
- producer_num();
- printf("In Main(): One more produced to allow for final thread to complete.\n");
- pthread_exit(NULL);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement