📄 mac-802_16-fsm.cc
字号:
ss_id,UpFlowTable[tbindex].upstream_record.flow_id, ran,UpFlowTable[tbindex].bk_offstart); /* Take care whether the slot size is big enough to send a request... TODO: Explain what is happening here .... */ /* Set the internal bkoff-window to bkoff-start*/ UpFlowTable[tbindex].bk_offwin = UpFlowTable[tbindex].bk_offstart; //UpFlowTable[tbindex].bk_offwin = ran + size_ureqgrant; /* Skip ran*size_ureqgrant opportunity */ UpFlowTable[tbindex].bk_offcounter = ran * size_ureqgrant; /* Look for slots to skip + sufficient slots to send a req */ UpFlowTable[tbindex].bk_offcounter += size_ureqgrant; UpFlowTable[tbindex].contention_on = 1; n = NumContentionSlots(tbindex); if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf): (1) found %d contention slots, bk_offcounter is %d\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(),n, UpFlowTable[tbindex].bk_offcounter); /*If this is true, then the random number of slots we are to skip exceeds the number of slots in this map.*/ if (UpFlowTable[tbindex].bk_offcounter > n) { MarkUsedContentionSlots(n,tbindex); UpFlowTable[tbindex].bk_offcounter -= n; /* Its important to make sure that after skipping the slots, enough number of slots are left capable of sending req frame.. */ if (UpFlowTable[tbindex].bk_offcounter < size_ureqgrant) UpFlowTable[tbindex].bk_offcounter = size_ureqgrant; UpFlowTable[tbindex].state = NRTPOLL_WAITFORMAP; if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf):Decided to wait for another MAP(WHY??)\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); } else { u_int32_t n_slots; /* We have already skipped more than neccessary slots , but there were not sufficient slots to send req last time, so find the first contention tx opportunity you get */ if (UpFlowTable[tbindex].bk_offcounter == size_ureqgrant) n_slots = 1; else /* e.g skip 13 slots, size_ureqgrant is 2.. Now when we reach here we have already skipped 11.. So, bkoff_couner is 15-11=4... So, we have to find the begining of 4 - 2 +1 i.e starting of 14nt slot.. */ n_slots = UpFlowTable[tbindex].bk_offcounter - size_ureqgrant + 1; etime = find_contention_slot(tbindex,n_slots); if (etime < 0.0) { printf("SS%d(flow-id %d) Timer expiration error: exiting..\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); exit(1); } mhReq_.start((Packet*)(&UpFlowTable[tbindex].intr), etime); current_time = Scheduler::instance().clock(); insert_reqlist(current_time + etime, tbindex); UpFlowTable[tbindex].num_retries++; UpFlowTable[tbindex].state = NRTPOLL_TOSENDREQ; if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf):Found etime of %lf,move to TOSENDREQ(WHY??)\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(),etime); } break; case CONTENTION_SLOTS: /* NumContentionSlots will return number of 'unused' contention slots available in the allocation table */ n = NumContentionSlots(tbindex); if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention: Found %d contention slots. \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id,n); if ( UpFlowTable[tbindex].bk_offcounter > n) { MarkUsedContentionSlots(n,tbindex); UpFlowTable[tbindex].bk_offcounter -= n; if (UpFlowTable[tbindex].bk_offcounter < size_ureqgrant) UpFlowTable[tbindex].bk_offcounter = size_ureqgrant; UpFlowTable[tbindex].state = NRTPOLL_WAITFORMAP; } else { u_int32_t n_slots; /* We have already skipped more than neccessary slots, but there were not sufficient slots to send req last time, so find the first contention tx opportunity you get */ if (UpFlowTable[tbindex].bk_offcounter == size_ureqgrant) n_slots = 1; else /* e.g skip 13 slots, size_ureqgrant is 2.. Now when we reach here we have already skipped 11.. So, bkoff_couner is 15-11=4... So, we have to find the begining of 4 - 2 +1 i.e starting of 14nt slot.. */ n_slots = UpFlowTable[tbindex].bk_offcounter - size_ureqgrant + 1; etime = find_contention_slot(tbindex,n_slots); if (etime == -1.0) { printf("SS%d(flow-id %d) Timer expiration error: exiting..\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); exit(1); } mhReq_.start((Packet*)(&UpFlowTable[tbindex].intr), etime); current_time = Scheduler::instance().clock(); insert_reqlist(current_time + etime, tbindex); UpFlowTable[tbindex].num_retries++; UpFlowTable[tbindex].state = NRTPOLL_TOSENDREQ; } break; case CONTENTION_BKOFF: ran = rng_->uniform((int)UpFlowTable[tbindex].bk_offwin); if (UpFlowTable[tbindex].num_retries == 1) /* First back-off */ { UpFlowTable[tbindex].avg_fcont += ran; UpFlowTable[tbindex].fcont_count++; } if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention: Backed-off,will skip %d slots\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id,ran); /* Take care whether the slot size is big enough to send a request... TODO: Explain what is happening here .... */ //UpFlowTable[tbindex].bk_offwin = ran + size_ureqgrant; /* Skip ran*size_ureqgrant opportunity */ UpFlowTable[tbindex].bk_offcounter = ran * size_ureqgrant; /* Look for slots to skip + sufficient slots to send a req */ UpFlowTable[tbindex].bk_offcounter += size_ureqgrant; n = NumContentionSlots(tbindex); if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf): (2) found %d contention slots, bk_offcounter is %d\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(),n, UpFlowTable[tbindex].bk_offcounter); if (UpFlowTable[tbindex].bk_offcounter > n) { MarkUsedContentionSlots(n,tbindex); UpFlowTable[tbindex].bk_offcounter -= n; /* Its important to make sure that after skipping the slots, enough number of slots are left capable of sending req frame.. */ if (UpFlowTable[tbindex].bk_offcounter < size_ureqgrant) UpFlowTable[tbindex].bk_offcounter = size_ureqgrant; UpFlowTable[tbindex].state = NRTPOLL_WAITFORMAP; if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf):Decided to wait for another MAP(WHY??)\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); } else { u_int32_t n_slots; /* We have already skipped more than neccessary slots, but there were not sufficient slots to send req last time, so find the first contention tx opportunity you get */ if (UpFlowTable[tbindex].bk_offcounter == size_ureqgrant) n_slots = 1; else /* e.g skip 13 slots, size_ureqgrant is 2.. Now when we reach here we have already skipped 11.. So, bkoff_couner is 15-11=4... So, we have to find the begining of 4 - 2 +1 i.e starting of 14nt slot.. */ n_slots = UpFlowTable[tbindex].bk_offcounter - size_ureqgrant + 1; etime = find_contention_slot(tbindex,n_slots); if (etime < 0.0) { printf("SS%d(flow-id %d) Timer expiration error: exiting..\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); exit(1); } mhReq_.start((Packet*)(&UpFlowTable[tbindex].intr), etime); current_time = Scheduler::instance().clock(); insert_reqlist(current_time + etime, tbindex); UpFlowTable[tbindex].num_retries++; UpFlowTable[tbindex].state = NRTPOLL_TOSENDREQ; if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):nrtpoll_contention(%lf):Found etime of %lf, move to TOSENDREQ (WHY??)\n", ss_id, UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(),etime); } break; default: printf("SS%d(flow-id %d) NRTPOLL-REQSENT state error: Unknown event received %d\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id,e); break; } return 1;}/*===========================END NRT-POLL STATE MACHINE FUNCTIONS===================*//*===========================BEST-EFFORT STATE MACHINE FUNCTIONS===================*//************************************************************************* tbindex denotes the service-flow entry on which packet has been mapped *************************************************************************//*! \param tbindex denotes the service-flow entry on which packet has been mapped */int Mac802_16SS::beffort_idle(char tbindex, EventType e, Packet* p){ if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_idle(%lf): BEFFORT_IDLE state \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); switch(e) { case PKT_ARRIVAL:#ifdef TIMINGS// printf("1 %lf %d %d 1\n",Scheduler::instance().clock(),// UpFlowTable[tbindex].upstream_record.flow_id,ss_id); //This is for the arrival from the outside timingsTrace(p,1);#endif if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_idle(%lf):Packet arrived, go to decision state\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); //insert_pkt(p,tbindex); UpFlowTable[tbindex].state = BEFFORT_DECISION; UpFlowTable[tbindex].pkt = p; /* Since this pkt is not being queued, so update the enque_time variable */ UpFlowTable[tbindex].enque_time = Scheduler::instance().clock(); UpFlowTable[tbindex].queuing_samples++; beffort_decision(tbindex, PKT_ARRIVAL, p); break; case MAP_ARRIVAL: UpdateAllocationTable(tbindex); if (UpFlowTable[tbindex].debug) { printf("SS%d(flow-id %d):beffort_idle(%lf): MAP arrived, new state: %d \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(), UpFlowTable[tbindex].state); printf("SS%d(flow-id %d) Allocation table \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); print_alloclist(tbindex); } break; default: printf("SS%d(flow-id %d) BEFFORT-IDLE state error: Unknown event received\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); break; } return 1;}/**************************************************************************************************************************************************/ int Mac802_16SS::beffort_decision(char tbindex, EventType e, Packet* p){ if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf): entered with event %d \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(),e); switch(e) { case PKT_ARRIVAL:#ifdef TIMINGS //We only get here from another state... //We enter a new request process timingsTrace(p,2);#endif if (!CanBeSent(UpFlowTable[tbindex].alloc_list,p,tbindex)) { if (UpFlowTable[tbindex].debug) printf("SS%d (flow-id %d):beffort_decision(%lf): Can NOT BeSent! \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); if (!CanUnicastReqBeSent(tbindex)) { if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf):Unicast Req Can NOT BeSent!\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); /*$A11 if (DataGrantPending(tbindex)) { if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf):DataGrant is pending... goto REQSENT state\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock()); turn_off_contention(tbindex); UpFlowTable[tbindex].state = BEFFORT_REQSENT; } else */ if (CanContentionReqBeSent(tbindex)) { UpFlowTable[tbindex].state = BEFFORT_CONTENTION; if (!UpFlowTable[tbindex].contention_on) beffort_contention(tbindex, CONTENTION_ON, p); else /* Contention is on and reached decision state, that implies that back-off has occured */ beffort_contention(tbindex, CONTENTION_BKOFF, p); if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf):ContentionRequ COULD be sent:updated state:%d\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(), UpFlowTable[tbindex].state); } else { UpFlowTable[tbindex].state = BEFFORT_WAITFORMAP; } if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf):Unicast req COULD NOT be sent:updated state:%d\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(), UpFlowTable[tbindex].state); } else { UpFlowTable[tbindex].state = BEFFORT_TOSENDREQ; turn_off_contention(tbindex); beffort_tosendreq(tbindex,SEND_UREQ, p); if (UpFlowTable[tbindex].debug) printf("SS%d(flow-id %d):beffort_decision(%lf):Unicast req CAN be sent:updated state:%d \n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id, Scheduler::instance().clock(), UpFlowTable[tbindex].state); } } else { turn_off_contention(tbindex); UpFlowTable[tbindex].state = BEFFORT_TOSEND; beffort_tosend(tbindex, SEND_PKT, p); } break; default: printf("SS%d(flow-id %d) BEFFORT-DECISION state error: Unknown event received\n", ss_id,UpFlowTable[tbindex].upstream_record.flow_id); break; } return 1;}/**************************************************************************************************************************************************/int Mac802_16SS::beffort_waitformap(char tbindex, EventType e, Packet* p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -