| 165 | } |
| 166 | |
| 167 | void StartThreads(size_t thread_count, size_t stack_size = 0) { |
| 168 | for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) { |
| 169 | const std::string thread_name = |
| 170 | base::StringPrintf("ThreadPool-%zu", thread_index); |
| 171 | threads_.push_back(std::make_unique<Thread>(thread_name)); |
| 172 | Thread* thread = threads_.back().get(); |
| 173 | |
| 174 | pthread_attr_t attr; |
| 175 | ASSERT_EQ(pthread_attr_init(&attr), 0) |
| 176 | << ErrnoMessage("pthread_attr_init"); |
| 177 | |
| 178 | if (stack_size > 0) { |
| 179 | const size_t page_size = getpagesize(); |
| 180 | DCHECK_EQ(stack_size % page_size, 0u); |
| 181 | size_t stack_alloc_size = 2 * page_size + stack_size; |
| 182 | |
| 183 | ASSERT_TRUE(thread->stack.ResetMmap(nullptr, |
| 184 | stack_alloc_size, |
| 185 | PROT_NONE, |
| 186 | MAP_PRIVATE | MAP_ANONYMOUS, |
| 187 | -1, |
| 188 | 0)); |
| 189 | char* stack_ptr = thread->stack.addr_as<char*>() + page_size; |
| 190 | ASSERT_EQ(mprotect(stack_ptr, stack_size, PROT_READ | PROT_WRITE), 0) |
| 191 | << "mprotect"; |
| 192 | |
| 193 | ASSERT_EQ(pthread_attr_setstack(&attr, stack_ptr, stack_size), 0) |
| 194 | << ErrnoMessage("pthread_attr_setstack"); |
| 195 | thread->expectation.max_stack_size = stack_size; |
| 196 | } |
| 197 | |
| 198 | ASSERT_EQ(pthread_attr_setschedpolicy(&attr, SCHED_OTHER), 0) |
| 199 | << ErrnoMessage("pthread_attr_setschedpolicy"); |
| 200 | thread->expectation.sched_policy = SCHED_OTHER; |
| 201 | |
| 202 | sched_param param; |
| 203 | param.sched_priority = 0; |
| 204 | ASSERT_EQ(pthread_attr_setschedparam(&attr, ¶m), 0) |
| 205 | << ErrnoMessage("pthread_attr_setschedparam"); |
| 206 | thread->expectation.static_priority = 0; |
| 207 | |
| 208 | thread->expectation.nice_value = thread_index % 20; |
| 209 | |
| 210 | ASSERT_EQ(pthread_create(&thread->pthread, &attr, ThreadMain, thread), 0) |
| 211 | << ErrnoMessage("pthread_create"); |
| 212 | } |
| 213 | |
| 214 | for (const auto& thread : threads_) { |
| 215 | thread->ready_semaphore.Wait(); |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | pid_t GetThreadExpectation(size_t thread_index, |
| 220 | ThreadExpectation* expectation, |
no test coverage detected