static typename Wrapper::unwrap_type get(Wrapper &w) { return w.get(); }
void test_lockfree() { Wrapper wrapper; Duration duration(typeid(Wrapper).name()); int const PRODUCER_NUM = 32; int const CONSUMER_NUM = 32; int const DATA_COUNT = 1000; std::vector<std::thread*> producers; std::vector<std::thread*> consumers; std::atomic<int> count(0); // atomic默认不会初始化 std::atomic_flag sets[DATA_COUNT*PRODUCER_NUM]; for (int i : range(DATA_COUNT*PRODUCER_NUM)) { sets[i].clear(); } // producers Barrier bp(PRODUCER_NUM); for (int i : range(PRODUCER_NUM)) { producers.push_back(new std::thread([&, i]() { bp.await(); for (int j : range(DATA_COUNT)) { typename Wrapper::Node* node = new typename Wrapper::Node(); // printf("n:%p\n", node); node->data = count.fetch_add(1); // printf("%d, ", node->data); // Make sure flag is not set, then set the flag. assert(!sets[node->data].test_and_set()); // return last flag wrapper.set(node); std::this_thread::yield(); } })); } // consumers Barrier bc(PRODUCER_NUM); std::stringstream ss[CONSUMER_NUM]; for (int i : range(CONSUMER_NUM)) { consumers.push_back(new std::thread([&, i]() { // ss[i] << "thread[" << i << "]: "; bc.await(); for (int j : range(DATA_COUNT)) { typename Wrapper::Node* node = nullptr; while (!(node = wrapper.get())) { // usleep(1); std::this_thread::yield(); } // Make sure flag is set, then clear the flag. assert(sets[node->data].test_and_set()); sets[node->data].clear(); // ss[i] << node->data << ", "; // printf("d:%p\n", node); delete node; std::this_thread::yield(); } })); } for (int i : range(PRODUCER_NUM)) { producers[i]->join(); delete producers[i]; } for (int i : range(CONSUMER_NUM)) { consumers[i]->join(); delete consumers[i]; } for (int i : range(CONSUMER_NUM)) { // std::cout << ss[i].str() << std::endl; } for (int i : range(DATA_COUNT)) { // Make sure all flags are not set. assert(!sets[i].test_and_set()); } }