コード例 #1
0
ファイル: switch.c プロジェクト: jinxyz527/eece494
// Thread which will handle dequeing and re-enqueing based on the status
// and the flags for all ports in the output buffer
void *output_monitor_routine(void *arg) {
    packet_t in_pkt ;
    ip_address_t address ;
    int dest_port=0 ;
    int loop_count= 0 ;
    element_to_queue * element ;

    while(!die) {

        // Only care dequing if there are elements.
        if((output_buffer->size > 0)) {
            // This will indeed dequeue the packet, but we may
            // have to put it back if the port isn't ready.

            queue_lock(output_buffer) ;
            dequeue(output_buffer,&in_pkt) ;
            queue_unlock(output_buffer) ;

            // Fetch the IP & lookup destination port
            ip_address_copy(&(in_pkt.address),&address);
            dest_port = cam_lookup_address(&address) ;
            if((dest_port != -1) && (dest_port < 4)) {
                // Wait for the lock
                port_lock(&(out_port[dest_port])) ;
                // If the flag is busy from the last write, then
                // we have to put the packet back in the queue and just
                // have to wait until we get to it again.
                if(out_port[dest_port].flag) {
                    element = calloc(1,sizeof(element_to_queue)) ;
                    packet_copy(&in_pkt,&(element->packet));

                    queue_lock(output_buffer) ;
                    enqueue(element,output_buffer) ;
                    queue_unlock(output_buffer) ;

                    port_unlock(&(out_port[dest_port])) ;
                    continue ;
                }
                // Port ready to be written , so go ahead and write.
                packet_copy(&in_pkt,&(out_port[dest_port].packet));
                out_port[dest_port].flag = TRUE ;
                port_unlock(&(out_port[dest_port])) ;
            }
        }
        // Make sure it tried to at least deque 5 elements, before we
        // make it sleep.
        if(loop_count > LOOP_COUNT) {
            loop_count = 0 ;
            sleep() ;
        } else
            loop_count++ ;
    }
}
コード例 #2
0
ファイル: switch.c プロジェクト: vanjoe/eece494
void *switch_thread_routine(void *arg)
{
	int i, k;	// For loops
	while (!die) {

		// Check if the in ports have any pending packets
		for (i = 0; i < 4; i++) {
			port_lock(&(in_port[i]));

			if (in_port[i].flag) {
				// If flag is set, deal with the packet
				int target_port = cam_lookup_address(&in_port[i].packet.address);
				port_lock(&(out_port[target_port]));

				// If the target out port is free, send the packet to it.
				// Else, add the current packet to the port's buffer.
				if (!out_port[target_port].flag) {
					out_port[target_port].packet.address = in_port[i].packet.address;
					out_port[target_port].packet.payload = in_port[i].packet.payload;
					out_port[target_port].flag = 1;
				} else {
					// If the buffer isn't full, add the packet.
					// Packet will be lost if the buffer is full.
					if (pending[target_port] < BUFFER_SIZE) {
						buffers[target_port][++pending[target_port]].address = in_port[i].packet.address;
						buffers[target_port][pending[target_port]].payload = in_port[i].packet.payload;
					}
				}

				in_port[i].flag = 0;
				port_unlock(&(out_port[target_port]));
			}
			port_unlock(&(in_port[i]));
		}
		
		// Check if the out ports have any pending packets in their buffers
		for (k = 0; k < 4; k++) {
			port_lock(&(out_port[k]));

			// If the output port is free and has packets in its buffer, send pcaktes to the port.
			if (!out_port[k].flag && pending[k] >= 0) {
				out_port[k].packet.address = buffers[k][pending[k]].address;
				out_port[k].packet.payload = buffers[k][pending[k]].payload;
				out_port[k].flag = 1;
				pending[k]--;
			}

			port_unlock(&(out_port[k]));
		}

	}
}
コード例 #3
0
ファイル: switch.c プロジェクト: vanjoe/eece494
void *switch_thread_routine(void *arg)
{
	int inputPortNumber, outputPortNumber, i, j;	// For loops	

	int inputPortPriorities[NUM_PORTS];
	int outputPortPriorities[NUM_PORTS];

	// ex. virtualOutputQueues[inputPort][outputPort]
	packet_t virtualOutputQueues[NUM_PORTS][NUM_PORTS][VOQ_SIZE];
	int virtualOutputQueueReadIndex[NUM_PORTS][NUM_PORTS];
	int virtualOutputQueueWriteIndex[NUM_PORTS][NUM_PORTS];

	packet_t outputBuffer[NUM_PORTS][OUTPUT_BUFFER_SIZE];
	int outputBufferReadIndex[NUM_PORTS];
	int outputBufferWriteIndex[NUM_PORTS];

	// Initialize the buffers
	memset(inputPortPriorities, 0, NUM_PORTS * sizeof(int));
	memset(outputPortPriorities, 0, NUM_PORTS * sizeof(int));

	memset(virtualOutputQueues, 0, NUM_PORTS * NUM_PORTS * VOQ_SIZE * sizeof(packet_t));
	memset(virtualOutputQueueReadIndex, 0, NUM_PORTS * NUM_PORTS * sizeof(int));
	memset(virtualOutputQueueWriteIndex, 0, NUM_PORTS * NUM_PORTS * sizeof(int));

	memset(outputBuffer, 0, NUM_PORTS * OUTPUT_BUFFER_SIZE * sizeof(packet_t));
	memset(outputBufferReadIndex, 0, NUM_PORTS * sizeof(int));
	memset(outputBufferWriteIndex, 0, NUM_PORTS * sizeof(int));

	while (!die) {

		// Check if the in ports have any pending packets
		// Add them to the appropriate VOQ
		for (inputPortNumber = 0; inputPortNumber < NUM_PORTS; inputPortNumber++) {
			port_lock(&(in_port[inputPortNumber]));
			if (in_port[inputPortNumber].flag) {
				// If flag is set, deal with the packet
				int outputPortNumber = cam_lookup_address(&in_port[inputPortNumber].packet.address);
				int queueWriteIndex = virtualOutputQueueWriteIndex[inputPortNumber][outputPortNumber];
				virtualOutputQueues[inputPortNumber][outputPortNumber][queueWriteIndex].address = in_port[inputPortNumber].packet.address;
				virtualOutputQueues[inputPortNumber][outputPortNumber][queueWriteIndex].payload = in_port[inputPortNumber].packet.payload;

				// Increment the write pointer for the virtual output queue
				virtualOutputQueueWriteIndex[inputPortNumber][outputPortNumber] = (queueWriteIndex + 1) % VOQ_SIZE;
				int voqwi = virtualOutputQueueWriteIndex[inputPortNumber][outputPortNumber];

				// Clear the flag, we've got the packet in a virtual output queue
				in_port[inputPortNumber].flag = 0;
			}
			port_unlock(&(in_port[inputPortNumber]));
		}

		// Run a round of the RR-New scheduling algorithm if any of the queues are non-empty
		// Request phase
		int totalRequests = 0;
		// ex. requests[outputPortNumber][inputPortNumber] = TRUE
		int requests[NUM_PORTS][NUM_PORTS];

		
		for (inputPortNumber = 0; inputPortNumber < NUM_PORTS; inputPortNumber++) {
			for (outputPortNumber = 0; outputPortNumber < NUM_PORTS; outputPortNumber++) {

				int queueReadIndex = virtualOutputQueueReadIndex[inputPortNumber][outputPortNumber];
				int queueWriteIndex = virtualOutputQueueWriteIndex[inputPortNumber][outputPortNumber];

				if (queueReadIndex != queueWriteIndex) {
					// Indicates the presence of a packet
					totalRequests++;
					requests[outputPortNumber][inputPortNumber] = TRUE;
				} else {
					// No request to see here...
					requests[outputPortNumber][inputPortNumber] = FALSE;
				}
			}
		}

		// We only need to go through the grant/accept phase if there were requests
		if (totalRequests > 0) {
			cellTimeCounter++;

			// Grant phase
			// ex. grantedRequests[inputPortNumber][outputPortNumber] = TRUE
			int grantedRequests[NUM_PORTS][NUM_PORTS];

			for (outputPortNumber = 0; outputPortNumber < NUM_PORTS; outputPortNumber++) {
				// Initialize granted to FALSE
				for (inputPortNumber = 0; inputPortNumber < NUM_PORTS; inputPortNumber++) {
					grantedRequests[inputPortNumber][outputPortNumber] = FALSE;
				}

				// Start at the priority pointer, look for the first request to grant
				inputPortNumber = outputPortPriorities[outputPortNumber];
				for (i = 0; i < NUM_PORTS; i++) {
					if (requests[outputPortNumber][inputPortNumber]) {
						grantedRequests[inputPortNumber][outputPortNumber] = TRUE;
						break;
					}
					inputPortNumber = (inputPortNumber + 1) % NUM_PORTS;
				}
			}

			// Accept phase
			for (inputPortNumber = 0; inputPortNumber < NUM_PORTS; inputPortNumber++) {
				// Start at the priority pointer, look for the first grant to accept
				outputPortNumber = inputPortPriorities[inputPortNumber];
				for (i = 0; i < NUM_PORTS; i++) {
					if (grantedRequests[inputPortNumber][outputPortNumber]) {
						// Accept! Send the packet over
						int queueReadIndex = virtualOutputQueueReadIndex[inputPortNumber][outputPortNumber];
						packet_t packet = virtualOutputQueues[inputPortNumber][outputPortNumber][queueReadIndex];
						virtualOutputQueueReadIndex[inputPortNumber][outputPortNumber] = (queueReadIndex + 1) % VOQ_SIZE;

						port_lock(&(out_port[outputPortNumber]));

						// If the target out port is free, send the packet to it.
						// Else, add the current packet to the port's buffer.
						if (!out_port[outputPortNumber].flag) {
							out_port[outputPortNumber].packet.address = packet.address;
							out_port[outputPortNumber].packet.payload = packet.payload;
							out_port[outputPortNumber].flag = 1;
						} else {
							// Add the packet to the output buffer to be read later
							int writeIndex = outputBufferWriteIndex[outputPortNumber];
							outputBuffer[outputPortNumber][writeIndex].address = packet.address;
							outputBuffer[outputPortNumber][writeIndex].payload = packet.payload;

							// Bump the write index
							outputBufferWriteIndex[outputPortNumber] = (writeIndex + 1) % OUTPUT_BUFFER_SIZE;
						}

						port_unlock(&(out_port[outputPortNumber]));

						// Update the priority trackers
						inputPortPriorities[inputPortNumber] = (outputPortNumber + 1) % NUM_PORTS;
						outputPortPriorities[outputPortNumber] = (inputPortNumber + 1) % NUM_PORTS;

						// We're done here...
						break;
					}

					// Haven't accepted anything yet, keep on tryin'
					outputPortNumber = (outputPortNumber + 1) % NUM_PORTS;
				}
			}
		}
		
		// Check if the out ports have any pending packets in their buffers
		for (outputPortNumber = 0; outputPortNumber < NUM_PORTS; outputPortNumber++) {
			port_lock(&(out_port[outputPortNumber]));

			// If the output port is free and has packets in its buffer, send them
			int readIndex = outputBufferReadIndex[outputPortNumber];
			int writeIndex = outputBufferWriteIndex[outputPortNumber];

			if (!out_port[outputPortNumber].flag && readIndex != writeIndex) {
				packet_t packet = outputBuffer[outputPortNumber][readIndex];
				out_port[outputPortNumber].packet.address = packet.address;
				out_port[outputPortNumber].packet.payload = packet.payload;
				out_port[outputPortNumber].flag = 1;

				outputBufferReadIndex[outputPortNumber] = (readIndex + 1) % OUTPUT_BUFFER_SIZE;
			}

			port_unlock(&(out_port[outputPortNumber]));
		}
	}
}