Skip to content

Commit a9edf34

Browse files
one-layer timing wheel
1 parent a6754b9 commit a9edf34

File tree

3 files changed

+135
-53
lines changed

3 files changed

+135
-53
lines changed

Data_Struct_Implementation/timerWheel/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ OBJ = timer.o
55
%.o: %.c
66
$(CC) -c -o $@ $< $(CFLAGS)
77

8-
stack: $(OBJ)
8+
timer: $(OBJ)
99
$(CC) -o $@ $^ $(CFLAGS)
1010

1111
clean:
12-
rm -f timer timer.o
12+
rm -f timer timer.o

Data_Struct_Implementation/timerWheel/README.md

Lines changed: 113 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,128 @@
1-
## StrStr
2-
#### Usage
1+
## Simple One-layer Timeing Wheel
2+
### Usage
33
```
44
make
5-
./strstr
5+
./timer
66
```
77

8-
#### Analysis
8+
### Analysis
99

10-
#### Code
10+
This is a simple one layer timing wheel design where the wheel contains 10 slices of wheel bin, with each bin it maintains a linked lists of callback function to call. These function will trigger once the timing wheel tick happens and deadline is due.
11+
12+
### Code
1113
```c
12-
#include <stdio.h>
13-
14-
// returns true if X and Y are same
15-
int compare(const char *X, const char *Y)
16-
{
17-
while (*X && *Y)
18-
{
19-
if (*X != *Y)
20-
return 0;
21-
22-
X++;
23-
Y++;
14+
#include<stdio.h>
15+
#include<stdint.h>
16+
#include<stdlib.h>
17+
#include<time.h>
18+
#include<unistd.h>
19+
20+
#define WHEEL_BIN_NUMBER 10
21+
#define GRANULARITY 1000000
22+
23+
typedef void (*timeout_handler)();
24+
25+
typedef struct node {
26+
struct node *next;
27+
int timestamp;
28+
timeout_handler timeout_cb;
29+
} Node, *pNode;
30+
31+
typedef struct timing_wheel {
32+
int cur_slot;
33+
int granularity;
34+
Node nodes[WHEEL_BIN_NUMBER];
35+
} TWheel, *pTWheel;
36+
37+
pTWheel init_time_wheel(int gran) {
38+
pTWheel new_wheel = (pTWheel) malloc(sizeof(TWheel));
39+
new_wheel->granularity = gran;
40+
new_wheel->cur_slot = 0;
41+
int i;
42+
for (i; i < WHEEL_BIN_NUMBER; i++) {
43+
new_wheel->nodes[i].next = NULL;
2444
}
25-
26-
return (*Y == '\0');
45+
46+
return new_wheel;
2747
}
28-
29-
// Function to implement strstr() function
30-
const char* strstr(const char* X, const char* Y)
31-
{
32-
while (*X != '\0')
33-
{
34-
if ((*X == *Y) && compare(X, Y))
35-
return X;
36-
X++;
48+
49+
int install_handler(pTWheel twheel, int deadline, timeout_handler new_cb) {
50+
int ret = 0;
51+
if (deadline/twheel->granularity >= WHEEL_BIN_NUMBER) {
52+
printf("Deadline exceed timing wheel size\n");
53+
return -1;
54+
}
55+
56+
int index = (twheel->cur_slot + ((deadline/(twheel->granularity))))%WHEEL_BIN_NUMBER;
57+
pNode iterator = &(twheel->nodes[index]);
58+
59+
while(iterator->next) {
60+
iterator = iterator->next;
61+
}
62+
63+
pNode new_node = (pNode) malloc(sizeof(Node));
64+
new_node->timeout_cb = new_cb;
65+
new_node->timestamp = deadline;
66+
new_node->next = NULL;
67+
iterator->next = new_node;
68+
69+
return ret;
70+
}
71+
72+
void tick(pTWheel twheel) {
73+
int i;
74+
pNode iterator = &twheel->nodes[twheel->cur_slot];
75+
while(iterator->next) {
76+
pNode tmp = iterator->next;
77+
tmp->timeout_cb();
78+
printf("Callback at %d deadline triggers\n", tmp->timestamp);
79+
iterator->next = iterator->next->next;
80+
free(tmp);
3781
}
38-
39-
return NULL;
82+
twheel->cur_slot = (twheel->cur_slot+1)%WHEEL_BIN_NUMBER;
4083
}
41-
42-
// Implement strstr function in C
43-
int main()
44-
{
45-
char *X = "Techie Delight - Coding made easy";
46-
char *Y = "Coding";
47-
48-
printf("%s\n", strstr(X, Y));
49-
84+
85+
void print_task() {
86+
printf("Hi1\n");
87+
}
88+
89+
void print_task2() {
90+
printf("Hi2\n");
91+
}
92+
93+
void print_task3() {
94+
printf("Hi3\n");
95+
}
96+
97+
int main(void) {
98+
int ret = 0;
99+
100+
pTWheel new_wheel = init_time_wheel(GRANULARITY);
101+
timeout_handler cb = print_task;
102+
install_handler(new_wheel, 4*GRANULARITY, cb);
103+
install_handler(new_wheel, 4.25*GRANULARITY, cb);
104+
install_handler(new_wheel, 4.9*GRANULARITY, cb);
105+
106+
cb = print_task2;
107+
install_handler(new_wheel, 8*GRANULARITY, cb);
108+
109+
cb = print_task3;
110+
install_handler(new_wheel, 8*GRANULARITY, cb);
111+
112+
install_handler(new_wheel, 12*GRANULARITY, cb);
113+
114+
int count = 0;
115+
while(count < 15) {
116+
tick(new_wheel);
117+
usleep(GRANULARITY);
118+
printf("Time: %d\n", count++);
119+
if (count == 8) {
120+
install_handler(new_wheel, 4*GRANULARITY, cb);
121+
}
122+
}
123+
50124
return 0;
51125
}
52126
```
53127
54128
### Reference
55-
56-
https://www.techiedelight.com/implement-strstr-function-c-iterative-recursive/

