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]); }
/* * This function is called by the assembly STUB function */ void uart_handler() { // Disable all interupts atomic_up(); #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Enter: uart_handler\r\n"); rtx_dbug_outs((CHAR *) "Reading data...\r\n"); #endif // irene said this should be enough - would be // very rare if it wasn't ready to read while (!(SERIAL1_UCSR & 1)) { } char_in = SERIAL1_RD; #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Determining what to do with char...\r\n"); #endif struct io_message * msg; switch(char_in) { #ifdef _HOTKEYS_DEBUG case '!': rtx_dbug_outs((CHAR *) "'!' hotkey detected...\r\n"); print_queues(); // print processes on ready queue and priorities break; case '@': rtx_dbug_outs((CHAR *) "'@' hotkey detected...\r\n"); print_mem_blocked(); // print processes on memory blocked queue and priorities break; case '#': rtx_dbug_outs((CHAR *) "'#' hotkey detected...\r\n"); print_msg_blocked(); // print processes on message blocked queue and priorities break; case '$': rtx_dbug_outs((CHAR *) "'$' hotkey detected...\r\n"); print_availible_mem_queue(); // print available memory queue break; case '^': rtx_dbug_outs((CHAR *) "'^' hotkey detected...\r\n"); print_used_mem_queue(); // print used memory queue break; case '&': rtx_dbug_outs((CHAR *) "'&' hotkey detected...\r\n"); output_kcd_buffer(); // print kcd buffer break; case '*': rtx_dbug_outs((CHAR *) "'*' hotkey detected...\r\n"); print_cmds(); // print valid commands break; #endif default: #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Sending message to KCD proc...\r\n"); #endif if (!are_blocks_available()) { atomic_down(); return; } msg = (io_message *)request_memory_block(); // reset tx/rx and send it to kcd msg->tx = UART_PID; msg->rx = KCD_PID; msg->msg[0] = char_in; send_message(KCD_PID, msg); break; } // Enable all interupts atomic_down(); }