-//-----------------------------------------------------------------------
-//
-// TestMutex - a simple (non-stress) test to verify that ICU mutexes
-// and condition variables are functioning. Does not test the use of
-// mutexes within ICU services, but rather that the
-// platform's mutex support is at least superficially there.
-//
-//----------------------------------------------------------------------
-static UMutex gTestMutexA = U_MUTEX_INITIALIZER;
-static UConditionVar gThreadsCountChanged = U_CONDITION_INITIALIZER;
-
-static int gThreadsStarted = 0;
-static int gThreadsInMiddle = 0;
-static int gThreadsDone = 0;
-
-static const int TESTMUTEX_THREAD_COUNT = 40;
-
-class TestMutexThread : public SimpleThread
-{
-public:
- virtual void run() {
- // This is the code that each of the spawned threads runs.
- // All threads move together throught the started - middle - done sequence together,
- // waiting for all other threads to reach each point before advancing.
- umtx_lock(&gTestMutexA);
- gThreadsStarted += 1;
- umtx_condBroadcast(&gThreadsCountChanged);
- while (gThreadsStarted < TESTMUTEX_THREAD_COUNT) {
- if (gThreadsInMiddle != 0) {
- IntlTest::gTest->errln(
- "%s:%d gThreadsInMiddle = %d. Expected 0.", __FILE__, __LINE__, gThreadsInMiddle);
- return;
- }
- umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
- }
-
- gThreadsInMiddle += 1;
- umtx_condBroadcast(&gThreadsCountChanged);
- while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
- if (gThreadsDone != 0) {
- IntlTest::gTest->errln(
- "%s:%d gThreadsDone = %d. Expected 0.", __FILE__, __LINE__, gThreadsDone);
- return;
- }
- umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
- }
-
- gThreadsDone += 1;
- umtx_condBroadcast(&gThreadsCountChanged);
- while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
- umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
- }
- umtx_unlock(&gTestMutexA);
- }
-};
-
-void MultithreadTest::TestMutex()
-{
- gThreadsStarted = 0;
- gThreadsInMiddle = 0;
- gThreadsDone = 0;
- int32_t i = 0;
- TestMutexThread threads[TESTMUTEX_THREAD_COUNT];
- umtx_lock(&gTestMutexA);
- for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
- if (threads[i].start() != 0) {
- errln("%s:%d Error starting thread %d", __FILE__, __LINE__, i);
- return;
- }
- }
-
- // Because we are holding gTestMutexA, all of the threads should be blocked
- // at the start of their run() function.
- if (gThreadsStarted != 0) {
- errln("%s:%d gThreadsStarted=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
- return;
- }
-
- while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
- if (gThreadsDone != 0) {
- errln("%s:%d gThreadsDone=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
- return;
- }
- umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
- }
-
- while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
- umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
- }
- umtx_unlock(&gTestMutexA);
-
- for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
- threads[i].join();
- }
-}
-
-