]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/tsmthred.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / tsmthred.cpp
index 9fabb4afee720282f0bef6e034261e1402118352..eb7b882f5a0f2bb66de2b9b733d534880a960719 100644 (file)
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
  * COPYRIGHT:
  * Copyright (c) 1999-2015, International Business Machines Corporation and
@@ -43,6 +45,7 @@ MultithreadTest::~MultithreadTest()
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>    // tolower, toupper
+#include <memory>
 
 #include "unicode/putil.h"
 
@@ -60,82 +63,26 @@ void MultithreadTest::runIndexedTest( int32_t index, UBool exec,
                 const char* &name, char* /*par*/ ) {
     if (exec)
         logln("TestSuite MultithreadTest: ");
-    switch (index) {
-    case 0:
-        name = "TestThreads";
-        if (exec)
-            TestThreads();
-        break;
-
-    case 1:
-        name = "TestMutex";
-        if (exec)
-            TestMutex();
-        break;
-
-    case 2:
-        name = "TestThreadedIntl";
+
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(TestThreads);
+    TESTCASE_AUTO(TestMutex);
 #if !UCONFIG_NO_FORMATTING
-        if (exec) {
-            TestThreadedIntl();
-        }
+    TESTCASE_AUTO(TestThreadedIntl);
 #endif
-        break;
-
-    case 3:
-      name = "TestCollators";
 #if !UCONFIG_NO_COLLATION
-      if (exec) {
-            TestCollators();
-      }
+    TESTCASE_AUTO(TestCollators);
 #endif /* #if !UCONFIG_NO_COLLATION */
-      break;
-
-    case 4:
-        name = "TestString";
-        if (exec) {
-            TestString();
-        }
-        break;
-
-    case 5:
-        name = "TestArabicShapingThreads";
-        if (exec) {
-            TestArabicShapingThreads();
-        }
-        break;
-
-    case 6:
-        name = "TestAnyTranslit";
-        if (exec) {
-            TestAnyTranslit();
-        }
-        break;
-
-    case 7:
-        name = "TestConditionVariables";
-        if (exec) {
-            TestConditionVariables();
-        }
-        break;
-    case 8:
-        name = "TestUnifiedCache";
-        if (exec) {
-            TestUnifiedCache();
-        }
-        break;
+    TESTCASE_AUTO(TestString);
+    TESTCASE_AUTO(TestArabicShapingThreads);
+    TESTCASE_AUTO(TestAnyTranslit);
+    TESTCASE_AUTO(TestConditionVariables);
+    TESTCASE_AUTO(TestUnifiedCache);
 #if !UCONFIG_NO_TRANSLITERATION
-    case 9:
-        name = "TestBreakTranslit";
-        if (exec) {
-            TestBreakTranslit();
-        }
-        break;
-#endif
-    default:
-        name = "";
-        break; //needed to end loop
-    }
+    TESTCASE_AUTO(TestBreakTranslit);
+    TESTCASE_AUTO(TestIncDec);
+#endif /* #if !UCONFIG_NO_TRANSLITERATION */
+    TESTCASE_AUTO_END
 }
 
 
@@ -446,7 +393,8 @@ struct FormatThreadTestData
 // "Someone from {2} is receiving a #{0} error - {1}. Their telephone call is costing {3 number,currency}."
 
 static void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale,
-                     UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments.
+                     UErrorCode inStatus0,                       // statusString 1
+                     const Locale &inCountry2, double currency3, // these numbers are the message arguments.
                      UnicodeString &result)
 {
     if(U_FAILURE(realStatus))
@@ -664,13 +612,13 @@ public:
         // Keep this data here to avoid static initialization.
         FormatThreadTestData kNumberFormatTestData[] =
         {
-            FormatThreadTestData((double)5.0, UnicodeString("5", "")),
-                FormatThreadTestData( 6.0, UnicodeString("6", "")),
-                FormatThreadTestData( 20.0, UnicodeString("20", "")),
-                FormatThreadTestData( 8.0, UnicodeString("8", "")),
-                FormatThreadTestData( 8.3, UnicodeString("8.3", "")),
-                FormatThreadTestData( 12345, UnicodeString("12,345", "")),
-                FormatThreadTestData( 81890.23, UnicodeString("81,890.23", "")),
+            FormatThreadTestData((double)5.0, UnicodeString(u"5")),
+                FormatThreadTestData( 6.0, UnicodeString(u"6")),
+                FormatThreadTestData( 20.0, UnicodeString(u"20")),
+                FormatThreadTestData( 8.0, UnicodeString(u"8")),
+                FormatThreadTestData( 8.3, UnicodeString(u"8.3")),
+                FormatThreadTestData( 12345, UnicodeString(u"12,345")),
+                FormatThreadTestData( 81890.23, UnicodeString(u"81,890.23")),
         };
         int32_t kNumberFormatTestDataLength = UPRV_LENGTHOF(kNumberFormatTestData);
 
@@ -1386,7 +1334,7 @@ const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject(
     } else {
         result->addRef();
     }
-    
     // Log that we created an object. The first object was already counted,
     //    don't do it again.
     umtx_lock(&gCTMutex);
@@ -1449,7 +1397,7 @@ void UnifiedCacheThread::exerciseByLocale(const Locale &locale) {
 
 void UnifiedCacheThread::run() {
     // Run the exercise with 2 different locales so that we can exercise
-    // eviction more. If each thread exerices just one locale, then
+    // eviction more. If each thread exercises just one locale, then
     // eviction can't start until the threads end.
     exerciseByLocale(fLoc);
     exerciseByLocale(fLoc2);
@@ -1569,4 +1517,36 @@ void MultithreadTest::TestBreakTranslit() {
     gTranslitExpected = NULL;
 }
 
+
+class TestIncDecThread : public SimpleThread {
+public:
+    TestIncDecThread() { };
+    virtual void run();
+};
+
+static u_atomic_int32_t gIncDecCounter;
+
+void TestIncDecThread::run() {
+    umtx_atomic_inc(&gIncDecCounter);
+    for (int32_t i=0; i<5000000; ++i) {
+        umtx_atomic_inc(&gIncDecCounter);
+        umtx_atomic_dec(&gIncDecCounter);
+    }
+}
+
+void MultithreadTest::TestIncDec()
+{
+    static constexpr int NUM_THREADS = 4;
+    gIncDecCounter = 0;
+    TestIncDecThread threads[NUM_THREADS];
+    for (auto &thread:threads) {
+        thread.start();
+    }
+    for (auto &thread:threads) {
+        thread.join();
+    }
+    assertEquals("TestIncDec", NUM_THREADS, gIncDecCounter);
+}
+
+
 #endif /* !UCONFIG_NO_TRANSLITERATION */