TEST(LockFreeQueue, PuthAndPop) {
  LockFreeQueue<int, max_size> queue;
  std::vector<int> result;

  std::thread writer{[&queue]() {
    for (auto i = 0; i < 10; ++i) {
      queue.push(i);
    }
    queue.push(done);
  }};

  std::thread reader{[&queue, &result]() {
    for (;;) {
      while (queue.size() == 0) {
        // busy wait
      }
      auto element = queue.front();
      queue.pop();
      if (element == done) {
        break;
      }
      std::cout << "Got: " << element << '\n';
      result.push_back(element);
    }
  }};

  writer.join();
  reader.join();

  ASSERT_EQ(std::vector<int>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), result);
}
예제 #2
0
void Genome::read ( std::ifstream& input ) {
  log("Genome: reading file...");
  unsigned int L(1);                         // line counter
  LockFreeQueue<std::vector<std::string>> q;
  
  auto readerTask = [&q,&input]() {
    debug("Starting reader thread...");
      for (std::string line; getline(input, line);) {
	q.push(strsplit(line, "\t"));
      }
      q.done();
      debug("All data read and tokenized, closing reader rhread");
  };
  
  auto parserTask = [&q,&L,this]() {
    debug("Starting parser thread...");
    std::vector<std::string> splits;
    while(q.pop(splits)) {
      assume(parseDataLine(splits), "Could not parse data in line " + std::to_string(L), false);
      L++;
    }
    debug("All tokens processed, closing parser thread");
  };
  
  // read and parse header lines sequentially
  for (std::string line; getline(input, line);) {
    //    std::cout << "Line #" << L << std::endl;
    if (line[0] == '@') {
      assume(parseHeaderLine(line), "Could not parse header in line " + std::to_string(L), false);
    }
    else {
      break;  // header lines parsed, break and begin threaded processing
    }
    L++;
  }
  
  // init and start threads
  std::thread readerThread(readerTask);
  std::thread parserThread(parserTask);
  
  // wait for threads to finish
  readerThread.join();
  parserThread.join();
  
  if (multistrand != nullptr) {
    log("Found " + std::to_string(multistrand->size()) + " strand switching events");
  }
  if (circular != nullptr) {
    log("Found " + std::to_string(circular->size()) + " circular transcripts");
  }

}
int main()
{
	bool finished = false;
	
	timestruct begin, end, *diff;
	clock_gettime(CLOCK_MONOTONIC, &begin);
	unsigned int count = 0;	
	LockFreeQueue<message> q;

	omp_set_num_threads(4);
	#pragma omp parallel shared(finished, count)
	{
		#pragma omp sections
		{
			#pragma omp section
			{
				for( unsigned int i = 0; i < 999999 ; ++i )
				{
					q.push(new message);
				}
				finished = true;
			}
			#pragma omp section
			{
				message* m;
				while((m = q.pop()) != NULL || !finished )
				{
					if(m)
					{
						__sync_fetch_and_add(&count, 1);
						delete m;
					}
				}
			}
			#pragma omp section
			{
				message* m = NULL;
				while((m = q.pop()) != NULL || !finished )
				{
					if(m)
					{
						__sync_fetch_and_add(&count, 1);
						delete m;
					}
				}
			}
			#pragma omp section
			{
				message* m = NULL;
				while((m = q.pop()) != NULL || !finished )
				{
					if(m)
					{
						__sync_fetch_and_add(&count, 1);
						delete m;
					}
				}
			}
		}		
	}
	
	clock_gettime(CLOCK_MONOTONIC, &end);
	diff = time_diff(&end, &begin);
	
	std::cout << "=========================" << std::endl;
	std::cout << "tv_sec: " << diff->tv_sec << std::endl << "tv_nsec: " << diff->tv_nsec << std::endl;
	std::cout << "count: " << count << std::endl;
	return 0;
}