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 uint64_t 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 } 52 --count_; 53 } 54 try_wait()55 bool try_wait() { 56 std::lock_guard<decltype(mutex_)> lock(mutex_); 57 if (count_) { 58 --count_; 59 return true; 60 } 61 return false; 62 } 63 }; 64 65 struct thread_start_arg_t { 66 thread_t* thread; 67 int thread_id; 68 semaphore_t start_sem; 69 }; 70 71 struct thread_t { 72 enum class State { 73 STOPPED, 74 RUNNING, 75 QUIESCE, 76 }; 77 78 private: 79 State is_running_{State::STOPPED}; 80 mutable std::mutex is_running_lock_; 81 semaphore_t thread_finish_semaphore; 82 83 public: 84 std::queue<work_item> work_queue; 85 semaphore_t work_queue_semaphore; 86 87 bool is_running() const; 88 void set_state(State state); 89 void quiesce(); 90 void notify_finished(); 91 92 pthread_t pthread_; 93 pid_t tid_; 94 std::string name_; 95 }; 96