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"); } }
void func2(void) { for(int i = 100000; i < 200000; i++) { queue.push_back(i); } }
void func1(void) { for(int i = 0; i <100000 ; i++) { queue.push_back(i); } }
void dequeue(LockFreeQueue<DummyEntry> &the_queue, std::list<DummyEntry*> &enqueued) { DummyEntry* expected = enqueued.front(); enqueued.pop_front(); SCOPED_TRACE(testing::Message() << "expected=0x" << std::hex << reinterpret_cast<uintptr_t>(expected) << std::dec << ", key=" << expected->_key); EXPECT_TRUE(contains(expected->_key, the_queue)); DummyEntry* ret = the_queue.dequeue(); EXPECT_EQ(expected->_key, ret->_key); EXPECT_EQ(expected, ret); EXPECT_FALSE(contains(expected->_key, the_queue)); EXPECT_TRUE(the_queue.unsafe_consistent()); check_size(enqueued.size(), the_queue); the_queue.unsafe_dump(std::cout); delete ret; }
void enqueue(LockFreeQueue<DummyEntry> &the_queue, std::list<DummyEntry*> &enqueued, uint32_t key) { DummyEntry* entry = new DummyEntry(key); SCOPED_TRACE(testing::Message() << "new pointer=0x" << std::hex << reinterpret_cast<uintptr_t>(entry) << std::dec << ", key=" << key); enqueued.push_back(entry); EXPECT_FALSE(contains(key, the_queue)); the_queue.enqueue(entry); the_queue.unsafe_dump(std::cout); EXPECT_TRUE(contains(key, the_queue)); EXPECT_TRUE(the_queue.unsafe_consistent()); check_size(enqueued.size(), the_queue); the_queue.unsafe_dump(std::cout); }
void func3(void) { for(int i = 0; i < 100004; i++) { std::cout<<queue.pop_front()<<" "; } std::cout<<std::endl; }
bool contains(uint32_t key, LockFreeQueue<DummyEntry> &the_queue) { std::vector<DummyEntry*> out; the_queue.unsafe_as_vector(out); for (size_t i = 0; i < out.size(); ++i) { if (out[i]->_key == key) { return true; } } return false; }
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); }
NodeIterator(LockFreeQueue<T> &queue) : mLastReturned(queue.fork()), mCurrent(const_cast<Node*>(mLastReturned->mNext)), mFreePool(&queue.mFreeNodePool) { }
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; }
void check_size(size_t expected, LockFreeQueue<DummyEntry> &the_queue) { // at least in single-thread situation, all of them should be correct EXPECT_EQ(expected, the_queue.unsafe_size()); EXPECT_EQ(expected, the_queue.safe_size()); EXPECT_EQ(expected, the_queue.approximate_size()); }