19d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 29d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 39d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// found in the LICENSE file. 49d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 59d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org#include "src/base/platform/condition-variable.h" 69d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 79d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org#include "src/base/platform/platform.h" 89d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org#include "src/base/platform/time.h" 99d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org#include "testing/gtest/include/gtest/gtest.h" 109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgnamespace v8 { 129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgnamespace base { 139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 149d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTEST(ConditionVariable, WaitForAfterNofityOnSameThread) { 159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < 10; ++n) { 169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex mutex; 179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable cv; 189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv.NotifyOne(); 229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n))); 239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv.NotifyAll(); 259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n))); 269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgnamespace { 319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 32ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass ThreadWithMutexAndConditionVariable FINAL : public Thread { 339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org public: 349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ThreadWithMutexAndConditionVariable() 355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : Thread(Options("ThreadWithMutexAndConditionVariable")), 365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org running_(false), 375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org finished_(false) {} 389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org virtual ~ThreadWithMutexAndConditionVariable() {} 399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 40ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Run() OVERRIDE { 419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org running_ = true; 439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_.NotifyOne(); 449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (running_) { 459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_.Wait(&mutex_); 469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org finished_ = true; 489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_.NotifyAll(); 499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org bool running_; 529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org bool finished_; 539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable cv_; 549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex mutex_; 559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}; 569d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 57d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace 589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTEST(ConditionVariable, MultipleThreadsWithSeparateConditionVariables) { 619d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org static const int kThreadCount = 128; 629d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ThreadWithMutexAndConditionVariable threads[kThreadCount]; 639d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 649d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&threads[n].mutex_); 669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].running_); 679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 689d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].Start(); 699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Wait for nth thread to start. 709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (!threads[n].running_) { 719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].cv_.Wait(&threads[n].mutex_); 729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = kThreadCount - 1; n >= 0; --n) { 769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&threads[n].mutex_); 779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].running_); 789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&threads[n].mutex_); 839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].running_); 849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Tell the nth thread to quit. 869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].running_ = false; 879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].cv_.NotifyOne(); 889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = kThreadCount - 1; n >= 0; --n) { 919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Wait for nth thread to quit. 929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&threads[n].mutex_); 939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (!threads[n].finished_) { 949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].cv_.Wait(&threads[n].mutex_); 959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 969d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].running_); 979d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].finished_); 989d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1009d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 1019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].Join(); 1029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&threads[n].mutex_); 1039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].running_); 1049d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].finished_); 1059d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1069d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 1079d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1089d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgnamespace { 1109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 111ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass ThreadWithSharedMutexAndConditionVariable FINAL : public Thread { 1129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org public: 1139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ThreadWithSharedMutexAndConditionVariable() 1145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : Thread(Options("ThreadWithSharedMutexAndConditionVariable")), 1155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org running_(false), 1165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org finished_(false), 1175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org cv_(NULL), 1185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org mutex_(NULL) {} 1199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org virtual ~ThreadWithSharedMutexAndConditionVariable() {} 1209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 121ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Run() OVERRIDE { 1229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(mutex_); 1239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org running_ = true; 1249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_->NotifyAll(); 1259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (running_) { 1269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_->Wait(mutex_); 1279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org finished_ = true; 1299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_->NotifyAll(); 1309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org bool running_; 1339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org bool finished_; 1349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable* cv_; 1359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex* mutex_; 1369d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}; 1379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 138d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace 1399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTEST(ConditionVariable, MultipleThreadsWithSharedSeparateConditionVariables) { 1429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org static const int kThreadCount = 128; 1439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ThreadWithSharedMutexAndConditionVariable threads[kThreadCount]; 1449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable cv; 1459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex mutex; 1469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 1489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].mutex_ = &mutex; 1499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].cv_ = &cv; 1509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Start all threads. 1539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 1549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 1559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 1569d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].running_); 1579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 1589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].Start(); 1599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1619d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1629d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Wait for all threads to start. 1639d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 1649d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 1659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = kThreadCount - 1; n >= 0; --n) { 1669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (!threads[n].running_) { 1679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv.Wait(&mutex); 1689d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Make sure that all threads are running. 1739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 1749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 1759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 1769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].running_); 1779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 1789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Tell all threads to quit. 1829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 1839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 1849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = kThreadCount - 1; n >= 0; --n) { 1859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].running_); 1869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].finished_); 1879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Tell the nth thread to quit. 1889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].running_ = false; 1899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv.NotifyAll(); 1919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 1929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 1939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Wait for all threads to quit. 1949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 1959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 1969d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 1979d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (!threads[n].finished_) { 1989d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv.Wait(&mutex); 1999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2009d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Make sure all threads are finished. 2049d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org { 2059d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(&mutex); 2069d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = kThreadCount - 1; n >= 0; --n) { 2079d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_FALSE(threads[n].running_); 2089d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_TRUE(threads[n].finished_); 2099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Join all threads. 2139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < kThreadCount; ++n) { 2149d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n].Join(); 2159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 2179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgnamespace { 2209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 221ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass LoopIncrementThread FINAL : public Thread { 2229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org public: 2235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org LoopIncrementThread(int rem, int* counter, int limit, int thread_count, 2245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ConditionVariable* cv, Mutex* mutex) 2255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : Thread(Options("LoopIncrementThread")), 2265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org rem_(rem), 2275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org counter_(counter), 2285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org limit_(limit), 2295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org thread_count_(thread_count), 2305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org cv_(cv), 2315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org mutex_(mutex) { 2329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_LT(rem, thread_count); 2339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_EQ(0, limit % thread_count); 2349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 236ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Run() OVERRIDE { 2379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org int last_count = -1; 2389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (true) { 2399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org LockGuard<Mutex> lock_guard(mutex_); 2409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org int count = *counter_; 2419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (count % thread_count_ != rem_ && count < limit_) { 2429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_->Wait(mutex_); 2439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org count = *counter_; 2449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org if (count >= limit_) break; 2469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_EQ(*counter_, count); 2479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org if (last_count != -1) { 2489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_EQ(last_count + (thread_count_ - 1), count); 2499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org count++; 2519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org *counter_ = count; 2529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org last_count = count; 2539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cv_->NotifyAll(); 2549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2569d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org private: 2589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org const int rem_; 2599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org int* counter_; 2609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org const int limit_; 2619d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org const int thread_count_; 2629d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable* cv_; 2639d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex* mutex_; 2649d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}; 2659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 266d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace 2679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2689d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTEST(ConditionVariable, LoopIncrement) { 2709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org static const int kMaxThreadCount = 16; 2719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Mutex mutex; 2729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org ConditionVariable cv; 2739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) { 2749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org int limit = thread_count * 10; 2759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org int counter = 0; 2769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Setup the threads. 278d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org Thread** threads = new Thread* [thread_count]; 2799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < thread_count; ++n) { 280d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org threads[n] = new LoopIncrementThread(n, &counter, limit, thread_count, 281d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org &cv, &mutex); 2829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Start all threads. 2859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = thread_count - 1; n >= 0; --n) { 2869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n]->Start(); 2879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Join and cleanup all threads. 2909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org for (int n = 0; n < thread_count; ++n) { 2919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org threads[n]->Join(); 2929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org delete threads[n]; 2939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org delete[] threads; 2959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2969d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org EXPECT_EQ(limit, counter); 2979d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 2989d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 2999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 3009d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} // namespace base 3019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} // namespace v8 302