133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris/* 233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * Copyright (C) 2015 The Android Open Source Project 333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * 433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * you may not use this file except in compliance with the License. 633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * You may obtain a copy of the License at 733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * 833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * 1033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * See the License for the specific language governing permissions and 1433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris * limitations under the License. 1533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris */ 1633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 1733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris#include <gtest/gtest.h> 1833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 1933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris#include "Action.h" 2033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris#include "Pointers.h" 2133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris#include "Thread.h" 2233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris#include "Threads.h" 2333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 2433c03d38298ff359d8829aea91bb02b26caab245Christopher FerrisTEST(ThreadsTest, single_thread) { 2533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Pointers pointers(2); 2633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 2733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Threads threads(&pointers, 1); 2833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread = threads.CreateThread(900); 2933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_TRUE(thread != nullptr); 3033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(1U, threads.num_threads()); 3133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 3233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* found_thread = threads.FindThread(900); 3333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(thread, found_thread); 3433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 3533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->CreateAction(0x1234, "thread_done", ""); 3633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 3733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->SetPending(); 3833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 3933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.Finish(thread); 4033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 4133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(0U, threads.num_threads()); 4233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris} 4333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 4433c03d38298ff359d8829aea91bb02b26caab245Christopher FerrisTEST(ThreadsTest, multiple_threads) { 4533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Pointers pointers(4); 4633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 4733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Threads threads(&pointers, 1); 4833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread1 = threads.CreateThread(900); 4933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_TRUE(thread1 != nullptr); 5033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(1U, threads.num_threads()); 5133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 5233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread2 = threads.CreateThread(901); 5333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_TRUE(thread2 != nullptr); 5433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(2U, threads.num_threads()); 5533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 5633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread3 = threads.CreateThread(902); 5733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_TRUE(thread3 != nullptr); 5833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(3U, threads.num_threads()); 5933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 6033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* found_thread1 = threads.FindThread(900); 6133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(thread1, found_thread1); 6233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 6333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* found_thread2 = threads.FindThread(901); 6433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(thread2, found_thread2); 6533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 6633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* found_thread3 = threads.FindThread(902); 6733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(thread3, found_thread3); 6833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 6933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread1->CreateAction(0x1234, "thread_done", ""); 7033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread2->CreateAction(0x1235, "thread_done", ""); 7133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread3->CreateAction(0x1236, "thread_done", ""); 7233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 7333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread1->SetPending(); 7433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.Finish(thread1); 7533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(2U, threads.num_threads()); 7633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 7733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread3->SetPending(); 7833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.Finish(thread3); 7933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(1U, threads.num_threads()); 8033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 8133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread2->SetPending(); 8233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.Finish(thread2); 8333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(0U, threads.num_threads()); 8433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris} 8533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 8633c03d38298ff359d8829aea91bb02b26caab245Christopher FerrisTEST(ThreadsTest, verify_quiesce) { 8733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Pointers pointers(4); 8833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 8933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Threads threads(&pointers, 1); 9033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread = threads.CreateThread(900); 9133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_TRUE(thread != nullptr); 9233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(1U, threads.num_threads()); 9333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 9433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris // If WaitForAllToQuiesce is not correct, then this should provoke an error 9533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris // since we are overwriting the action data while it's being used. 9633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris for (size_t i = 0; i < 512; i++) { 9733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->CreateAction(0x1234 + i, "malloc", "100"); 9833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->SetPending(); 9933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.WaitForAllToQuiesce(); 10033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 10133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->CreateAction(0x1234 + i, "free", ""); 10233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->SetPending(); 10333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.WaitForAllToQuiesce(); 10433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris } 10533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 10633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->CreateAction(0x1236, "thread_done", ""); 10733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris thread->SetPending(); 10833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris threads.Finish(thread); 10933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(0U, threads.num_threads()); 11033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris} 11133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 11233c03d38298ff359d8829aea91bb02b26caab245Christopher Ferrisstatic void TestTooManyThreads() { 11333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Pointers pointers(4); 11433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 11533c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Threads threads(&pointers, 1); 11633c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris for (size_t i = 0; i <= threads.max_threads(); i++) { 11733c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris Thread* thread = threads.CreateThread(900+i); 11833c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EQ(thread, threads.FindThread(900+i)); 11933c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris } 12033c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris} 12133c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris 12233c03d38298ff359d8829aea91bb02b26caab245Christopher FerrisTEST(ThreadsTest, too_many_threads) { 12333c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris ASSERT_EXIT(TestTooManyThreads(), ::testing::ExitedWithCode(1), ""); 12433c03d38298ff359d8829aea91bb02b26caab245Christopher Ferris} 125