1 /*
2 * Copyright (C) 2022 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 FILLP_TIMEING_WHEEL_H
17 #define FILLP_TIMEING_WHEEL_H
18
19 #include "hlist.h"
20 #include "opt.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define FILLP_SECOND_IN_US 1000000
27 #define FILLP_MICROSECOND_IN_NS 1000
28
29 #define FILLP_TIMING_WHEEL_SEC_FLAG 0x01
30 #define FILLP_TIMING_WHEEL_MIN_FLAG 0x02
31 #define FILLP_TIMING_WHEEL_HOUR_FLAG 0x04
32
33 #define FILLP_TIMING_WHEEL_SET_SEC(status) ((status) |= FILLP_TIMING_WHEEL_SEC_FLAG)
34 #define FILLP_TIMING_WHEEL_SET_MIN(status) ((status) |= FILLP_TIMING_WHEEL_MIN_FLAG)
35 #define FILLP_TIMING_WHEEL_SET_HOUR(status) ((status) |= FILLP_TIMING_WHEEL_HOUR_FLAG)
36
37 #define FILLP_TIMING_WHEEL_CLEAR_SEC(status) ((status) = (status) & (FILLP_UINT32)(~FILLP_TIMING_WHEEL_SEC_FLAG))
38 #define FILLP_TIMING_WHEEL_CLEAR_MIN(status) ((status) = (status) & (FILLP_UINT32)(~FILLP_TIMING_WHEEL_MIN_FLAG))
39 #define FILLP_TIMING_WHEEL_CLEAR_HOUR(status) ((status) = (status) & (FILLP_UINT32)(~FILLP_TIMING_WHEEL_HOUR_FLAG))
40
41 #define FILLP_TIMING_WHEEL_IS_SEC_CLEAR(status) (!((status)&FILLP_TIMING_WHEEL_SEC_FLAG))
42 #define FILLP_TIMING_WHEEL_IS_MIN_CLEAR(status) (!((status)&FILLP_TIMING_WHEEL_MIN_FLAG))
43 #define FILLP_TIMING_WHEEL_IS_HOUR_CLEAR(status) (!((status)&FILLP_TIMING_WHEEL_HOUR_FLAG))
44
45 #define FILLP_TIMING_WHEEL_IS_CLEAR(status) ((status) == 0)
46
47 struct FillpTimingWheelHand {
48 struct Hlist slotList[FILLP_TIMING_WHEEL_SLOT_NUM];
49 FILLP_LLONG curSlotTime;
50
51 FILLP_INT accuracy;
52 FILLP_INT handLength;
53 FILLP_INT curTick;
54 };
55
56 struct FillpTimingWheel {
57 struct FillpTimingWheelHand secHand;
58 struct FillpTimingWheelHand minHand;
59 struct FillpTimingWheelHand hourHand;
60
61 FILLP_LLONG curTime;
62 /* secHand->cur_tick + minHand->cur_tick * SLOT_NUM + hourHand->cur_tick * SLOT_NUM * SLOT_NUM */
63 FILLP_LLONG tickTime;
64 FILLP_LLONG accuracy;
65 /* Current loop, the cb may calls */
66 struct Hlist curCbList;
67 /* for hour check , then recycle */
68 struct Hlist hourCycleList;
69 /* Is in callback function context */
70 FILLP_UINT8 inCbContext;
71 FILLP_LLONG nextMinimalExpireTime;
72 };
73
74 typedef void (*FillpTimingWheelCb)(void *arg);
75 struct FillpTimingWheelCbNode {
76 void *arg;
77 FillpTimingWheelCb cb;
78 };
79
80 struct FillpTimingWheelTimerNode {
81 struct HlistNode secNode;
82 struct HlistNode minNode;
83 struct HlistNode hourNode;
84 struct HlistNode cycleNode;
85 struct HlistNode cbListNode;
86 struct FillpTimingWheel *wheel;
87
88 FILLP_LLONG expireTime;
89 struct FillpTimingWheelCbNode cbNode;
90 FILLP_UINT32 interval; /* If cyclical */
91 FILLP_UINT32 status;
92 };
93
94 #define FILLP_TIMING_WHEEL_INIT_NODE(node) \
95 do { \
96 (node)->wheel = FILLP_NULL_PTR; \
97 (node)->status = 0; \
98 } while (0)
99
100 #define FILLP_TIMING_WHEEL_IS_NODE_ENABLED(timerNode) \
101 ((timerNode)->wheel && \
102 (!FILLP_TIMING_WHEEL_IS_CLEAR((timerNode)->status) || HLISTNODE_LINKED(&(timerNode)->cbListNode)))
103
104
FillpTimingWheelHourNodeEntry(struct HlistNode * hourNode)105 static __inline struct FillpTimingWheelTimerNode *FillpTimingWheelHourNodeEntry(struct HlistNode *hourNode)
106 {
107 return (struct FillpTimingWheelTimerNode *)((char *)(hourNode) -
108 (uintptr_t)(&(((struct FillpTimingWheelTimerNode *)0)->hourNode)));
109 }
110
FillpTimingWheelMinNodeEntry(struct HlistNode * minNode)111 static __inline struct FillpTimingWheelTimerNode *FillpTimingWheelMinNodeEntry(struct HlistNode *minNode)
112 {
113 return (struct FillpTimingWheelTimerNode *)((char *)(minNode) -
114 (uintptr_t)(&(((struct FillpTimingWheelTimerNode *)0)->minNode)));
115 }
116
FillpTimingWheelSecNodeEntry(struct HlistNode * secNode)117 static __inline struct FillpTimingWheelTimerNode *FillpTimingWheelSecNodeEntry(struct HlistNode *secNode)
118 {
119 return (struct FillpTimingWheelTimerNode *)((char *)(secNode) -
120 (uintptr_t)(&(((struct FillpTimingWheelTimerNode *)0)->secNode)));
121 }
122
FillpTimingWheelCycleNodeEntry(struct HlistNode * cycleNode)123 static __inline struct FillpTimingWheelTimerNode *FillpTimingWheelCycleNodeEntry(struct HlistNode *cycleNode)
124 {
125 return (struct FillpTimingWheelTimerNode *)((char *)(cycleNode) -
126 (uintptr_t)(&(((struct FillpTimingWheelTimerNode *)0)->cycleNode)));
127 }
128
FillpTimingWheelCblistNodeEntry(struct HlistNode * cbNode)129 static __inline struct FillpTimingWheelTimerNode *FillpTimingWheelCblistNodeEntry(struct HlistNode *cbNode)
130 {
131 return (struct FillpTimingWheelTimerNode *)((char *)(cbNode) -
132 (uintptr_t)(&(((struct FillpTimingWheelTimerNode *)0)->cbListNode)));
133 }
134
135 void FillpTimingWheelInit(struct FillpTimingWheel *ftWheel, FILLP_LLONG accuracy);
136
137 void FillpTimingWheelAddTimer(struct FillpTimingWheel *ftWheel, FILLP_LLONG expireTime,
138 struct FillpTimingWheelTimerNode *timerNode);
139
140 void FillpTimingWheelLoopCheck(struct FillpTimingWheel *ftWheel, FILLP_LLONG curTime);
141
142 void FillpTimingWheelDelTimer(struct FillpTimingWheel *ftWheel, struct FillpTimingWheelTimerNode *timerNode);
143
144 #ifdef __cplusplus
145 }
146 #endif
147
148 #endif /* FILLP_TIMEING_WHEEL_H */