[libc++] (Take 2) Add a test that uses the debug database from multiple threads

In r358591, I added a test that uses the debug database from multiple
threads and that helped us uncover the problem that was fixed in r355367.
However, the test broke the tsan CI bots, and I think the problem is the
test allocator that was used in the test (which is not thread safe).

I'm committing again without using the test allocator, and in a separate
test file.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@358610 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/libcxx/debug/containers/db_sequence_container_iterators.multithread.pass.cpp b/test/libcxx/debug/containers/db_sequence_container_iterators.multithread.pass.cpp
new file mode 100644
index 0000000..3cd0ce0
--- /dev/null
+++ b/test/libcxx/debug/containers/db_sequence_container_iterators.multithread.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: windows
+// UNSUPPORTED: libcpp-has-no-threads
+// MODULES_DEFINES: _LIBCPP_DEBUG=1
+
+// Can't test the system lib because this test enables debug mode
+// UNSUPPORTED: with_system_cxx_lib
+
+// test multihtreaded container debugging
+
+#define _LIBCPP_DEBUG 1
+
+#include <cassert>
+#include <cstddef>
+#include <deque>
+#include <list>
+#include <thread>
+#include <vector>
+#include "container_debug_tests.hpp"
+
+
+template <typename Container>
+Container makeContainer(int size) {
+  Container c;
+  typedef typename Container::value_type ValueType;
+  for (int i = 0; i < size; ++i)
+    c.insert(c.end(), ValueType(i));
+  assert(c.size() == static_cast<std::size_t>(size));
+  return c;
+}
+
+template <typename Container>
+void ThreadUseIter() {
+  const size_t maxRounds = 7;
+  struct TestRunner{
+    void operator()() {
+      for (size_t count = 0; count < maxRounds; count++) {
+        const size_t containerCount = 11;
+        std::vector<Container> containers;
+        std::vector<typename Container::iterator> iterators;
+        for (size_t containerIndex = 0; containerIndex < containerCount; containerIndex++) {
+          containers.push_back(makeContainer<Container>(3));
+          Container& c = containers.back();
+          iterators.push_back(c.begin());
+          iterators.push_back(c.end());
+        }
+      }
+    }
+  };
+
+  TestRunner r;
+  const size_t threadCount = 4;
+  std::vector<std::thread> threads;
+  for (size_t count = 0; count < threadCount; count++)
+    threads.emplace_back(r);
+  r();
+  for (size_t count = 0; count < threadCount; count++)
+    threads[count].join();
+}
+
+int main(int, char**) {
+  ThreadUseIter<std::vector<int> >();
+  return 0;
+}