title: Managing a linked list with pthreads
body: <p>I am attempting to simulate a bank with a line of customers represented by a linked list with a thread calculating the probability that a customer walks in (with a preset probability) every unit of time and adds the customer to the end of the line while several teller threads remove a customer from the beginning of the line and I keep getting segmentation faults at seemingly unpredictable points during each simulation.  Below is the code I use for adding too and removing from the list.  The error seems to occur  because the customer thread is attempting to add while a teller is removing.</p>
  
  <pre><code>void addToQ(int x, void *arg){
      printf("ADD ATTEMPT\n");
      struct shiftInfo *info = (struct shiftInfo *) arg;
      if (head -&gt; ID == -1){ //No clients in line
          head -&gt; ID = x;
          head -&gt; next = dummy;
          tail = head;
      }
  
      else{ //clients already in line
          tail -&gt; next = (NODE *)malloc(sizeof(NODE));
          tail = tail -&gt; next;
          tail -&gt; ID = x;
          tail -&gt; next = dummy;
          info -&gt; inQ++;
      }
      printf("ADD SUCCESS\n");
  }
  //Removes node closest to root
  //Assumes: root != end
  void removeFromQ(void *arg){
      printf("REMOVE ATTEMPT\n");
      struct shiftInfo *info = (struct shiftInfo *) arg;
      if (head -&gt; next == dummy){ //only one element
          printf("SCENARIO 1\n");
          head -&gt; ID = -1;
      }
      else{
          printf("SCENARIO 2\n");
          curr = head -&gt; next;
          head = curr -&gt; next;
          printf("Halfway\n");
          if ((head -&gt; next == NULL) || (head -&gt; next == dummy))
              tail = head;
      }
      info -&gt; inQ--;
      printf("REMOVE SUCCESS\n");
  }
  </code></pre>
  
  <p>Here are the thread functions:</p>
  
  <pre><code>void *customerT(void *arg){
      int custID = 100;
      float newCust = 0;
      struct shiftInfo *info = (struct shiftInfo *) arg;
      float aRate = info -&gt; arrivalRate;
      pthread_mutex_lock (&amp;start); //Ensures Customers don't start before Tellers get to work
      pthread_mutex_unlock (&amp;start);
      while(0&lt;info -&gt; simTime){
          newCust = (double)rand() / (double)RAND_MAX;
          if (newCust &lt;= aRate){
              pthread_mutex_lock (&amp;start);
              addToQ(custID,(void *)info);
              pthread_mutex_unlock (&amp;start);
              custID++;
              }
          sleep(1/60);
      }
      pthread_exit(NULL);
   }
  
  
  void *teller(void *arg){
      struct shiftInfo *info = (struct shiftInfo *) arg;
      int clientID;
      int clients = info -&gt; inQ;
      pthread_mutex_lock (&amp;start); //Ensures tellers dont start before customers arrive
      pthread_mutex_unlock (&amp;start);
      while(0&lt;info -&gt; simTime){
          pthread_mutex_lock (&amp;accessQ);
          clients = info -&gt; inQ;
          if(head -&gt; ID &gt; 0){
              pthread_mutex_lock (&amp;start);
              removeFromQ((void *)info);
              pthread_mutex_unlock (&amp;start);
              printf("CLIENT OBTAINED\n");
          }
          printf("In Q %d\n", clients);
          pthread_mutex_unlock (&amp;accessQ);
          sleep((info -&gt; serviceTime)/60);
          }
      pthread_exit(NULL);
  }
  </code></pre>
  
  <p>and in case it is relevant, here is the manager thread function:</p>
  
  <pre><code>//Creates Customer thread, Teller threads, and timer thread
  void *mainThread(void *info){
      head = (NODE *)malloc(sizeof(NODE));
      head -&gt; ID = -1;
      head -&gt; next = dummy;
      tail = head;
      int status;
      struct shiftInfo *I = info; 
      pthread_mutex_init(&amp;start, NULL);
      pthread_mutex_init(&amp;removeID, NULL);
      pthread_mutex_init(&amp;accessQ, NULL);
      pthread_mutex_lock (&amp;start);
  
      printf("Scheduling Tellers\n");
      pthread_t threads[(I -&gt; tellers)];
      for (int i = 0; i &lt; (I -&gt; tellers); i++){
          I -&gt; threadID = i;
          status = pthread_create(&amp;threads[i], NULL, teller, (void *)info);
          if (status){
              printf("ERROR CODE: %d\n", status);
              exit(-1);
          }
      }
  
      printf("Preparing Customers\n");
      pthread_t customer;
      status = pthread_create(&amp;customer, NULL, customerT, (void *)info);
          if (status){
              printf("ERROR CODE: %d\n", status);
              exit(-1);
          }
  
      printf("Making Timer\n");
      pthread_t time;
          status = pthread_create(&amp;time, NULL, timer, (void *)info);
          if (status){
              printf("ERROR CODE: %d\n", status);
              exit(-1);
          }
  
      pthread_mutex_unlock (&amp;start);
  }
  </code></pre>