15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Trivial tests that thread runs and doesn't crash on create and join ---------
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TrivialThread : public PlatformThread::Delegate {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrivialThread() : did_run_(false) {}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ThreadMain() OVERRIDE {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_run_ = true;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_run() const { return did_run_; }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_run_;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TrivialThread);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformThreadTest, Trivial) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrivialThread thread;
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PlatformThreadHandle handle;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(thread.did_run());
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThread::Join(handle);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(thread.did_run());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformThreadTest, TrivialTimesTen) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrivialThread thread[10];
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadHandle handle[arraysize(thread)];
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(thread[n].did_run());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(PlatformThread::Create(0, &thread[n], &handle[n]));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformThread::Join(handle[n]);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(thread[n].did_run());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests of basic thread functions ---------------------------------------------
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FunctionTestThread : public TrivialThread {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FunctionTestThread() : thread_id_(0) {}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ThreadMain() OVERRIDE {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thread_id_ = PlatformThread::CurrentId();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformThread::YieldCurrentThread();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that the thread ID is the same across calls.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(thread_id_, PlatformThread::CurrentId());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TrivialThread::ThreadMain();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadId thread_id() const { return thread_id_; }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadId thread_id_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FunctionTestThread);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformThreadTest, Function) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadId main_thread_id = PlatformThread::CurrentId();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FunctionTestThread thread;
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PlatformThreadHandle handle;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(thread.did_run());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThread::Join(handle);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(thread.did_run());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(thread.thread_id(), main_thread_id);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the thread ID is the same across calls.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(main_thread_id, PlatformThread::CurrentId());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformThreadTest, FunctionTimesTen) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadId main_thread_id = PlatformThread::CurrentId();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FunctionTestThread thread[10];
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformThreadHandle handle[arraysize(thread)];
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(thread[n].did_run());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(PlatformThread::Create(0, &thread[n], &handle[n]));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformThread::Join(handle[n]);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t n = 0; n < arraysize(thread); n++) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(thread[n].did_run());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(thread[n].thread_id(), main_thread_id);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure no two threads get the same ID.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < n; ++i) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_NE(thread[i].thread_id(), thread[n].thread_id());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the thread ID is the same across calls.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(main_thread_id, PlatformThread::CurrentId());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
122