1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include "Action.h" 20 #include "Pointers.h" 21 #include "Thread.h" 22 #include "Threads.h" 23 24 TEST(ThreadsTest, single_thread) { 25 Pointers pointers(2); 26 27 Threads threads(&pointers, 1); 28 Thread* thread = threads.CreateThread(900); 29 ASSERT_TRUE(thread != nullptr); 30 ASSERT_EQ(1U, threads.num_threads()); 31 32 Thread* found_thread = threads.FindThread(900); 33 ASSERT_EQ(thread, found_thread); 34 35 thread->CreateAction(0x1234, "thread_done", ""); 36 37 thread->SetPending(); 38 39 threads.Finish(thread); 40 41 ASSERT_EQ(0U, threads.num_threads()); 42 } 43 44 TEST(ThreadsTest, multiple_threads) { 45 Pointers pointers(4); 46 47 Threads threads(&pointers, 1); 48 Thread* thread1 = threads.CreateThread(900); 49 ASSERT_TRUE(thread1 != nullptr); 50 ASSERT_EQ(1U, threads.num_threads()); 51 52 Thread* thread2 = threads.CreateThread(901); 53 ASSERT_TRUE(thread2 != nullptr); 54 ASSERT_EQ(2U, threads.num_threads()); 55 56 Thread* thread3 = threads.CreateThread(902); 57 ASSERT_TRUE(thread3 != nullptr); 58 ASSERT_EQ(3U, threads.num_threads()); 59 60 Thread* found_thread1 = threads.FindThread(900); 61 ASSERT_EQ(thread1, found_thread1); 62 63 Thread* found_thread2 = threads.FindThread(901); 64 ASSERT_EQ(thread2, found_thread2); 65 66 Thread* found_thread3 = threads.FindThread(902); 67 ASSERT_EQ(thread3, found_thread3); 68 69 thread1->CreateAction(0x1234, "thread_done", ""); 70 thread2->CreateAction(0x1235, "thread_done", ""); 71 thread3->CreateAction(0x1236, "thread_done", ""); 72 73 thread1->SetPending(); 74 threads.Finish(thread1); 75 ASSERT_EQ(2U, threads.num_threads()); 76 77 thread3->SetPending(); 78 threads.Finish(thread3); 79 ASSERT_EQ(1U, threads.num_threads()); 80 81 thread2->SetPending(); 82 threads.Finish(thread2); 83 ASSERT_EQ(0U, threads.num_threads()); 84 } 85 86 TEST(ThreadsTest, verify_quiesce) { 87 Pointers pointers(4); 88 89 Threads threads(&pointers, 1); 90 Thread* thread = threads.CreateThread(900); 91 ASSERT_TRUE(thread != nullptr); 92 ASSERT_EQ(1U, threads.num_threads()); 93 94 // If WaitForAllToQuiesce is not correct, then this should provoke an error 95 // since we are overwriting the action data while it's being used. 96 for (size_t i = 0; i < 512; i++) { 97 thread->CreateAction(0x1234 + i, "malloc", "100"); 98 thread->SetPending(); 99 threads.WaitForAllToQuiesce(); 100 101 thread->CreateAction(0x1234 + i, "free", ""); 102 thread->SetPending(); 103 threads.WaitForAllToQuiesce(); 104 } 105 106 thread->CreateAction(0x1236, "thread_done", ""); 107 thread->SetPending(); 108 threads.Finish(thread); 109 ASSERT_EQ(0U, threads.num_threads()); 110 } 111 112 static void TestTooManyThreads() { 113 Pointers pointers(4); 114 115 Threads threads(&pointers, 1); 116 for (size_t i = 0; i <= threads.max_threads(); i++) { 117 Thread* thread = threads.CreateThread(900+i); 118 ASSERT_EQ(thread, threads.FindThread(900+i)); 119 } 120 } 121 122 TEST(ThreadsTest, too_many_threads) { 123 ASSERT_EXIT(TestTooManyThreads(), ::testing::ExitedWithCode(1), ""); 124 } 125