daily pastebin goal
57%
SHARE
TWEET

Untitled

a guest Apr 16th, 2018 67 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Histogram text analyzer for program 5.
  3.  *
  4.  * Author: Andrew Porter
  5.  * Date: 04/13/2018
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <pthread.h>
  13.  
  14. #include "concurrentBuffer.h"
  15.  
  16. #define MAX_WORD 50
  17. #define MIN_WORD 6
  18.  
  19. #ifndef BUFFER_SIZE
  20. #define BUFFER_SIZE 10
  21. #endif
  22.  
  23. long glob_histogram[MAX_WORD+1];
  24.  
  25. static char* getWord (FILE* f);
  26. static void *work_one(void *info);
  27. static void *work_two(void *buffer);
  28.  
  29. typedef struct {
  30.   FILE *fp;
  31.   void *buffer;
  32. } INFO;
  33.  
  34. /**
  35.  * Histogram text analyzer for program 5.
  36.  */
  37. int main (int argc, char *argv[])
  38. {
  39.     if (argc < 2)
  40.     {
  41.         fprintf(stderr, "usage: ./histogram [file_names]\n");
  42.         exit(-1);
  43.     }
  44.  
  45.     // create concurrent buffer
  46.     void *cBuffer = createConcurrentBuffer(BUFFER_SIZE);
  47.     if (cBuffer == NULL)
  48.     {
  49.       fprintf(stderr, "can't create the concurrent buffer\n");
  50.       exit(-1);
  51.     }
  52.  
  53.     pthread_t thread1array[argc+1];
  54.     pthread_t thread2array[argc+1];
  55.  
  56.     for (int i = 1; i < argc; i++)
  57.     {
  58.       // open the file to be read
  59.       FILE *fp = fopen(argv[i], "r");
  60.       if (fp == NULL)
  61.       {
  62.         fprintf(stderr, "can't open %s\n", argv[1]);
  63.         exit(-1);
  64.       }
  65.  
  66.       // create struct to pass info to first thread
  67.       INFO *ip = malloc(sizeof(INFO));
  68.       if (ip == NULL)
  69.       {
  70.         fprintf(stderr, "can't malloc the INFO struct\n");
  71.         exit(-1);
  72.       }
  73.       ip->fp = fp;
  74.       ip->buffer = cBuffer;
  75.  
  76.       // create the first thread
  77.       pthread_t *thread1 = thread1array+i;
  78.       if (pthread_create(thread1, NULL, work_one, ip) != 0)
  79.       {
  80.         fprintf(stderr, "can't create thread 1\n");
  81.         exit(-1);
  82.       }
  83.  
  84.       // create the second thread
  85.       pthread_t *thread2 = thread2array+i;
  86.       if (pthread_create(thread2, NULL, work_two, cBuffer) != 0)
  87.       {
  88.         fprintf(stderr, "can't create thread 2\n");
  89.         exit(-1);
  90.       }
  91.     }
  92.  
  93.     // wait for threads to finish and sum partial results into global sum
  94.     for (int i = 1; i < argc; i++)
  95.     {
  96.       // wait for the first thread to finish
  97.       if (pthread_join(thread1array[i], NULL))
  98.       {
  99.         fprintf(stderr, "join for thread 1 fails\n");
  100.         exit(-1);
  101.       }
  102.  
  103.       // wait for the second thread to finish
  104.       void *ret;
  105.       if (pthread_join(thread2array[i], &ret))
  106.       {
  107.         fprintf(stderr, "join for thread 2 fails\n");
  108.         exit(-1);
  109.       }
  110.  
  111.       for (int i = 0; i < MAX_WORD+1; i++)
  112.       {
  113.           glob_histogram[i] += ((long*)ret)[i];
  114.       }
  115.  
  116.       free(ret);  // free return value
  117.     }
  118.  
  119.     // free the concurrent buffer
  120.     deleteConcurrentBuffer(cBuffer);
  121.  
  122.     // print the global histogram
  123.     for (int i = 6; i < MAX_WORD+1; i++)
  124.     {
  125.       printf("%d %ld\n", i, glob_histogram[i]);
  126.     }
  127.  
  128.     return 0;
  129. }
  130.  
  131. /**
  132.  *    getWord from input file.
  133.  *    code used from serialHistrogram.c.
  134.  *
  135.  *    @param file
  136.  *    @return char*
  137.  */
  138. static char *getWord(FILE *fp)
  139. {
  140.   char buf[MAX_WORD+1];
  141.   int c;
  142.   int i = 0;
  143.  
  144.   //read until a letter or EOF is seen
  145.   c = getc(fp);
  146.   while (!isalpha(c))
  147.   {
  148.     if (c == EOF)
  149.     {
  150.       return NULL;
  151.     }
  152.     c = getc(fp);
  153.   }
  154.  
  155.   // now read until a non-letter or EOF is seen
  156.   while (isalpha(c))
  157.   {
  158.     // if word too long, stop storing letters
  159.     if (i < MAX_WORD)
  160.     {
  161.       buf[i] = tolower(c);
  162.     }
  163.     i += 1;
  164.     c = getc(fp);
  165.   }
  166.  
  167.   // if word too short or too long, can discard it and try to read another
  168.   if ((i < MIN_WORD) || (i > MAX_WORD))
  169.   {
  170.     // just recurse
  171.     return getWord(fp);
  172.   }
  173.   // otherwise make a safe copy of word
  174.   else {
  175.     buf[i] = 0;
  176.     char *p = malloc(strlen(buf)+1);
  177.     strcpy(p, buf);
  178.     return p;
  179.   }
  180. }
  181.  
  182. /**
  183.  *    work function for the first thread (the producer)
  184.  *
  185.  *    @param info
  186.  *    @return void
  187.  */
  188. static void *work_one(void *info)
  189. {
  190.     INFO *ip = info;
  191.  
  192.     // read the lines in the file
  193.     char *word;
  194.     while ((word = getWord(ip->fp)) != NULL)
  195.     {
  196.         putConcurrentBuffer(ip->buffer, word);
  197.     }
  198.  
  199.     // put a NULL to indicate EOF
  200.     putConcurrentBuffer(ip->buffer, NULL);
  201.  
  202.     // close the file
  203.     fclose(ip->fp);
  204.  
  205.     // free the memory for the "info"
  206.     free(info);
  207.  
  208.     return NULL;
  209. }
  210.  
  211. /**
  212.  *    work function for the second thread (the consumer)
  213.  *
  214.  *    @param info
  215.  *    @return void
  216.  */
  217. static void *work_two(void *buffer)
  218. {
  219.     // get lines from the buffer
  220.     // and sum the number of characters in the line
  221.  
  222.     char *word;
  223.     long* temp = malloc(sizeof(glob_histogram));
  224.     if ( temp == NULL )
  225.     {
  226.         printf("malloc failed");
  227.         exit(-1);
  228.     }
  229.     for (int i = 0; i < MAX_WORD+1; i++)
  230.     {
  231.       temp[i] = 0;
  232.     }
  233.  
  234.     while ((word = getConcurrentBuffer(buffer)) != NULL)
  235.     {
  236.         temp[strlen(word)]++;
  237.         free(word);
  238.     }
  239.  
  240.     return (void*) temp;
  241. }
RAW Paste Data
Top