1 /* 2 * Copyright 2023 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 #pragma once 18 19 #include <pthread.h> 20 #include <stdlib.h> 21 #include <unistd.h> 22 23 #include <condition_variable> 24 #include <cstdint> 25 #include <mutex> 26 #include <queue> 27 #include <string> 28 29 #include "osi/include/thread.h" 30 31 using thread_func = std::function<void(void* context)>; 32 using thread_data = void*; 33 using work_item = std::pair<thread_func, thread_data>; 34 35 class semaphore_t { 36 std::condition_variable condition_; 37 unsigned long count_ = 0; // Initialized as locked. 38 39 public: 40 std::mutex mutex_; notify()41 void notify() { 42 std::lock_guard<decltype(mutex_)> lock(mutex_); 43 ++count_; 44 condition_.notify_one(); 45 } 46 wait()47 void wait() { 48 std::unique_lock<decltype(mutex_)> lock(mutex_); 49 while (!count_) // Handle spurious wake-ups. 50 condition_.wait(lock); 51 --count_; 52 } 53 try_wait()54 bool try_wait() { 55 std::lock_guard<decltype(mutex_)> lock(mutex_); 56 if (count_) { 57 --count_; 58 return true; 59 } 60 return false; 61 } 62 }; 63 64 struct thread_start_arg_t { 65 thread_t* thread; 66 int thread_id; 67 semaphore_t start_sem; 68 }; 69 70 struct thread_t { 71 enum class State { 72 STOPPED, 73 RUNNING, 74 QUIESCE, 75 }; 76 77 private: 78 State is_running_{State::STOPPED}; 79 mutable std::mutex is_running_lock_; 80 semaphore_t thread_finish_semaphore; 81 82 public: 83 std::queue<work_item> work_queue; 84 semaphore_t work_queue_semaphore; 85 86 bool is_running() const; 87 void set_state(State state); 88 void quiesce(); 89 void notify_finished(); 90 91 pthread_t pthread_; 92 pid_t tid_; 93 std::string name_; 94 }; 95