//weighted_round_robin.c
typedef struct node {
LinkListNode node;
int weight;
int effective_weight;
int current_weight;
int name;
}node_t;
int get_total_weight(void* list) {
int i;
int total_weight = 0;
for (i = 0; i < LinkList_Length(list); i++) {
struct node* tmp = (struct node*)LinkList_Get(list, i);
total_weight += tmp->effective_weight;
}
return total_weight;
}
int update_choosed_node_current_weight(void* node, int total_weight) {
node_t* choosed_node = (node_t*)node;
choosed_node->current_weight -= total_weight;
return 0;
}
void* get_max_weight_node(void* list) {
int i;
node_t* max_weight_node = (node_t*)LinkList_Get(list, 0);
for (i = 1; i < LinkList_Length(list); i++) {
struct node* tmp = (struct node*)LinkList_Get(list, i);
max_weight_node = (max_weight_node->current_weight < tmp->current_weight) ? tmp : max_weight_node;
}
return max_weight_node;
}
int update_node_current_weight(void* list) {
int i;
for (i = 0; i < LinkList_Length(list); i++) {
struct node* tmp = (struct node*)LinkList_Get(list, i);
tmp->current_weight += tmp->effective_weight;
}
return 0;
}
bool weighted_round_robin_arbitration(void* list, int round) {
int i=0;
for(i=0; i<round; i++){
update_node_current_weight(list);
node_t* max_weight_node = (node_t *)get_max_weight_node(list);
if(max_weight_node != NULL){
printf("round %d: choose queue name=%c, weight=%d, current_weight=%d\n",
i, max_weight_node->name, max_weight_node->weight, max_weight_node->current_weight);
}
else {
printf("ERROR: failed get node\n");
return false;
}
update_choosed_node_current_weight(max_weight_node, get_total_weight(list));
}
return true;
}
//test.c
int main() {
struct node node0;
node0.name = 'a';
node0.weight = 1;
node0.effective_weight = node0.weight;
node0.current_weight = 0;
struct node node1;
node1.name = 'b';
node1.weight = 2;
node1.effective_weight = node1.weight;
node1.current_weight = 0;
struct node node2;
node2.name = 'c';
node2.weight = 4;
node2.effective_weight = node2.weight;
node2.current_weight = 0;
LinkList* list = LinkList_Init();
LinkList_Insert(list, (LinkListNode*)& node0, LinkList_Length(list));
LinkList_Insert(list, (LinkListNode*)& node1, LinkList_Length(list));
LinkList_Insert(list, (LinkListNode*)& node2, LinkList_Length(list));
weighted_round_robin_arbitration(list, 7);
LinkList_Destory(list);
return 0;
}
Weighted round-robin useful reference link 1
Weighted round-robin useful reference link 2