Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.07 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <semaphore.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #define NUM_THREADS 30
  7. #define INITIAL_SIZE 1
  8.  
  9. sem_t v1,v2,v3;
  10. struct buffer_batch_t *vault;//global buffer batch
  11. typedef struct buffer_t buffer_t;
  12. struct buffer_t{
  13.     int length; /*actual size of buffer*/
  14.     int n_items;   /*actual number of items in buffer*/
  15.     int first,last; /*indicates first and last items*/
  16.     //char *itemBuffer; /*holds the item for the consumer*/
  17.     struct char_t *itemBuffer; /*holds the item for the consumer*/
  18. };
  19.  
  20. typedef struct char_t char_t;
  21. struct char_t{
  22.     char item;
  23.     //int producer_id;
  24.     int prod_seq_num;
  25.    
  26. };
  27.  
  28. typedef struct buffer_batch_t buffer_batch_t;
  29. struct buffer_batch_t{
  30.     buffer_t **bufferList;
  31.     int counter;
  32.     int inception;
  33.  
  34. };
  35.     /*
  36.     void *printHello(void *threadid){
  37.         long tid;
  38.         tid = (long)threadid;//from the argument
  39.         printf("Yo yo yo! world! Wutup?  It's the threadid %ld!\n", tid);
  40.         pthread_exit(NULL);
  41.  
  42.     }
  43.     */
  44.  
  45. char_t *allocBuffer(int size){/*allocates an item buffer with given size and initializes all values to 0 or NUL*/
  46.     char_t* newItemBuff;
  47.     int i;
  48.     newItemBuff = (char_t*)malloc(sizeof(char_t)*size);
  49.     for(i=0;i<size;i++){
  50.         newItemBuff[i].item= 0;
  51.         //newItemBuff[i].producer_id = -2;
  52.     }
  53.     return newItemBuff;
  54. }
  55.  
  56. 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*/  
  57.     buffer_t *newBuffer = (buffer_t*)malloc(sizeof(buffer_t));
  58.     int newSize,i,remainder;
  59.     newSize = oldBuff->length + 1000;
  60.     /*initialize new Buffer struct and copy only the spaces with items*/
  61.     newBuffer->length = newSize;
  62.     newBuffer->n_items = oldBuff->n_items;
  63.     newBuffer->itemBuffer = allocBuffer(newSize);
  64.     //printf("newBuff size: %i\n",newBuffer->length);
  65.     for(i=0;i<oldBuff->n_items;i++){
  66.         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
  67.             remainder = oldBuff->n_items - i;//ie:
  68.             if(oldBuff->first == (remainder-oldBuff->n_items+i)){//checks to see if wrap around is trying reread in on itself.
  69.                 printf("ERROR: Wrap extension issue... running into first on wrap\n");
  70.                 return 0;
  71.             }
  72.             newBuffer->itemBuffer[i] = oldBuff->itemBuffer[remainder - oldBuff->n_items + i];
  73.         }
  74.         else{
  75.             newBuffer->itemBuffer[i] = oldBuff->itemBuffer[oldBuff->first+i];
  76.         }
  77.     }
  78.     newBuffer->first = 0;           //resets first and last place markers
  79.     newBuffer->last = newBuffer->n_items-1;
  80.  
  81.     return newBuffer;
  82. }
  83.  
  84. buffer_t *shortenBuffer(buffer_t *oldBuff){
  85.     buffer_t *newBuffer = (buffer_t*)malloc(sizeof(buffer_t));
  86.     int newSize,i,remainder;
  87.     newSize = INITIAL_SIZE;
  88.     /*initialize new Buffer struct and copy only the spaces with items*/
  89.     newBuffer->length = newSize;
  90.     newBuffer->n_items = oldBuff->n_items;
  91.     newBuffer->itemBuffer = allocBuffer(newSize);
  92.     for(i=0;i<oldBuff->n_items;i++){
  93.         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
  94.             remainder = oldBuff->n_items - i;//ie:
  95.             if(oldBuff->first == (remainder-oldBuff->n_items+i)){//checks to see if wrap around is trying reread in on itself.
  96.                 printf("ERROR: SHORTEN Wrap extension issue... running into first on wrap\n");
  97.                 return 0;
  98.             }
  99.             newBuffer->itemBuffer[i] = oldBuff->itemBuffer[remainder - oldBuff->n_items + i];
  100.         }
  101.         else{
  102.             newBuffer->itemBuffer[i] = oldBuff->itemBuffer[oldBuff->first+i];
  103.         }
  104.     }
  105.     newBuffer->first = 0;           //resets first and last place markers
  106.     newBuffer->last = newBuffer->n_items-1;
  107.  
  108.     return newBuffer;
  109.  
  110. }
  111. buffer_t* setBuffer(int length, int n_items, char_t *itemBuffer){/*allows the setting of each var in the struct*/
  112.     buffer_t *nbuffer = (buffer_t*)malloc(sizeof(buffer_t));
  113.     nbuffer->length = length;
  114.     nbuffer->n_items = n_items;
  115.     nbuffer->itemBuffer = itemBuffer;
  116.     nbuffer->first = 0;
  117.     nbuffer->last = 0;
  118.     return nbuffer;
  119. }
  120.  
  121.  
  122. void printInfo(buffer_t *buffer,int i){
  123.     printf("START/////////////////////PRINTSTART/////////////////////START\n");
  124.     printf("buffer->length = %i\n",buffer->length);
  125.     printf("buffer->n_items = %i\n",buffer->n_items);
  126.     printf("buffer->first = %i\n",buffer->first);
  127.     printf("buffer->last = %i\n",buffer->last);
  128.     //printf("buffer->item->prod_id = %i\n",buffer->itemBuffer[i].producer_id);
  129.     printf("END/////////////////////PRINTEND/////////////////////END\n");
  130. }
  131.  
  132. void* producer_lc(){/*produces random lower case letter and inserts it into lowerCase buffer*/
  133.     char itemR = rand()%26+97;
  134.     char_t item;
  135.     item.item = itemR;
  136.     //item.producer_id = (int)id;
  137.     buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
  138.     sem_wait(&v1);
  139.    
  140.    
  141.     buffer = vault->bufferList[0];
  142.    
  143.     printf("INSERTED = %c\n",itemR);
  144.     int insertIndex = buffer->last+1;//place item in next index
  145.     if(buffer->n_items == 0){
  146.         buffer->first = 0;
  147.         insertIndex = 0;
  148.     }
  149.     else if(buffer->length==buffer->n_items){//extend if the buffer is full
  150.         printf("EXTENDING ARRAY\n");
  151.         buffer = extendBuffer(buffer);
  152.         insertIndex = buffer->last+1;
  153.         printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
  154.         vault->bufferList[0] = buffer;
  155.        
  156.     }
  157.     else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
  158.         printf("WRAPPING TO FRONT");
  159.         if(buffer->itemBuffer[0].item != 0){
  160.             printf("Error: producer wrapping issue\n");
  161.             return;
  162.         }
  163.         insertIndex = 0;//sets insert index back to the front of the array 
  164.     }
  165.     buffer->itemBuffer[insertIndex] = item;
  166.     buffer->last = insertIndex;
  167.     buffer->n_items++;
  168.     //printInfo(buffer,0);
  169.     sem_post(&v3);
  170.     sem_post(&v2);
  171.     sem_post(&v1);
  172.     return buffer;
  173.    
  174. }
  175.  
  176. void* producer_uc(){/*produces random upper case letter and inserts it into upperCase buffer*/
  177.     char itemR = rand()%26+65;
  178.     char_t item;
  179.     item.item = itemR;
  180.     //item.producer_id = (int)id;
  181.     buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
  182.     sem_wait(&v1);
  183.     buffer = vault->bufferList[1];
  184.     printf("INSERTED = %c\n",itemR);
  185.     int insertIndex = buffer->last+1;//place item in next index
  186.     if(buffer->n_items == 0){
  187.         buffer->first = 0;
  188.         insertIndex = 0;
  189.     }
  190.     else if(buffer->length==buffer->n_items){//extend if the buffer is full
  191.         //sem_wait(&v4);
  192.         printf("EXTENDING ARRAY\n");
  193.         buffer = extendBuffer(buffer);
  194.         insertIndex = buffer->last+1;
  195.         printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
  196.         vault->bufferList[1] = buffer;
  197.         //sem_post(&v4);
  198.     }
  199.     else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
  200.         if(buffer->itemBuffer[0].item != 0){
  201.             printf("Error: producer wrapping issue\n");
  202.             return;
  203.         }
  204.         insertIndex = 0;//sets insert index back to the front of the array 
  205.     }
  206.     buffer->itemBuffer[insertIndex]=item;
  207.     buffer->last = insertIndex;
  208.     buffer->n_items++;
  209.    
  210.     sem_post(&v3);
  211.    
  212.     sem_post(&v2);
  213.     sem_post(&v1);
  214.     //printInfo(buffer,1);
  215.     return buffer;
  216. }
  217.  
  218. void* producer_num(){/*produces random number 0-9 and inserts it into numerical buffer*/
  219.     char itemR = rand()%10+48;
  220.     int insertIndex;
  221.     char_t item;
  222.     item.item = itemR;
  223.     //item.producer_id = (int)id;
  224.     buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
  225.     sem_wait(&v1);
  226.     buffer = vault->bufferList[2];
  227.     printf("INSERTED = %c\n",itemR);
  228.  
  229.     insertIndex = buffer->last+1;//place item in next index
  230.     if(buffer->n_items == 0){
  231.         buffer->first = 0;
  232.         insertIndex = 0;
  233.     }
  234.     else if(buffer->length==buffer->n_items){//extend if the buffer is full
  235.         //sem_wait(&v4);
  236.         printf("EXTENDING ARRAY\n");
  237.         buffer = extendBuffer(buffer);
  238.         insertIndex = buffer->last+1;
  239.         printf("Buff size: %i, insertIndex: %i\n",buffer->length,insertIndex);
  240.         vault->bufferList[2] = buffer;
  241.         //sem_post(&v4);
  242.     }
  243.     else if((insertIndex == buffer->length)&&(buffer->n_items < buffer->length)){//wrap around to the front
  244.         if(buffer->itemBuffer[0].item != 0){
  245.             printf("Error: producer wrapping issue\n");
  246.             return;
  247.         }
  248.         insertIndex = 0;//sets insert index back to the front of the array 
  249.     }
  250.     buffer->itemBuffer[insertIndex]=item;
  251.     buffer->last = insertIndex;
  252.     buffer->n_items++;
  253.     sem_post(&v3);
  254.     //printInfo(buffer,2);
  255.     sem_post(&v2);
  256.     sem_post(&v1);
  257.     return;
  258. }
  259. buffer_t* checkItems(buffer_t* buffer){
  260.     int i;
  261.     int n_items=0;
  262.     for(i=0;i<buffer->length;i++){
  263.         if(buffer->itemBuffer[i].item=!0){
  264.             n_items ++;
  265.         }
  266.     }
  267.     buffer->n_items = n_items;
  268.     return buffer;
  269.    
  270. }
  271. void* consumer(){//consumer takes in all 3 buffer as an argument, then rolls the dice on which one it consumes 
  272.     int id,rolling, rolled;
  273.     char_t item;
  274.     buffer_t *buffer = (buffer_t*)malloc(sizeof(buffer_t));
  275.     buffer_batch_t *bbt = (buffer_batch_t*)malloc(sizeof(buffer_batch_t));
  276.     rolling = rand()%3;
  277.     sem_wait(&v2);
  278.     sem_wait(&v3);
  279.     sem_wait(&v1);
  280.     bbt = vault;
  281.     rolling = rand()%3;
  282.     rolled = rolling;
  283.     id=0;
  284.     while(1){
  285.        
  286.        
  287.         //bbt->counter = rolling;
  288.    
  289.         //printf("rolled %i\n",rolling);
  290.         //int rolling = 0;
  291.    
  292.  
  293.         //printf("bbt->bufferList[%i]->n_items = %i//////////////////////////////////\n", rolling,bbt->bufferList[rolling]->n_items);
  294.        
  295.         if(bbt->bufferList[rolled]->n_items ==0){
  296.             if(rolled == 0){
  297.                 if(bbt->bufferList[1]->n_items==0){
  298.                     if(bbt->bufferList[2]->n_items==0){
  299.                         printf("**************SHOULD NOT EVEN GET HERE********************\n");
  300.                         continue;          
  301.                     }
  302.                     //buffer = bbt->bufferList[2];
  303.                     rolling = 2;break;
  304.                 }
  305.                 //buffer = bbt->bufferList[1];
  306.                 rolling = 1;break;
  307.             }
  308.  
  309.             if(rolled == 1){
  310.                 if(bbt->bufferList[0]->n_items==0){
  311.                     if(bbt->bufferList[2]->n_items==0){
  312.                         printf("**************SHOULD NOT EVEN GET HERE********************\n");
  313.                         continue;              
  314.                     }
  315.                     //buffer = bbt->bufferList[2];
  316.                     rolling = 2;break;
  317.                 }
  318.                 //buffer = bbt->bufferList[0];
  319.                 rolling = 0;break;
  320.             }
  321.  
  322.             if(rolled == 2){
  323.                 if(bbt->bufferList[0]->n_items==0){
  324.                     if(bbt->bufferList[1]->n_items==0){
  325.                         printf("**************SHOULD NOT EVEN GET HERE********************\n");
  326.                         continue;              
  327.                     }
  328.                     //buffer = bbt->bufferList[1];
  329.                     rolling = 1;break;
  330.                 }
  331.                 //buffer = bbt->bufferList[0];
  332.                 rolling = 0;break;
  333.             }
  334.             printf("**************SHOULD NEVER GET HERE********************\n");
  335.            
  336.            
  337.             //sem_post(&v1);
  338.             continue;
  339.         }break;
  340.     }
  341.     printf("------------------CONSUMING IN %i / rolled %i---------------------\n",rolling,rolled);
  342.     //bbt->inception =0;
  343.     buffer = bbt->bufferList[rolling];
  344.     printf("Buffer = %i, first = %i, item = %c\n",rolling, buffer->first,buffer->itemBuffer[buffer->first].item);
  345.     item = buffer->itemBuffer[buffer->first];
  346.     buffer->itemBuffer[buffer->first].item = 0;
  347.     if(buffer->first == buffer->length-1){
  348. /*  //was going to shorten buffer when needed, but some more modifications would be needed
  349.         if((buffer->length>INITIAL_SIZE) &&(buffer->n_items<((3*INITIAL_SIZE)/4))){//shortens buffer for to have some efficiency of memory
  350.             buffer = shortenBuffer(buffer);
  351.             buffer->n_items--;
  352.             return item;
  353.         }
  354. */
  355.         buffer->first =0;
  356.         buffer->n_items--;
  357.         //sem_wait(&v3);
  358.         //vault = bbt;
  359.         sem_post(&v1);
  360.         sem_post(&v2);
  361.         printf("RC = %c\n",item.item); 
  362.         printInfo(buffer,rolling);
  363.         return ;
  364.     }
  365.    
  366.         buffer->first++;
  367.         buffer->n_items--;
  368.    
  369.  
  370.     printf("RC = %c\n",item.item); 
  371.     printInfo(buffer,rolling);
  372.     //vault = bbt;
  373.     sem_post(&v2);
  374.     sem_post(&v1);
  375.     return;
  376. }
  377.  
  378.  
  379. void* setBuff(size_t size){
  380.     void *buff;
  381.     buff =malloc(sizeof(size));
  382.     return buff;
  383. }
  384. int main(int argc, char *argv[]){
  385.     int t;
  386.     pthread_t threads[NUM_THREADS];
  387.     pthread_t threads_c[NUM_THREADS+1];
  388.     size_t buffer_batch_t;
  389.     //vault= (buffer_batch_t *)malloc(sizeof(buffer_batch_t));
  390.     vault =setBuff(buffer_batch_t);
  391.     char rc,rc1[NUM_THREADS];
  392.     int initialSize = INITIAL_SIZE; /*initial size of buffers*/
  393.     int i;
  394.     srand(time(NULL));
  395.     sem_init(&v1,0,1);
  396.     sem_init(&v2,0,0);
  397.     sem_init(&v3,0,0);
  398.     //need 3 buffers that will not overflow - thus needing a function that extends the array.
  399.     buffer_t *lowerCase = (buffer_t*)malloc(sizeof(buffer_t));
  400.     buffer_t *upperCase = (buffer_t*)malloc(sizeof(buffer_t));
  401.     buffer_t *numerical = (buffer_t*)malloc(sizeof(buffer_t));
  402.     vault->bufferList = (buffer_t**)malloc(sizeof(buffer_t*)*3);
  403.     vault->inception =-1;  
  404.    
  405.    
  406.    
  407.     //allocating and initializing buffers
  408.     lowerCase = setBuffer(initialSize, 0, allocBuffer(initialSize));
  409.     upperCase = setBuffer(initialSize,0,allocBuffer(initialSize));
  410.     numerical = setBuffer(initialSize,0,allocBuffer(initialSize));
  411.  
  412.     vault->bufferList[0] = lowerCase;
  413.     vault->bufferList[1] = upperCase;
  414.     vault->bufferList[2] = numerical;
  415.     printf("In Main():  Creating 10 Consumers then 9 Prodcuers\n");
  416.     for (t=0;t<10;t++){
  417.         //printf("In main: CREATING CONSUMER THREAD %iid\n",t);
  418.         //buffers->consumerid = t;
  419.         rc = pthread_create(&threads_c[t],NULL,consumer,NULL);
  420.         if(rc){
  421.             printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
  422.             exit(-1);
  423.  
  424.         }
  425.  
  426.     }
  427.  
  428.     for (t=0;t<3;t++){
  429.         //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
  430.         rc = pthread_create(&threads[t],NULL,(void*)producer_lc,NULL);
  431.         if(rc){
  432.             printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
  433.             exit(-1);
  434.  
  435.         }
  436.    
  437.     }
  438.  
  439.     for (t=3;t<6;t++){
  440.         //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
  441.         rc = pthread_create(&threads[t],NULL,(void*)producer_uc,NULL);
  442.         if(rc){
  443.             printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
  444.             exit(-1);
  445.  
  446.         }
  447.    
  448.     }
  449.        
  450.     for (t=6;t<9;t++){
  451.         //printf("In main: CREATING PRODUCER THREAD %iid\n",t);
  452.         rc = pthread_create(&threads[t],NULL,(void*)producer_num,NULL);
  453.         if(rc){
  454.             printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
  455.             exit(-1);
  456.  
  457.         }
  458.  
  459.     }
  460. /*
  461.     for (t=0;t<9;t++){
  462.         printf("In main: CREATING CONSUMER THREAD %iid\n",t);
  463.         //buffers->consumerid = t;
  464.         rc = pthread_create(&threads_c[t],NULL,(void*)consumer,NULL);
  465.         if(rc){
  466.             printf("ERROR: return code from pthread_create() is %d and it dookied everywhere!\n",rc);
  467.             exit(-1);
  468.  
  469.         }
  470.  
  471.     }
  472. */
  473.     producer_num();
  474.     printf("In Main(): One more produced to allow for final thread to complete.\n");
  475.     pthread_exit(NULL);
  476.   return 0;
  477. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement