* The controller decides whether in this iteration we should send * (the packet is in c->tosend) and/or receive (flag c->can_dequeue) */
| 643 | * (the packet is in c->tosend) and/or receive (flag c->can_dequeue) |
| 644 | */ |
| 645 | static void |
| 646 | controller(struct cfg_s *c) |
| 647 | { |
| 648 | struct mbuf *m; |
| 649 | struct dn_fs *fs; |
| 650 | int flow_id; |
| 651 | |
| 652 | /* hysteresis between max and min */ |
| 653 | if (c->state == 0 && c->pending >= (uint32_t)c->th_max) |
| 654 | c->state = 1; |
| 655 | else if (c->state == 1 && c->pending <= (uint32_t)c->th_min) |
| 656 | c->state = 0; |
| 657 | ND(1, "state %d pending %2d", c->state, c->pending); |
| 658 | c->can_dequeue = c->state; |
| 659 | c->tosend = NULL; |
| 660 | if (c->can_dequeue) |
| 661 | return; |
| 662 | |
| 663 | /* |
| 664 | * locate the flow to use for enqueueing |
| 665 | * We take the queue with the lowest number of queued packets, |
| 666 | * generate a packet for it, and put the queue in the next highest. |
| 667 | */ |
| 668 | if (1) { |
| 669 | int i; |
| 670 | struct dn_queue *q; |
| 671 | struct list_head *h; |
| 672 | |
| 673 | i = ffs(c->llmask) - 1; |
| 674 | if (i < 0) { |
| 675 | D("no candidate"); |
| 676 | c->can_dequeue = 1; |
| 677 | return; |
| 678 | } |
| 679 | h = &c->ll[i]; |
| 680 | ND(1, "backlog %d p %p prev %p next %p", i, h, h->prev, h->next); |
| 681 | q = list_first_entry(h, struct dn_queue, ni.h); |
| 682 | list_del(&q->ni.h); |
| 683 | flow_id = Q2FI(c, q); |
| 684 | DX(2, "extracted flow %p %d backlog %d", q, flow_id, i); |
| 685 | if (list_empty(h)) { |
| 686 | ND(2, "backlog %d empty", i); |
| 687 | c->llmask &= ~(1<<i); |
| 688 | } |
| 689 | ND(1, "before %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next); |
| 690 | list_add_tail(&q->ni.h, h+1); |
| 691 | ND(1, " after %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next); |
| 692 | if (i < BACKLOG) { |
| 693 | ND(2, "backlog %d full", i+1); |
| 694 | c->llmask |= 1<<(1+i); |
| 695 | } |
| 696 | fs = &q->fs->fs; |
| 697 | fs->cur = flow_id; |
| 698 | #ifdef USE_CUR |
| 699 | c->cur_fs = q->fs - c->fs; |
| 700 | } else { |
| 701 | /* XXX this does not work ? */ |
| 702 | /* now decide whom to send the packet, and the length */ |
no test coverage detected