Apollo 10.0
自动驾驶开放平台
croutine.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
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 CYBER_CROUTINE_CROUTINE_H_
18#define CYBER_CROUTINE_CROUTINE_H_
19
20#include <atomic>
21#include <chrono>
22#include <functional>
23#include <memory>
24#include <mutex>
25#include <set>
26#include <string>
27
28#include "cyber/common/log.h"
30
31namespace apollo {
32namespace cyber {
33namespace croutine {
34
35using RoutineFunc = std::function<void()>;
36using Duration = std::chrono::microseconds;
37
39
40class CRoutine {
41 public:
42 explicit CRoutine(const RoutineFunc &func);
43 virtual ~CRoutine();
44
45 // static interfaces
46 static void Yield();
47 static void Yield(const RoutineState &state);
48 static void SetMainContext(const std::shared_ptr<RoutineContext> &context);
50 static char **GetMainStack();
51
52 // public interfaces
53 bool Acquire();
54 void Release();
55
56 // It is caller's responsibility to check if state_ is valid before calling
57 // SetUpdateFlag().
58 void SetUpdateFlag();
59
60 // acquire && release should be called before Resume
61 // when work-steal like mechanism used
65 char **GetStack();
66
67 void Run();
68 void Stop();
69 void Wake();
70 void HangUp();
71 void Sleep(const Duration &sleep_duration);
72
73 // getter and setter
74 RoutineState state() const;
75 void set_state(const RoutineState &state);
76
77 uint64_t id() const;
78 void set_id(uint64_t id);
79
80 const std::string &name() const;
81 void set_name(const std::string &name);
82
83 int processor_id() const;
85
86 uint32_t priority() const;
87 void set_priority(uint32_t priority);
88
89 std::chrono::steady_clock::time_point wake_time() const;
90
91 void set_group_name(const std::string &group_name) {
92 group_name_ = group_name;
93 }
94
95 const std::string &group_name() { return group_name_; }
96
97 private:
98 CRoutine(CRoutine &) = delete;
99 CRoutine &operator=(CRoutine &) = delete;
100
101 std::string name_;
102 std::chrono::steady_clock::time_point wake_time_ =
103 std::chrono::steady_clock::now();
104
105 RoutineFunc func_;
106 RoutineState state_;
107
108 std::shared_ptr<RoutineContext> context_;
109
110 std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
111 std::atomic_flag updated_ = ATOMIC_FLAG_INIT;
112
113 bool force_stop_ = false;
114
115 int processor_id_ = -1;
116 uint32_t priority_ = 0;
117 uint64_t id_ = 0;
118
119 std::string group_name_;
120
121 static thread_local CRoutine *current_routine_;
122 static thread_local char *main_stack_;
123};
124
125inline void CRoutine::Yield(const RoutineState &state) {
126 auto routine = GetCurrentRoutine();
127 routine->set_state(state);
129}
130
134
135inline CRoutine *CRoutine::GetCurrentRoutine() { return current_routine_; }
136
137inline char **CRoutine::GetMainStack() { return &main_stack_; }
138
139inline RoutineContext *CRoutine::GetContext() { return context_.get(); }
140
141inline char **CRoutine::GetStack() { return &(context_->sp); }
142
143inline void CRoutine::Run() { func_(); }
144
145inline void CRoutine::set_state(const RoutineState &state) { state_ = state; }
146
147inline RoutineState CRoutine::state() const { return state_; }
148
149inline std::chrono::steady_clock::time_point CRoutine::wake_time() const {
150 return wake_time_;
151}
152
153inline void CRoutine::Wake() { state_ = RoutineState::READY; }
154
156
157inline void CRoutine::Sleep(const Duration &sleep_duration) {
158 wake_time_ = std::chrono::steady_clock::now() + sleep_duration;
160}
161
162inline uint64_t CRoutine::id() const { return id_; }
163
164inline void CRoutine::set_id(uint64_t id) { id_ = id; }
165
166inline const std::string &CRoutine::name() const { return name_; }
167
168inline void CRoutine::set_name(const std::string &name) { name_ = name; }
169
170inline int CRoutine::processor_id() const { return processor_id_; }
171
172inline void CRoutine::set_processor_id(int processor_id) {
173 processor_id_ = processor_id;
174}
175
177 // Synchronous Event Mechanism
178 if (state_ == RoutineState::SLEEP &&
179 std::chrono::steady_clock::now() > wake_time_) {
180 state_ = RoutineState::READY;
181 return state_;
182 }
183
184 // Asynchronous Event Mechanism
185 if (!updated_.test_and_set(std::memory_order_release)) {
186 if (state_ == RoutineState::DATA_WAIT || state_ == RoutineState::IO_WAIT) {
187 state_ = RoutineState::READY;
188 }
189 }
190 return state_;
191}
192
193inline uint32_t CRoutine::priority() const { return priority_; }
194
195inline void CRoutine::set_priority(uint32_t priority) { priority_ = priority; }
196
197inline bool CRoutine::Acquire() {
198 return !lock_.test_and_set(std::memory_order_acquire);
199}
200
201inline void CRoutine::Release() {
202 return lock_.clear(std::memory_order_release);
203}
204
206 updated_.clear(std::memory_order_release);
207}
208
209} // namespace croutine
210} // namespace cyber
211} // namespace apollo
212
213#endif // CYBER_CROUTINE_CROUTINE_H_
void set_priority(uint32_t priority)
Definition croutine.h:195
void set_group_name(const std::string &group_name)
Definition croutine.h:91
void set_state(const RoutineState &state)
Definition croutine.h:145
static CRoutine * GetCurrentRoutine()
Definition croutine.h:135
void Sleep(const Duration &sleep_duration)
Definition croutine.h:157
void set_processor_id(int processor_id)
Definition croutine.h:172
const std::string & group_name()
Definition croutine.h:95
RoutineState state() const
Definition croutine.h:147
void set_name(const std::string &name)
Definition croutine.h:168
std::chrono::steady_clock::time_point wake_time() const
Definition croutine.h:149
RoutineContext * GetContext()
Definition croutine.h:139
const std::string & name() const
Definition croutine.h:166
static void SetMainContext(const std::shared_ptr< RoutineContext > &context)
std::function< void()> RoutineFunc
Definition croutine.h:35
void SwapContext(char **src_sp, char **dest_sp)
std::chrono::microseconds Duration
Definition croutine.h:36
class register implement
Definition arena_queue.h:37