Skip to content

Commit 0f1602f

Browse files
committed
Added scheduling algorithms STFQ and WFQ
This commit adds the following two scheduling algorithms to the repo using the new framework: - Weighted Fair Queueing (WFQ) - Start-Time Fair Queuing (STFQ) Signed-off-by: Frey Alfredsson <[email protected]>
1 parent 7f338c2 commit 0f1602f

File tree

2 files changed

+113
-9
lines changed

2 files changed

+113
-9
lines changed

queue-exp/pifo_stfq.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
#
66
# pifo-stfq.py
77

8+
"""Start-Time Fair Queuing (STFQ)
9+
10+
This scheduling algorithm is mentioned in the paper "Programmable packet
11+
scheduling at line rate" by Sivaraman, Anirudh, et al.
12+
13+
It schedules packets by their start time within a flow. It defines the start
14+
time as the finish time of the last enqueued packet within a flow.
15+
"""
16+
817
__copyright__ = """
918
Copyright (c) 2021 Toke Høiland-Jørgensen <[email protected]>
1019
Copyright (c) 2021 Frey Alfredsson <[email protected]>
@@ -26,23 +35,39 @@
2635
"""
2736

2837
from pifo_lib import Packet, Runner, Pifo
38+
from pifo_lib import SchedulingAlgorithm
39+
2940

41+
class Stfq(SchedulingAlgorithm):
42+
"""Start-Time Fair Queuing (STFQ)"""
3043

31-
class Stfq(Pifo):
3244
def __init__(self):
33-
super().__init__()
34-
self.last_finish = {}
35-
self.virt_time = 0
45+
self._pifo = Pifo()
46+
47+
self._last_finish = {}
48+
self._virt_time = 0
3649

3750
def get_rank(self, pkt):
38-
flow = pkt.flow
39-
if flow in self.last_finish:
40-
rank = max(self.virt_time, self.last_finish[flow])
51+
flow_id = pkt.flow
52+
if flow_id in self._last_finish:
53+
rank = max(self._virt_time, self._last_finish[flow_id])
4154
else:
42-
rank = self.virt_time
43-
self.last_finish[flow] = rank + pkt.length
55+
rank = self._virt_time
56+
self._last_finish[flow_id] = rank + pkt.length
4457
return rank
4558

59+
def enqueue(self, item):
60+
rank = self.get_rank(item)
61+
self._pifo.enqueue(item, rank)
62+
63+
def dequeue(self):
64+
return self._pifo.dequeue()
65+
66+
def dump(self):
67+
self._pifo.dump()
68+
69+
70+
4671
if __name__ == "__main__":
4772
pkts = [
4873
Packet(flow=1, idn=1, length=2),

queue-exp/pifo_wfq.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
# coding: utf-8 -*-
3+
#
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
#
6+
# pifo-wfq.py
7+
8+
"""Weighted Fair Queueing (WFQ)
9+
10+
This scheduling algorithm is mentioned in the paper "Programmable packet
11+
scheduling at line rate" by Sivaraman, Anirudh, et al. It schedules flows by
12+
giving them a fraction of the capacity using predefined weights. In our example,
13+
we defined flows with an odd number to get a weight of 50 and even numbers to
14+
get 100.
15+
"""
16+
17+
__copyright__ = """
18+
Copyright (c) 2021 Toke Høiland-Jørgensen <[email protected]>
19+
Copyright (c) 2021 Frey Alfredsson <[email protected]>
20+
"""
21+
22+
__license__ = """
23+
This program is free software: you can redistribute it and/or modify
24+
it under the terms of the GNU General Public License as published by
25+
the Free Software Foundation, either version 3 of the License, or
26+
(at your option) any later version.
27+
28+
This program is distributed in the hope that it will be useful,
29+
but WITHOUT ANY WARRANTY; without even the implied warranty of
30+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31+
GNU General Public License for more details.
32+
33+
You should have received a copy of the GNU General Public License
34+
along with this program. If not, see <http://www.gnu.org/licenses/>.
35+
"""
36+
37+
from pifo_lib import Packet, Runner, Pifo
38+
from pifo_lib import SchedulingAlgorithm
39+
40+
41+
class Wfq(SchedulingAlgorithm):
42+
"""Weighted Fair Queueing (WFQ)"""
43+
44+
def __init__(self):
45+
self._pifo = Pifo()
46+
self._last_finish = {}
47+
self._virt_time = 0
48+
49+
def get_rank(self, pkt):
50+
flow = pkt.flow
51+
weight = 50 if flow % 2 == 1 else 100
52+
if flow in self._last_finish:
53+
rank = max(self._virt_time, self._last_finish[flow])
54+
else:
55+
rank = self._virt_time
56+
self._last_finish[flow] = rank + pkt.length / weight
57+
return rank
58+
59+
def enqueue(self, item):
60+
rank = self.get_rank(item)
61+
self._pifo.enqueue(item, rank)
62+
63+
def dequeue(self):
64+
return self._pifo.dequeue()
65+
66+
def dump(self):
67+
self._pifo.dump()
68+
69+
70+
if __name__ == "__main__":
71+
pkts = [
72+
Packet(flow=1, idn=1, length=100),
73+
Packet(flow=1, idn=2, length=100),
74+
Packet(flow=1, idn=3, length=100),
75+
Packet(flow=2, idn=1, length=100),
76+
Packet(flow=2, idn=2, length=100),
77+
Packet(flow=2, idn=3, length=100),
78+
]
79+
Runner(pkts, Wfq()).run()

0 commit comments

Comments
 (0)