/* * RUN THE COLLECTOR * args * Stack* s -- local variable stack * heap** h -- current (pointer to pointer to) from-space * int bd -- are we collecting BigData heap? (bool: 0 false, otherwise true) */ void collect(Stack* s, heap** h, int bd){ heap* to = heapCreate(); weakptrs = stackCreate(); // If stack is empty, return empty heap if(!s){ *h = to; return; } //evacuate things pointed to from the stack, update stack references do{ s->data = evac(s->data, *h, to); }while(s=s->next); // if collecting bigdata heap, no need to scavenge if(bd){ *h = to; return; } //scavenge the to-space scavenge(*h,to); /* * Check weak pointer references. If data is already forwarded, we know * it's got another reference -- copy the forwarding pointer loc. * Otherwise, we collect the data. */ int i; while((i = pop(&weakptrs)) != -1){ if((*h)->heap[to->heap[i+1]] == FWD) to->heap[i+1] = (*h)->heap[to->heap[i+1]+1]; else to->heap[i+1] = -1; } //Change reference of from-space to to-space free(*h); *h = to; //collect big data heap if(!(collectioncount % BIGDATACOLLECT)){ if(!bigdataindex) return; collect(bigdataindex, &bigdataheap, 1); Stack* bdi = bigdataindex; do{ (*h)->heap[bdi->bdloc] = bdi->data; }while(bdi=bdi->next); } }
void detalgo_1(long int sim_time, int service_rates[2], long int *num_arrivals[2], gboolean *overheard[2], long int total_arrivals[2], long int *max_ID_ack[2], long int *backlog[2], long int thres, gboolean *stable){ long int i,j,k; int c[2]; long int lastID[2] = {0,0}; long int g[2],b[2],r[2]; int FAST,SLOW; long int ID; int debug = 0; int mg,Mg; int counter; int flow; /* Initializations */ r[0] = service_rates[0]; r[1] = service_rates[1]; FAST = service_rates[FLOW_1] <= service_rates[FLOW_2]?FLOW_2:FLOW_1; SLOW = fmod(FAST+1,2); if (stable!=NULL) {*stable = TRUE; } /* Initialize TCPchecklist library. */ TCPchecklist_init(); /* Create TCP checklists */ TCPchecklist[FLOW_1] = TCPchecklist_create(total_arrivals[FLOW_1]); TCPchecklist[FLOW_2] = TCPchecklist_create(total_arrivals[FLOW_2]); /* Begin simulation */ for (i = 0; i<sim_time; i++){ /* Get new arrivals */ for (k = 0; k<2; k++){ /* flow loop */ for (j = 0; j<num_arrivals[k][i]; j++){ /* arrival loop */ lastID[k]++; ID = lastID[k]; if (overheard[k][ID-1]){ g_queue_push_tail(queues[k][GOOD],GINT_TO_POINTER(ID)); } else { g_queue_push_tail(queues[k][BAD],GINT_TO_POINTER(ID)); } } } if(debug){ printf("slot %ld\n",i); printf("after arrivals\n"); print_queues(); printf("************************************************\n"); } /* Rename variables for easier reference. */ g[0] = g_queue_get_length(queues[0][GOOD]); g[1] = g_queue_get_length(queues[1][GOOD]); b[0] = g_queue_get_length(queues[0][BAD]); b[1] = g_queue_get_length(queues[1][BAD]); /* Take controls */ if (g[FAST] >= r[SLOW] && g[SLOW] >= r[SLOW]){ evac( queues[FAST][GOOD],TCPchecklist[FAST],r[SLOW]); evac( queues[SLOW][GOOD],TCPchecklist[SLOW],r[SLOW]); } else if (b[FAST] >= r[FAST] && b[SLOW] >= r[SLOW]){ k = (GPOINTER_TO_INT(g_queue_peek_head(queues[FAST][BAD])) < GPOINTER_TO_INT(g_queue_peek_head(queues[SLOW][BAD]))) ? FAST : SLOW; evac( queues[k][BAD],TCPchecklist[k],r[k]); } else if (b[SLOW] >= r[SLOW]){ evac( queues[SLOW][BAD],TCPchecklist[SLOW],r[SLOW]); } else if (b[FAST] >= r[FAST]){ evac( queues[FAST][BAD],TCPchecklist[FAST],r[FAST]); } else if (b[SLOW] >= r[SLOW]){ evac( queues[SLOW][BAD],TCPchecklist[SLOW],r[SLOW]); } else if (g[SLOW] >= r[SLOW]){ evac( queues[SLOW][GOOD],TCPchecklist[SLOW],r[SLOW]); } else if (g[FAST] >= r[FAST]){ evac( queues[FAST][GOOD],TCPchecklist[FAST],r[FAST]); } /* anti-idleness controls */ else{ /* Determine what flow can send the most packets. */ mg = MIN(g[SLOW],g[FAST]); Mg = MAX(g[SLOW],g[FAST]); counter=0; if ( MIN(r[SLOW],g[SLOW]+g[FAST] + b[SLOW] + b[FAST] ) >= MIN(r[FAST],g[FAST]+b[FAST]) ) { while(counter<r[SLOW]){ g[0] = g_queue_get_length(queues[0][GOOD]); g[1] = g_queue_get_length(queues[1][GOOD]); b[0] = g_queue_get_length(queues[0][BAD]); b[1] = g_queue_get_length(queues[1][BAD]); /* Evacuate the g+g. */ if (g[FLOW_1] && g[FLOW_2]){ evac( queues[FAST][GOOD],TCPchecklist[FAST],1); evac( queues[SLOW][GOOD],TCPchecklist[SLOW],1); counter++; continue; } /* Evacuate any bad packets. */ if (b[FAST] && b[SLOW] ){ /* Choose the queue with the largest backlog. */ flow = (MAX(b[FAST],b[SLOW]) == b[SLOW])?SLOW:FAST; evac( queues[flow][BAD],TCPchecklist[flow],1); counter++; continue; } if (b[SLOW]){ evac( queues[SLOW][BAD],TCPchecklist[SLOW],1); counter++; continue; } if (b[FAST]){ evac( queues[FAST][BAD],TCPchecklist[FAST],1); counter++; continue; } /* g controls */ if (g[SLOW]){ evac( queues[SLOW][GOOD],TCPchecklist[SLOW],1); counter++; continue; } if (g[FAST]){ evac( queues[FAST][GOOD],TCPchecklist[FAST],1); counter++; continue; } break; } } else { while(counter<r[FAST]){ g[FAST] = g_queue_get_length(queues[FAST][GOOD]); b[FAST] = g_queue_get_length(queues[FAST][BAD]); /* First evacuate the fast bad packets. */ if( b[FAST]){ evac(queues[FAST][BAD],TCPchecklist[FAST],1); counter++; continue; } /* Then evacuate the fast good packets. */ if(g[FAST]){ evac(queues[FAST][GOOD],TCPchecklist[FAST],1); counter++; continue; } break; } } } if(debug){ printf("after control\n"); print_queues(); printf("************************************************\n");} /* Get greatest ACKed ID for this slot. */ max_ID_ack[FAST][i] = TCPchecklist_get_largest_consecutive_ACK_id(TCPchecklist[FAST]); max_ID_ack[SLOW][i] = TCPchecklist_get_largest_consecutive_ACK_id(TCPchecklist[SLOW]); /* Check if system is stable. Otherwise stop*/ if (stable!=NULL && (lastID[FLOW_1]-max_ID_ack[FLOW_1][i] > thres || lastID[FLOW_2]-max_ID_ack[FLOW_2][i] > thres) ){ *stable = FALSE; break; } /* Rename variables for easier reference. */ g[0] = g_queue_get_length(queues[0][GOOD]); g[1] = g_queue_get_length(queues[1][GOOD]); b[0] = g_queue_get_length(queues[0][BAD]); b[1] = g_queue_get_length(queues[1][BAD]); /* Compute current backlog. */ backlog[FLOW_1][i] = g[FLOW_1]+ b[FLOW_1]; backlog[FLOW_2][i] = g[FLOW_2]+ b[FLOW_2]; if(debug){ printf("checklists largest ACK\n"); printf("flow 1: %ld\nflow 2: %ld\n",max_ID_ack[FLOW_1][i],max_ID_ack[FLOW_2][i]); printf("************************************************\n"); printf("give values\n"); scanf(" %ld ",&k);} } /* Finalize TCPchecklist. */ TCPchecklist_finit(); /* Evacuate the queue remnants. */ g_queue_clear(queues[FLOW_1][GOOD]); g_queue_clear(queues[FLOW_1][BAD]); g_queue_clear(queues[FLOW_2][GOOD]); g_queue_clear(queues[FLOW_2][BAD]); }
/* * Scavenge. Evacuate references found in the to-heap. * End of switch assumes pointer at next tag. */ void scavenge(heap* from, heap* to){ int i=0; while(i < to->hp){ switch(to->heap[i]){ // Don't need to do anything. case INT: case BOOL: case WEAK: i+=2; break; // Don't need to do anything. case STRING: i++; while(to->heap[i] != 0) i++; i++; break; // Evac both references. case RANGE: to->heap[i+1] = evac(to->heap[i+1], from, to); to->heap[i+2] = evac(to->heap[i+2], from, to); i+=3; break; case BIGDATA: { int* bdh = bigdataheap->heap; i++; int lim = bdh[to->heap[i] + 1] + to->heap[i] + 3; int x = to->heap[i]; x+=2; while(++x < lim) bdh[x] = evac(bdh[x], from, to); i++; break; } case LAMBDA: { int lim = i + to->heap[i+2] + 3; i+=2; while(++i < lim) to->heap[i] = evac(to->heap[i], from, to); break; } case DATA: { int lim = i + datacons->heap[to->heap[i+1]] + 2; i++; while(++i < lim) to->heap[i] = evac(to->heap[i], from, to); break; } case SOFT: { if(from->hp < from->hpLimit / 2) //don't collect if >50% memory left to->heap[i+1] = evac(to->heap[i+1],from,to); else to->heap[i+1] = -1; i+=2; break; } // If cons is false, don't collect value. case PHANTOM: to->heap[i+1] = to->heap[i+2] ? evac(to->heap[i+1], from, to) : -1; i+=3; break; } } }