1 /*
2  * Copyright (C) 2019 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 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
18 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
19 
20 #include <functional>
21 #include <thread>
22 
23 #include "perfetto/ext/base/unix_task_runner.h"
24 
25 namespace perfetto {
26 namespace base {
27 
28 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
29 // joins the thread upon destruction. Can be moved to transfer ownership.
30 //
31 // Guarantees that:
32 // * the UnixTaskRunner will be constructed and destructed on the task thread.
33 // * the task thread will live for the lifetime of the UnixTaskRunner.
34 //
35 class ThreadTaskRunner {
36  public:
37   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
38     return ThreadTaskRunner(name);
39   }
40 
41   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
42   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
43 
44   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
45   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
46   ~ThreadTaskRunner();
47 
48   // Executes the given function on the task runner thread and blocks the caller
49   // thread until the function has run.
50   void PostTaskAndWaitForTesting(std::function<void()>);
51 
52   // Can be called from another thread to get the CPU time of the thread the
53   // task-runner is executing on.
54   uint64_t GetThreadCPUTimeNsForTesting();
55 
56   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
57   // this ThreadTaskRunner object (unless this object is moved-from, in which
58   // case the pointer remains valid for the lifetime of the new owning
59   // ThreadTaskRunner).
60   //
61   // Warning: do not call Quit() on the returned runner pointer, the termination
62   // should be handled exclusively by this class' destructor.
get()63   UnixTaskRunner* get() const { return task_runner_; }
64 
65  private:
66   explicit ThreadTaskRunner(const std::string& name);
67   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
68 
69   std::thread thread_;
70   std::string name_;
71   UnixTaskRunner* task_runner_ = nullptr;
72 };
73 
74 }  // namespace base
75 }  // namespace perfetto
76 
77 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
78