📄 genericatmswitch.java
字号:
}
}
}
}
private void sw_proc_slot_time() {
java.util.Iterator i=voports.values().iterator();
while(i.hasNext()) {
sw_demux_spq((Port)i.next());
}
i=voports.values().iterator();
while(i.hasNext()) {
Port voport=(Port)i.next();
if((!voport.sigQueue.isEmpty() || !voport.abr.ptr.isEmpty()
|| !voport.vbr.ptr.isEmpty()) &&
!voport.link_busy) {
voport.link_busy=true;
sw_schedule_output(voport);
}
}
}
private void sw_averaging_interval() {
//update cell loss percent
sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
}
private void sw_demux_spq(Port voport) {
Cell cell;
int i,temp,qs,pick,no_drop,lst[]=null;
boolean done,match;
ForwardEntry fe;
qs = voport.spq.size();
no_drop=(qs > sw_speedup.getValue() ? qs-sw_speedup.getValue():0);
if(no_drop!=0) {
sw_cpucong.setValue(true);
sw_cpucong.update(theSim.now());
lst=new int[qs];
for(i=0;i<qs;i++) lst[i]=i;
for(i=0;i<no_drop;i++) {
pick=randgen.nextInt(qs-i)+i;
//swap entry i with the picked entry
temp=lst[i];
lst[i]=lst[pick];
lst[pick]=temp;
}
//the above code shuffles the number randomly (fairly too),
//(only the first no_drop entries actually "shuffled" out)
//and the first no_drop entries will be the index of the cell
//in spq to be dropped
}
pick=0;
match=false;
while(!voport.spq.isEmpty()) {
cell=(Cell)voport.spq.remove(0);
for(i=0;i<no_drop;i++) {
if(pick==lst[i]) {
match=true;
break;
}
}
if(match) {
num_dropped++;
sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
cell=null;
match=false;
}
else {
fe=(ForwardEntry)cell.forwardEntry;
//it's time to switch ...
cell.vpi=fe.tokey.vpi;
cell.vci=fe.tokey.vci;
if(fe.contype==UNIInfo.CON_ABR || fe.contype==UNIInfo.CON_UBR) {
if((voport.abr.ptr.size() < sw_oqsize.getValue())
|| (sw_oqsize.getValue() == -1)) {
voport.abr.ptr.add(cell);
voport.abr.iq.setValue(voport.abr.ptr.size(),theSim.now(),sw_log_factor.getValue());
}
else {
num_dropped++;
sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
voport.abr.dq.setValue(voport.abr.dq.getValue()+1,theSim.now(),sw_log_factor.getValue());
cell=null;
}
}
else {
if((voport.vbr.ptr.size() < sw_oqsize.getValue())
|| (sw_oqsize.getValue()==-1)) {
voport.vbr.ptr.add(cell);
voport.vbr.iq.setValue(voport.vbr.ptr.size(),theSim.now(),sw_log_factor.getValue());
}
else {
num_dropped++;
sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
voport.vbr.dq.setValue(voport.vbr.dq.getValue()+1,theSim.now(),sw_log_factor.getValue());
cell=null;
}
}
}
pick++;
}
}
private void sw_schedule_output(Port voport) {
Cell icell=null;
if(!voport.sigQueue.isEmpty()) {
icell=(Cell)voport.sigQueue.remove(0);
}
else if(!voport.vbr.ptr.isEmpty()) {
icell=(Cell)voport.vbr.ptr.remove(0);
voport.vbr.iq.setValue(voport.vbr.iq.getValue() - 1,theSim.now(),sw_log_factor.getValue());
}
else if(!voport.abr.ptr.isEmpty()) {
icell=(Cell)voport.abr.ptr.remove(0);
voport.abr.iq.setValue(voport.abr.iq.getValue() - 1,theSim.now(),sw_log_factor.getValue());
}
theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,
voport.to_link,theSim.now(),icell));
}
private void sw_receive(SimEvent e) {
long ticks;
ticks=SimClock.USec2Tick(sw_delay.getValue());
theSim.enqueue(new SimEvent(MY_RECEIVE,e.getSource(),this,
theSim.now()+ticks,e.getParams()));
//update cell count
total_cell++;
sw_cells_received.setValue(sw_cells_received.getValue()+1,theSim.now(),sw_log_factor.getValue());
}
private void sw_my_receive(SimEvent e) {
Cell cell=(Cell)e.getParams();
ForwardEntry fe;
SimComponent src=(SimComponent)e.getSource();
Port voport=null;
fe=(ForwardEntry)sw_forward_table.lookup(cell.vpi,cell.vci,src);
if(fe==null) { //no forwarding info
//check for signaling cells
if(cell.vpi==0 && cell.vci==5) {
doUNI(cell,(Port)voports.get(src));
}
else {
//else, drop the cell
num_dropped++;
sw_dropped.setValue(num_dropped*100.0/total_cell,theSim.now(),sw_log_factor.getValue());
}
return;
}
cell.forwardEntry=fe;
voport=(Port)voports.get(fe.tokey.link);
voport.spq.add(cell);
}
private void doUNI(Cell cell,Port voport) {
CallRecord rec;
SimComponent dest;
int vpi,vci,cref;
if(voport.aal.receiveCell(cell)==1) {
UNIInfo uni=(UNIInfo)cell.payload;
switch(uni.msgtype) {
case UNIInfo.UNI_SETUP:
//first, add a new record
CallRecord newrec=new CallRecord();
newrec.fe=new ForwardEntry();
if(uni.newvpi!=-1 && uni.newvci!=-1) {
newrec.fe.fromkey=new ForwardKey(uni.newvpi,uni.newvci,voport.to_link);
}
else { //tedious, must generate new vpi,vci
do {
vpi=randgen.nextInt(255)+1;
vci=randgen.nextInt(65535)+1;
newrec.fe.fromkey=new ForwardKey(vpi,vci,voport.to_link);
} while(sw_forward_table.fromkeyExist(newrec.fe.fromkey));
}
newrec.fromkey=new CallRecordKey(uni.callref,voport.to_link);
newrec.fe.contype=uni.contype;
newrec.fe.svc=true;
dest=sw_route_table.queryOutLink(uni.calledNSAP);
if(dest==null || dest==voport.to_link) { //this is bad...
//System.out.println("Routing problem at switch: "+getName());
//System.out.println(" Call request from: "+voport.to_link.getName());
//System.out.print(" Either destination not found or ");
//System.out.println(" destination same as source.");
//it's time to send a release_complete...
UNIInfo newuni=new UNIInfo();
newuni.callref=uni.callref+65535; //see NOTE below
newuni.msgtype=UNIInfo.UNI_RELEASE_COMPLETE;
voport.sigQueue.addAll(voport.aal.sendData(newuni,20,0,5));
return;
}
do { //tedious again, must generate new vpi,vci
vpi=randgen.nextInt(255)+1;
vci=randgen.nextInt(65535)+1;
newrec.fe.tokey=new ForwardKey(vpi,vci,dest);
} while(sw_forward_table.tokeyExist(newrec.fe.tokey));
//now generate new callref to dest
do {
cref=randgen.nextInt(65535)+1;
newrec.tokey=new CallRecordKey(cref,dest);
/* NOTE:
Call reference actually has a flag, 0 when sent from source,
1 when sent toward source. Here, I use 1-65535 when sent from source,
and 65536-131070 when sent toward source. This is to avoid
simultaneus assignment of same call reference from two source
(refer UNI3.1 spec of ATMForum).
(Of course, in the records and r_records maps, the original value
1-65535 is always used)
*/
} while(r_records.get(newrec.tokey)!=null);
sw_forward_table.addNewEntry(newrec.fe);
records.put(newrec.fromkey,newrec);
r_records.put(newrec.tokey,newrec);
//next, send back CALL_PROCEEDING
UNIInfo newuni=new UNIInfo();
newuni.callref=uni.callref+65535; //remember, toward source should
//add 65535
newuni.msgtype=UNIInfo.UNI_CALL_PROCEEDING;
newuni.newvpi=newrec.fe.fromkey.vpi;
newuni.newvci=newrec.fe.fromkey.vci;
voport.sigQueue.addAll(voport.aal.sendData(newuni,20,0,5));
//then, pass along the SETUP message, change necessary info
uni.callref=newrec.tokey.callref;
uni.newvpi=newrec.fe.tokey.vpi;
uni.newvci=newrec.fe.tokey.vci;
voport=(Port)voports.get(dest); //switch port to destination port
voport.sigQueue.addAll(voport.aal.sendData(uni,120,0,5));
break;
case UNIInfo.UNI_CONNECT:
//need to pass along this message to source
rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
if(rec==null) return; //no record?!!
uni.callref=rec.fromkey.callref+65535;
voport=(Port)voports.get(rec.fromkey.link);
voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));
break;
case UNIInfo.UNI_RELEASE:
//must delete record, and pass along
//release can be from either direction
if(uni.callref>65535) { //reverse direction, from destination
rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
if(rec==null) return; //no record?!!
uni.callref=rec.fromkey.callref+65535;
voport=(Port)voports.get(rec.fromkey.link);
}
else {
rec=(CallRecord)records.get(new CallRecordKey(uni.callref,voport.to_link));
if(rec==null) return; //no record?!!
uni.callref=rec.tokey.callref;
voport=(Port)voports.get(rec.tokey.link);
}
voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));
//delete the record
sw_forward_table.removeEntry(rec.fe);
records.remove(rec.fromkey);
r_records.remove(rec.tokey);
break;
case UNIInfo.UNI_RELEASE_COMPLETE:
//only used for rejecting call setup request
//so assume from the destination side
//must delete record and pass along
rec=(CallRecord)r_records.get(new CallRecordKey(uni.callref-65535,voport.to_link));
if(rec==null) return; //no record?!!
uni.callref=rec.fromkey.callref+65535;
voport=(Port)voports.get(rec.fromkey.link);
voport.sigQueue.addAll(voport.aal.sendData(uni,20,0,5));
//delete the record
sw_forward_table.removeEntry(rec.fe);
records.remove(rec.fromkey);
r_records.remove(rec.tokey);
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -