title: Block/Freeze in Concurrent c++ code using Intel TBB
body: <p>I tried out writing a pipelined version of  Bitonic Sort using with File Read, Sort, File Write stages using Intel TBB as shown below. The code freezes at the spinlock at while(!outQueue.try_pop(line)); in the FileWriter Filter. Can someone explain why this might be?</p>
  
  <p>update:
  I did some further testing and discovered that internal_try_pop that is called by try_pop from the header file _concurrent_queue_internal.h has a compare_and_swap operation that fails forever for this particular try_pop. The following are values i extracted from the internal_try_pop</p>
  
  <pre><code>head counter(k)15
  tail counter1605177747
  item ticket(tk)15
  k after head CAS 15
  (k=tk)15,15---break!!
  </code></pre>
  
  <p>I think the tail counter value is garbage. The only reason i can think of for this situation is that the value added to the queue by the sorter may be implicitly modified by it thus making it unavailable. </p>
  
  <p>Any ideas? </p>
  
  <p>Thanks :)</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  #include &lt;algorithm&gt;
  #include &lt;fstream&gt;
  #include "tbb\parallel_for.h"
  #include "tbb\blocked_range.h"
  #include "tbb\pipeline.h"
  #include "tbb\concurrent_queue.h"
  
  using namespace tbb;
  using namespace std;
  
  // Filter that writes lines to the output file.
  class FileWriterFilter: public tbb::filter {
  string outPath;
  public:
  FileWriterFilter(string outPath );
  /*override*/void* operator()( void* item );
  };
  
  FileWriterFilter::FileWriterFilter( string outPath ) :
  tbb::filter(/*is_serial=*/true),
  outPath(outPath)
  {
  }
  
  void* FileWriterFilter::operator()( void* item ) {
  
  concurrent_queue&lt;string&gt;&amp; outQueue = *static_cast&lt;concurrent_queue&lt;string&gt;*&gt;(item);
  string line;
  while(!outQueue.try_pop(line));
  
  ofstream myfile(outPath);
  if (myfile.is_open())
  {
      myfile &lt;&lt;line&lt;&lt;endl;
  }
  //myfile.close();
  return NULL;
  
   }
  
   class FileReaderFilter: public tbb::filter {
  public:
  
  FileReaderFilter(string inPath);
  
  private:
  ifstream ifs;
  tbb::concurrent_queue&lt;string&gt; queue;
  /*override*/ void* operator()(void*);
  
   };
  
   FileReaderFilter::FileReaderFilter(string inPath ) :
  filter(/*is_serial=*/true),
  ifs(inPath)
  {
  }
  
   void* FileReaderFilter::operator()(void*) {
  
  string temp;
  
  if( getline( ifs, temp ))
  {
  
      queue.push(temp);
  }
  
  return &amp;queue;
   }
  
  class BitonicSort: public tbb::filter{
  
  public:
      BitonicSort();
  /*override*/void* operator()( void* item );
  
  size_t *a;
  
  private : static const  bool ASCENDING=true, DESCENDING=false;
  
  public :void sort(size_t *b,int n)
  {
      a=b;
      bitonicSort(0,n,ASCENDING);
  
  }
  
  private: void bitonicSort(int lo,int n,bool dir)
  {
      if(n&gt;1)
      {
          int m=n/2;
          bitonicSort(lo,m,ASCENDING);
  
          bitonicSort(lo+m,m,DESCENDING);
          bitonicMerge(lo,n,dir);
  
  
      }
  
  }
  
  private : void bitonicMerge(int lo,int n,bool dir)
       {
           if(n&gt;1)
           {
               int m=n/2;
               for(int i=lo;i&lt;lo+m;i++)
               {
                   compare(i,i+m,dir);
  
               }
               bitonicMerge(lo,m,dir);
               bitonicMerge(lo+m,m,dir);
           }
       }
  
  private : void compare(int i,int j, bool dir)
            {
                if(dir==a[i]&gt;a[j])
                {
                    exchange(i,j);
  
                }
  
            }
  
  private : void exchange(int i,int j)
            {
              /*  cout&lt;&lt;a[i]&lt;&lt;" "&lt;&lt;a[j]&lt;&lt;endl;*/
                int t=a[i];
                a[i]=a[j];
                a[j]=t;
                /*cout&lt;&lt;a[i]&lt;&lt;" "&lt;&lt;a[j]&lt;&lt;endl&lt;&lt;endl;*/
            }
  
     private :string convertInt(int number)
     {
     stringstream ss;//create a stringstream
     ss &lt;&lt; number;//add number to the stream
     return ss.str();//return a string with the contents of the stream
  }
   };
  
  
   BitonicSort::BitonicSort() :
  tbb::filter(/*serial=*/false)
   {}
  
   /*override*/void* BitonicSort::operator()( void* item ) {
  
  int num_elem=2048;
  size_t *max = new size_t[num_elem];
  concurrent_queue&lt;string&gt;&amp; queue = *static_cast&lt;concurrent_queue&lt;string&gt;*&gt;(item);
  concurrent_queue&lt;string&gt; outQueue;
  string line;
  while(!queue.try_pop(line));  
  istringstream iss(line);
  int i=0;
  do
  {
      string sub;
      iss &gt;&gt; sub;
      max[i]=atoi(sub.c_str());;
      i++;
  } while (iss);
  
  sort(max,num_elem);
  
  string out;
  
  for(int i=0;i&lt;num_elem;i++)
  {
      out.append(convertInt(max[i]).append(" "));
  }
  
  outQueue.push(out);
  
  return &amp;outQueue;
   }
  
  
   int main() {
  
  tbb::pipeline pipeline;
  
  FileReaderFilter reader("sample.txt");
  pipeline.add_filter(reader);
  
  BitonicSort sorter;
  pipeline.add_filter(sorter);
  
  FileWriterFilter writer("test.txt");
  pipeline.add_filter(writer);
  
  pipeline.run(3);
  
  
  pipeline.clear();
  
  system("PAUSE");
   }
  </code></pre>