You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2007/06/14 01:07:21 UTC

svn commit: r547057 - /incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp

Author: sebor
Date: Wed Jun 13 16:07:20 2007
New Revision: 547057

URL: http://svn.apache.org/viewvc?view=rev&rev=547057
Log:
2007-06-13  Martin Sebor  <se...@roguewave.com>

	* 21.string.cons.mt.cpp: New test exercising the thread safety
	of a small subset of basic_string ctors and assignment operators.

Added:
    incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp

Added: incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp?view=auto&rev=547057
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp (added)
+++ incubator/stdcxx/trunk/tests/strings/21.string.cons.mt.cpp Wed Jun 13 16:07:20 2007
@@ -0,0 +1,246 @@
+/***************************************************************************
+ *
+ * 21.string.cons.mt.cpp:
+ *
+ * Test exercising the thread safety of basic_string constructors
+ * and assignment operators.
+ *
+ * $Id: 21.string.push_back.mt.cpp 425530 2006-07-25 21:39:50Z sebor $
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software  Foundation (ASF) under one or more
+ * contributor  license agreements.  See  the NOTICE  file distributed
+ * with  this  work  for  additional information  regarding  copyright
+ * ownership.   The ASF  licenses this  file to  you under  the Apache
+ * License, Version  2.0 (the  "License"); you may  not use  this file
+ * except in  compliance with the License.   You may obtain  a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the  License is distributed on an  "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
+ * implied.   See  the License  for  the  specific language  governing
+ * permissions and limitations under the License.
+ *
+ **************************************************************************/
+
+#include <string>       // for string
+
+#include <cstddef>      // for size_t
+
+#include <driver.h>     // for rw_test()
+#include <rw_thread.h>  // for rw_thread_pool(), ...
+#include <valcmp.h>     // for rw_strncmp()
+
+/**************************************************************************/
+
+#define MAX_THREADS      32
+#define MAX_LOOPS    100000
+
+const char* const
+data [] = {
+    /*  0 */ "",
+    /*  1 */ "a",
+    /*  2 */ "bc",
+    /*  3 */ "cde",
+    /*  4 */ "defg",
+    /*  5 */ "efghi",
+    /*  6 */ "fghijk",
+    /*  7 */ "ghijklm"
+};
+
+const std::size_t
+nstrings = sizeof data / sizeof *data;
+
+const std::string
+shared [nstrings] = {
+    data [0], data [1], data [2], data [3],
+    data [4], data [5], data [6], data [7]
+};
+
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+const wchar_t* const
+wdata [] = {
+    /*  0 */ L"",
+    /*  1 */ L"a",
+    /*  2 */ L"bc",
+    /*  3 */ L"cde",
+    /*  4 */ L"defg",
+    /*  5 */ L"efghi",
+    /*  6 */ L"fghijk",
+    /*  7 */ L"ghijklm"
+};
+
+const std::wstring
+wshared [nstrings] = {
+    wdata [0], wdata [1], wdata [2], wdata [3],
+    wdata [4], wdata [5], wdata [6], wdata [7]
+};
+
+#endif   // _RWSTD_NO_WCHAR_T
+
+/**************************************************************************/
+
+int rw_opt_nthreads = 4;
+int rw_opt_nloops   = MAX_LOOPS;
+
+
+template <class T>
+void
+test_string_cons (const T* const             *pdata,
+                  const std::basic_string<T> *pshared,
+                  std::size_t                 threadno)
+{
+    typedef std::basic_string<T> String;
+
+    for (std::size_t i = 0; i != std::size_t (rw_opt_nloops); ++i) {
+
+        const std::size_t inx1 = (i + threadno) % nstrings;
+        const std::size_t inx2 = (inx1 + 1) % nstrings;
+
+        // create a copy of the global string
+        const String copy (pshared [inx1]);
+
+        String assigned (pshared [inx2]);
+
+        {
+            // create another copy of the same global string
+            const String copy2 (pshared [inx1]);
+
+            // verify that this copy has the expected length...
+            RW_ASSERT (pshared [inx1].length () == copy2.length ());
+
+            // ...and the expected data
+            RW_ASSERT (0 == rw_strncmp (pdata [inx1], copy2.data ()));
+
+            assigned = pshared [inx1];
+
+            // copy2 gets destroyed...
+        }
+
+        // verify that local copy has the expected length...
+        RW_ASSERT (pshared [inx1].length () == copy.length ());
+
+        // ...and the expected data
+        RW_ASSERT (0 == rw_strncmp (pdata [inx1], copy.data ()));
+
+        // verify that assigned string has the expected length...
+        RW_ASSERT (pshared [inx1].length () == assigned.length ());
+
+        // ...and the expected data
+        RW_ASSERT (0 == rw_strncmp (pdata [inx1], assigned.data ()));
+
+        // reassign and verify again
+        assigned = pdata [inx2];
+
+        RW_ASSERT (pshared [inx2].length () == assigned.length ());
+        RW_ASSERT (0 == rw_strncmp (pdata [inx2], assigned.data ()));
+    }
+
+}
+
+
+extern "C" {
+
+bool test_wstring;
+
+static void*
+thread_func (void *arg)
+{
+    const rw_thread_t* const pthread = (rw_thread_t*)arg;
+
+    // get the 0-based thread number
+    const std::size_t threadno = std::size_t (pthread->threadno);
+
+    if (test_wstring) {
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+        test_string_cons<wchar_t>(wdata, wshared, threadno);
+
+#endif   // _RWSTD_NO_WCHAR_T
+
+    }
+    else {
+        test_string_cons (data, shared, threadno);
+    }
+
+    return 0;
+}
+
+}   // extern "C"
+
+/**************************************************************************/
+
+static int
+run_test (int, char**)
+{
+    rw_info (0, 0, 0,
+             "testing std::string with %d thread%{?}s%{;}, "
+             "%zu iteration%{?}s%{;} each",
+             rw_opt_nthreads, 1 != rw_opt_nthreads,
+             rw_opt_nloops, 1 != rw_opt_nloops);
+
+    test_wstring = false;
+
+    // create and start a pool of threads and wait for them to finish
+    int result =
+        rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0);
+
+    for (std::size_t i = 0; i != nstrings; ++i) {
+
+        const std::size_t size =
+            std::string::traits_type::length (data [i]);
+
+        rw_assert (size == shared [i].size (), 0, 0,
+                   "shared string modifed from #s to %{#S}",
+                   data [i], &shared [i]);
+    }
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+    rw_info (0, 0, 0,
+             "testing std::wstring with %d thread%{?}s%{;}, "
+             "%zu iteration%{?}s%{;} each",
+             rw_opt_nthreads, 1 != rw_opt_nthreads,
+             rw_opt_nloops, 1 != rw_opt_nloops);
+
+    test_wstring = true;
+
+    // start a pool of threads to exercise wstring thread safety
+    result +=
+        rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0);
+
+    for (std::size_t i = 0; i != nstrings; ++i) {
+
+        const std::size_t size =
+            std::wstring::traits_type::length (wdata [i]);
+
+        rw_assert (size == wshared [i].size (), 0, 0,
+                   "shared string modifed from #ls to %{#lS}",
+                   wdata [i], &wshared [i]);
+    }
+
+#endif   // _RWSTD_NO_WCHAR_T
+
+    return result;
+}
+
+/**************************************************************************/
+
+int main (int argc, char *argv[])
+{
+    return rw_test (argc, argv, __FILE__,
+                    "lib.string.cons",
+                    "thread safety", run_test,
+                    "|-nloops#0 "       // must be non-negative
+                    "|-nthreads#0-*",   // must be in [0, MAX_THREADS]
+                    &rw_opt_nloops,
+                    int (MAX_THREADS),
+                    &rw_opt_nthreads);
+}