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 "Alloc.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 AllocEntry thread_done = {.type = THREAD_DONE}; 36 thread->SetAllocEntry(&thread_done); 37 38 thread->SetPending(); 39 40 threads.Finish(thread); 41 42 ASSERT_EQ(0U, threads.num_threads()); 43 } 44 45 TEST(ThreadsTest, multiple_threads) { 46 Pointers pointers(4); 47 48 Threads threads(&pointers, 1); 49 Thread* thread1 = threads.CreateThread(900); 50 ASSERT_TRUE(thread1 != nullptr); 51 ASSERT_EQ(1U, threads.num_threads()); 52 53 Thread* thread2 = threads.CreateThread(901); 54 ASSERT_TRUE(thread2 != nullptr); 55 ASSERT_EQ(2U, threads.num_threads()); 56 57 Thread* thread3 = threads.CreateThread(902); 58 ASSERT_TRUE(thread3 != nullptr); 59 ASSERT_EQ(3U, threads.num_threads()); 60 61 Thread* found_thread1 = threads.FindThread(900); 62 ASSERT_EQ(thread1, found_thread1); 63 64 Thread* found_thread2 = threads.FindThread(901); 65 ASSERT_EQ(thread2, found_thread2); 66 67 Thread* found_thread3 = threads.FindThread(902); 68 ASSERT_EQ(thread3, found_thread3); 69 70 AllocEntry thread_done = {.type = THREAD_DONE}; 71 thread1->SetAllocEntry(&thread_done); 72 thread2->SetAllocEntry(&thread_done); 73 thread3->SetAllocEntry(&thread_done); 74 75 thread1->SetPending(); 76 threads.Finish(thread1); 77 ASSERT_EQ(2U, threads.num_threads()); 78 79 thread3->SetPending(); 80 threads.Finish(thread3); 81 ASSERT_EQ(1U, threads.num_threads()); 82 83 thread2->SetPending(); 84 threads.Finish(thread2); 85 ASSERT_EQ(0U, threads.num_threads()); 86 } 87 88 TEST(ThreadsTest, verify_quiesce) { 89 Pointers pointers(4); 90 91 Threads threads(&pointers, 1); 92 Thread* thread = threads.CreateThread(900); 93 ASSERT_TRUE(thread != nullptr); 94 ASSERT_EQ(1U, threads.num_threads()); 95 96 // If WaitForAllToQuiesce is not correct, then this should provoke an error 97 // since we are overwriting the action data while it's being used. 98 constexpr size_t kAllocEntries = 512; 99 std::vector<AllocEntry> mallocs(kAllocEntries); 100 std::vector<AllocEntry> frees(kAllocEntries); 101 for (size_t i = 0; i < kAllocEntries; i++) { 102 mallocs[i].type = MALLOC; 103 mallocs[i].ptr = 0x1234 + i; 104 mallocs[i].size = 100; 105 thread->SetAllocEntry(&mallocs[i]); 106 thread->SetPending(); 107 threads.WaitForAllToQuiesce(); 108 109 frees[i].type = FREE; 110 frees[i].ptr = 0x1234 + i; 111 thread->SetAllocEntry(&frees[i]); 112 thread->SetPending(); 113 threads.WaitForAllToQuiesce(); 114 } 115 116 AllocEntry thread_done = {.type = THREAD_DONE}; 117 thread->SetAllocEntry(&thread_done); 118 thread->SetPending(); 119 threads.Finish(thread); 120 ASSERT_EQ(0U, threads.num_threads()); 121 } 122 123 static void TestTooManyThreads() { 124 Pointers pointers(4); 125 126 Threads threads(&pointers, 1); 127 for (size_t i = 0; i <= threads.max_threads(); i++) { 128 Thread* thread = threads.CreateThread(900+i); 129 ASSERT_EQ(thread, threads.FindThread(900+i)); 130 } 131 } 132 133 TEST(ThreadsTest, too_many_threads) { 134 ASSERT_EXIT(TestTooManyThreads(), ::testing::ExitedWithCode(1), ""); 135 } 136