Data_Struct_Implementation/timerWheel/timer.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include<stdio.h>
22
#include<stdint.h>
3+
#include<stdlib.h>
4+
#include<time.h>
5+
#include<unistd.h>
36

47
#define WHEEL_BIN_NUMBER 10
58
#define GRANULARITY 1000000
@@ -46,6 +49,7 @@ int install_handler(pTWheel twheel, int deadline, timeout_handler new_cb) {
4649

4750
pNode new_node = (pNode) malloc(sizeof(Node));
4851
new_node->timeout_cb = new_cb;
52+
new_node->timestamp = deadline;
4953
new_node->next = NULL;
5054
iterator->next = new_node;
5155

@@ -56,8 +60,9 @@ void tick(pTWheel twheel) {
5660
int i;
5761
pNode iterator = &twheel->nodes[twheel->cur_slot];
5862
while(iterator->next) {
59-
iterator->next->timeout_cb();
6063
pNode tmp = iterator->next;
64+
tmp->timeout_cb();
65+
printf("Callback at %d deadline triggers\n", tmp->timestamp);
6166
iterator->next = iterator->next->next;
6267
free(tmp);
6368
}
@@ -80,22 +85,27 @@ int main(void) {
8085
int ret = 0;
8186

8287
pTWheel new_wheel = init_time_wheel(GRANULARITY);
83-
timeout_handler cb1 = print_task;
84-
install_handler(new_wheel, 4*GRANULARITY, cb1);
88+
timeout_handler cb = print_task;
89+
install_handler(new_wheel, 4*GRANULARITY, cb);
90+
install_handler(new_wheel, 4.25*GRANULARITY, cb);
91+
install_handler(new_wheel, 4.9*GRANULARITY, cb);
8592

86-
timeout_handler cb2 = print_task2;
87-
install_handler(new_wheel, 8*GRANULARITY, cb2);
93+
cb = print_task2;
94+
install_handler(new_wheel, 8*GRANULARITY, cb);
8895

89-
timeout_handler cb3 = print_task3;
90-
install_handler(new_wheel, 8*GRANULARITY, cb3);
91-
92-
install_handler(new_wheel, 12*GRANULARITY, cb3);
96+
cb = print_task3;
97+
install_handler(new_wheel, 8*GRANULARITY, cb);
98+
99+
install_handler(new_wheel, 12*GRANULARITY, cb);
93100

94101
int count = 0;
95-
while(count < 5) {
102+
while(count < 15) {
96103
tick(new_wheel);
97104
usleep(GRANULARITY);
98105
printf("Time: %d\n", count++);
106+
if (count == 8) {
107+
install_handler(new_wheel, 4*GRANULARITY, cb);
108+
}
99109
}
100110

101111
return 0;

0 commit comments

Comments
 (0)