int main() { #if _LIBCPP_STD_VER > 11 { m.lock(); std::vector<std::thread> v; for (int i = 0; i < 5; ++i) v.push_back(std::thread(f1)); std::this_thread::sleep_for(ms(250)); m.unlock(); for (auto& t : v) t.join(); } { m.lock(); std::vector<std::thread> v; for (int i = 0; i < 5; ++i) v.push_back(std::thread(f2)); std::this_thread::sleep_for(ms(300)); m.unlock(); for (auto& t : v) t.join(); } #endif // _LIBCPP_STD_VER > 11 }
/** * insert method; find the right place in the list, add val so that it is * in sorted order; if val is already in the list, exit without inserting */ void insert(int val) { mtx.lock(); // traverse the list to find the insertion point Node* prev =sentinel; Node* curr = prev->next; while (curr != NULL) { if (curr->val >= val) break; prev = curr; curr = prev->next; } // now insert new_node between prev and curr // // NB: if the test fails, it means we quit the above loop on account // of /finding/ val, in which case we just exit if (!curr || ((curr->val) > val)) { // create the new node Node* i = (Node*)malloc(sizeof(Node)); i->val = val; i->next = curr; // insert it prev->next = i; } mtx.unlock(); }
/** * To remove from the list, we need to keep a pointer to the previous * node, too. Note that this is much easier on account of us having a * sentinel */ void remove(int val) { mtx.lock(); // find the node whose val matches the request Node* prev = sentinel; Node* curr = prev->next; while (curr != NULL) { // if we find the node, disconnect it and end the search if (curr->val == val) { prev->next = curr->next; // delete curr... free(curr); break; } else if (curr->val > val) { // this means the search failed break; } // advance one node prev = curr; curr = prev->next; } mtx.unlock(); }
int main() { m.lock(); std::thread t(f); std::this_thread::sleep_for(WaitTime); m.unlock(); t.join(); }
void g() { time_point t0 = Clock::now(); m.lock_shared(); time_point t1 = Clock::now(); m.unlock_shared(); ns d = t1 - t0; assert(d < Tolerance); // within tolerance }
void f() { time_point t0 = Clock::now(); m.lock(); time_point t1 = Clock::now(); m.unlock(); ns d = t1 - t0 - WaitTime; assert(d < Tolerance); // within tolerance }
int main() { m.lock(); std::vector<std::thread> v; for (int i = 0; i < 5; ++i) v.push_back(std::thread(f)); std::this_thread::sleep_for(ms(250)); m.unlock(); for (auto& t : v) t.join(); }
void f() { time_point t0 = Clock::now(); assert(!m.try_lock_shared()); assert(!m.try_lock_shared()); assert(!m.try_lock_shared()); while(!m.try_lock_shared()) ; time_point t1 = Clock::now(); m.unlock_shared(); ns d = t1 - t0 - ms(250); assert(d < ms(200)); // within 200ms }
/** * lookup method: just traverse the list in order, and see if we find the * val */ bool lookup(int val) { mtx.lock_shared(); Node* curr = sentinel->next; while (curr != NULL) { if (curr->val >= val) break; curr = curr->next; } bool tmp = ((curr != NULL) && (curr->val == val)); mtx.unlock_shared(); return tmp; }
int main() { m.lock(); std::vector<std::thread> v; for (int i = 0; i < 5; ++i) v.push_back(std::thread(f)); std::this_thread::sleep_for(WaitTime); m.unlock(); for (auto& t : v) t.join(); m.lock_shared(); for (auto& t : v) t = std::thread(g); std::thread q(f); std::this_thread::sleep_for(WaitTime); m.unlock_shared(); for (auto& t : v) t.join(); q.join(); }