• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef RELIABILITY_XCOLLIE_TIMERRING_H
17 #define RELIABILITY_XCOLLIE_TIMERRING_H
18 
19 #include <time.h>
20 
21 #include <condition_variable>
22 #include <functional>
23 #include <list>
24 #include <mutex>
25 #include <string>
26 #include <vector>
27 
28 #include "thread_ex.h"
29 
30 namespace OHOS {
31 namespace HiviewDFX {
32 struct TimerTask {
33     std::string name;
34     unsigned int timeout;
35     bool loop;
36     std::function<void (struct InputTimerPara*)> func;
37     struct InputTimerPara* inputTimerPara;
38 };
39 
40 struct InputTimerPara {
41     std::string name;
42     unsigned int timeout;
43     unsigned int flag;
44     int tid;
45     time_t startTime;
46     std::function<void (void*)> func;
47     void* arg;
48 };
49 
50 struct TaskNode {
51     int id; // -1 if not alloc
52     unsigned int seq;
53     int pos; // the position of timer ring
54     int round; // timer ring round
55     struct TimerTask timerTask;
56 };
57 
58 static const unsigned int MAX_XCOLLIE_SHIFT = 7;
59 static const unsigned int COOKIE_SHIFT = 8;
60 static const unsigned int MAX_XCOLLIE_NUM = (1 << MAX_XCOLLIE_SHIFT);
61 static const unsigned int TIMER_RING_CHECK_INTERVAL = 1;
62 static const unsigned int MAX_TIMERRING_SIZE = 60;
63 static const unsigned int MAX_DELAY_COUNT = 3;
64 static const unsigned int MILLI_SECONDS = 1000;
65 
66 #define WRAP_SEQ(id) ((id) & ((1 << COOKIE_SHIFT) - 1))
67 #define CALC_RING_POS(timeout) ((ringPos_ + (((timeout) - 1) / TIMER_RING_CHECK_INTERVAL + 1)) % MAX_TIMERRING_SIZE)
68 #define CALC_RING_ROUND(timeout) (((timeout) / TIMER_RING_CHECK_INTERVAL) / MAX_TIMERRING_SIZE)
69 
70 static const std::string XCOLLIE_THREAD_NAME = "XCollieThread";
71 class TimerRing : public Thread {
72 public:
73     TimerRing();
74     ~TimerRing() override;
75     int AddTask(const struct TimerTask &task);
76     struct InputTimerPara* CancelTask(int id);
77     bool UpdateTask(int id, unsigned int timeout);
78     bool ReadyToWork() override;
79     bool Run() override;
GetName()80     std::string GetName() const
81     {
82         return XCOLLIE_THREAD_NAME;
83     };
84     void TryNotify();
85 private:
86     void TryRecycle(std::list<struct TaskNode*> &timeoutNodes);
87     void InitTaskNode(struct TaskNode* taskNode, unsigned int seq);
88     void DoTimeoutTask();
89     void TrySleep();
90 
91     std::vector<struct TaskNode> taskNodes_ = std::vector<struct TaskNode>(MAX_XCOLLIE_NUM);
92     std::list<struct TaskNode*> freeTaskNodes_ = std::list<struct TaskNode*>();
93     std::vector<std::list<struct TaskNode*>> ringTaskNodes_ =
94         std::vector<std::list<struct TaskNode*>>(MAX_TIMERRING_SIZE);
95 
96     mutable std::mutex lock_;
97     std::condition_variable condition_;
98     bool threadInSleep_;
99     time_t lastTimeout_;
100     uint64_t lastDuration_;
101     int ringPos_;
102 };
103 } // end of namespace HiviewDFX
104 } // end of namespace OHOS
105 #endif
106