Exemplo n.º 1
0
////////////////////////////////////////////////////////////////////////////////
//
//  Function        : seek_if_i_must
//  Description     : determines whether to seek or not
//
//  Author : Nicholas Krzenski
//  Last Modified : October 8, 2013 
//
void seek_if_i_must(SMSA_DRUM_ID drum, SMSA_BLOCK_ID block) {
    /* Are we there? */
    // Incorrect drum
    if( drum != curDrum) {
        // Seek drum
        smsa_client_operation( SEEK_DRUM, NULL);
        // Update head
        curDrum = drum;
        curBlock = 0;
        logMessage( LOG_INFO_LEVEL, "Seeking drum at [%d]\n", drum );
    }
    // Incorrect block
    if(block != curBlock) {
        // Seek block
        smsa_client_operation( SEEK_BLOCK, NULL);
        // Update head
        curBlock = block;
        logMessage( LOG_INFO_LEVEL, "Seeking block at [%d]\n", block );
    }
}
Exemplo n.º 2
0
int smsa_vunmount( void )  {
	
	uint32_t command;     		 //holds the generated "unmount" command.	
	ERROR_SOURCE err = 0;		 //holds return values of function calls to checkForErrors	


	if ( DEBUG )
		printCache( cache_hits, disk_reads);		

	
	//save the contents of the memory to a file, so that
	//it can be restored when mount is called again, rather
	//than setting it to all zeros. If an error occurs in this 
	//function we will not return a 1 since it is not a catastrophic
	//error, and the virtual memory will still function properly 
	//once mount is called
//	err = saveDiskToFile();

	//generate the op command so that we can use it to call
	//the smsa_operation function to unmount the disk. Once 
	//again, DONT_CARE is defined as 0. After function call
	//command will contain the value neccessary to call
	//smsa_operation in order to unmount the disk
	err = generateOPCommand ( &command, SMSA_UNMOUNT, DONT_CARE, DONT_CARE, DONT_CARE );

	if ( DEBUG )
		logMessage ( LOG_INFO_LEVEL, "Sending UNMOUNT Command Across the Network");

	//call function with the "mount" op command,
	//and NULL set as the parameter for the char*,
	//since we will not use this char* in the mount
	//function
	if ( smsa_client_operation ( command, NULL ) ) {
		logMessage ( LOG_INFO_LEVEL, "_smsa_vunmount:Failed to send UNMOUNT command on the network");
		return 1;
	

	logMessage ( LOG_INFO_LEVEL, "Successfully Unmounted the Disk" );


	//free cache
	if ( smsa_close_cache() )
		logMessage ( LOG_INFO_LEVEL, "_smsa_vunmount:Failed to properly close cache in smsa_close_cache()" );
		return 1;
	}

	
	//if checkForErrors finds that err is non-zero, it will return 1. 
	//see smsa_driver.h for error enum definition
	return ( checkForErrors ( err, "_vumount", DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, 
						DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE ) );
}
Exemplo n.º 3
0
int smsa_vunmount( void )  {
    // Free cache
    smsa_close_cache();

    // Begin unmounting, log an error is unsucessful
    logMessage( LOG_INFO_LEVEL, "Unmounting...\n" );
    if( smsa_client_operation( UNMOUNT_DISK, NULL ) == -1 ) {
        logMessage( LOG_ERROR_LEVEL, "Unmounting disk failed...aborting\n" );
        return -1;
    }
    logMessage( LOG_INFO_LEVEL, "Unmounted successfully!\n" );
    
    return 0;
}
Exemplo n.º 4
0
int smsa_vmount( int lines ) {
    // Initialize cache
    smsa_init_cache(lines);

    logMessage( LOG_INFO_LEVEL, "Mounting...\n" );
    if( smsa_client_operation( MOUNT_DISK, NULL ) == -1 ) {
        logMessage( LOG_ERROR_LEVEL, "Mounting disk failed...aborting\n" );
        return -1;
    }
    logMessage( LOG_INFO_LEVEL, "Mounted successfully!\n" );

    // Initialize global read head
    curDrum = 0;
    curBlock = 0;


    return 0;
}
Exemplo n.º 5
0
////////////////////////////////////////////////////////////////////////////////
//
// Function     : smsa_vmount
// Description  : Mount the SMSA disk array virtual address space
//
// Inputs       : none
// Outputs      : -1 if failure or 0 if successful
int smsa_vmount( int cache_size ) {
	
	uint32_t command;   	 //holds the generated op command
	ERROR_SOURCE err = 0;	 //holds return values of function calls to checkForErrors	
	

	//generate the op command, so that we can use this 
	//command to call the smsa_operation function to mount
	//the disk. DONT_CARE is defined as 0. After function call,
	//command will have the value needed to call the smsa_operation
	//function
	err = generateOPCommand( &command, SMSA_MOUNT, DONT_CARE, DONT_CARE, DONT_CARE );	

	
	if ( DEBUG )
		logMessage ( LOG_INFO_LEVEL, "Calling smsa_client_operation to mount the Disk" );
	
	
	//send the mound command with NULL set as
	//the parameter for the char* since, we will
	//not have to use it.
	if ( smsa_client_operation( command, NULL ) ) {
		logMessage ( LOG_INFO_LEVEL, "_smsa_vmount:smsa_client_operation failed when given the Mount command" );
		return 1;
	}

	
	logMessage ( LOG_INFO_LEVEL, "Disk successfully Mounted. Connection established with server" );

	
	//initialize cache
	if ( smsa_init_cache ( cache_size ) ) {
		logMessage ( LOG_INFO_LEVEL, "_smsa_vmount:Failed to succesfully initialize the cache" );
		return 1;
	}
	

	//Initialize the drum and block head positions to zero
	head.drum = 0;
	head.block = 0;	
	
	if ( DEBUG )
		logMessage ( LOG_INFO_LEVEL, "Block and Drum Head Structure Initalized Drum Head To %d and Block Head To %d", head.drum, head.block );

	//restore the memory that was saved in the txt file,
	//when vunmount finished. This will load the all disk
	//and blocks with the contents of the file. If this function
	//fails, we will not return 1 here and cause the program
	//to fail, because being unable to load the memory from 
	//the file is not a catastrophic error
//	err = restoreDiskFromFile();

	
	//initialize cache performance variables
	cache_hits = 0;
	disk_reads = 0;


	//if checkForErrors finds that err is non-zero, it will return 1. 
	//see smsa_driver.h for error enum definition
	return ( checkForErrors ( err, "_vmount", DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, 
						DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE ) );
}
Exemplo n.º 6
0
int smsa_vwrite( SMSA_VIRTUAL_ADDRESS addr, uint32_t len, unsigned char *buf )  {
    // First check if the length is 0
    // Write nothing and return if so
    if(len == 0) {
        return 0;
    }

    /* Initialize variables */
    int i;
    int err = 0;
    int read_bytes = 0;
    uint32_t offset;
    SMSA_DRUM_ID drum;
    SMSA_BLOCK_ID block;
    SMSA_BLOCK_ID block_orig;
    unsigned char *smsa_vwrite_buffer = NULL;

    drum = find_drum(addr);
    block = find_block(addr);
    block_orig = block;
    offset = addr & 0xff;
    seek_if_i_must(drum, block);
    
    // Loop to iterate through blocks
    do {
        /* Bounds Check */
        // Check if drum is in bounds
        if( (drum > SMSA_DISK_ARRAY_SIZE) || (drum < 0) ) {
            logMessage( LOG_ERROR_LEVEL, "The drum is out of bounds [%d]\n", drum );
            return -1;
        }

        // Check if block is in bounds
        if( (block > SMSA_MAX_BLOCK_ID) || (block < 0) ) {
            logMessage( LOG_ERROR_LEVEL, "The block is out of bounds [%d]\n", block );
            return -1;
        }
        
        // Check if original block
        if( block == block_orig ) {
            i = offset;
        } else { i = 0; }

        // If last block
        if( (block == SMSA_BLOCK_SIZE) ) { 
            block = 0; 
            curBlock = 0;
            drum++;
            seek_if_i_must(drum, block);
        }

        /* Is it in the cache? */
        logMessage(LOG_INFO_LEVEL, "Asking cache at: drum[%d]\tblock[%d]\n", drum, block);
        smsa_vwrite_buffer = smsa_get_cache_line(drum, block);
        // If Yes
        if(smsa_vwrite_buffer != NULL) {
            do {
                smsa_vwrite_buffer[i] = buf[read_bytes];
                read_bytes++;
                i++;
            } while( (i<SMSA_BLOCK_SIZE) && (read_bytes<len) );
            block++;
            curBlock++;
            /* smsa_operation( SEEK_BLOCK, NULL ); */
        }
        // If No
        else {
            smsa_vwrite_buffer = (unsigned char *) malloc(SMSA_BLOCK_SIZE * sizeof(unsigned char));
            // Read from disk
            smsa_client_operation( DISK_READ, smsa_vwrite_buffer);

            // Loop to write into buffer
            do {
                smsa_vwrite_buffer[i] = buf[read_bytes];
                read_bytes++;
                i++;
            } while( (i<SMSA_BLOCK_SIZE) && (read_bytes<len) );

            // Put into cache
            logMessage(LOG_INFO_LEVEL, "Finding a place to put the cache entry...\n");
            err = smsa_put_cache_line(drum, block, smsa_vwrite_buffer);
            block++;
            curBlock++;
        }
        if(err) {
            logMessage(LOG_ERROR_LEVEL, "Something bad happened in the cache :/\n");
            return -1;
        }

        // Write to disk
        smsa_client_operation( SEEK_PREVIOUS_BLOCK, NULL );
        smsa_client_operation( DISK_WRITE, smsa_vwrite_buffer );
    } while(read_bytes<len);

    return 0;
}
Exemplo n.º 7
0
int smsa_vread( SMSA_VIRTUAL_ADDRESS addr, uint32_t len, unsigned char *buf ) {
    /* First check if the length is 0 */
    // Write nothing and return if so
    if(len == 0) {
        return 0;
    }

    /* Initialize variables */
    int i = 0;
    int err = 0;
    int read_bytes = 0;
    uint32_t offset;
    SMSA_DRUM_ID drum;
    SMSA_BLOCK_ID block;
    SMSA_BLOCK_ID block_orig;
    unsigned char *smsa_vread_buffer = NULL;

    drum = find_drum(addr);
    block = find_block(addr);
    block_orig = block;
    offset = addr & 0xff;
    seek_if_i_must(drum, block);

    // Loop to iterate through blocks
    do {
        /* Bounds checking */
         // Check if drum is in bounds
        if( (drum > SMSA_DISK_ARRAY_SIZE) || (drum < 0) ) {
            logMessage( LOG_ERROR_LEVEL, "The drum is out of bounds [%d]\n", drum );
            return -1;
        }

        // Check if block is in bounds
        if( (block > SMSA_MAX_BLOCK_ID) || (block < 0) ) {
            logMessage( LOG_ERROR_LEVEL, "The block is out of bounds [%d]\n", block );
            return -1;
        }

        /* Is it the original block? */
        // Yes  - begin reading from offset
        // No   - begin reading from beginning
        if( block  == block_orig ) {
            i = offset;
        } else { i = 0; }

        /* Is it last block in the drum? */
        if( block == SMSA_BLOCK_SIZE) {
            // Seek to the beginning of next drum
            block=0;
            curBlock = 0;
            drum++;
            seek_if_i_must(drum, block);
        }

        /* Is it in the cache? */
        logMessage(LOG_INFO_LEVEL, "Asking cache at: drum[%d]\tblock[%d]\n", drum, block);
        smsa_vread_buffer = smsa_get_cache_line(drum, block);
        // If yes
        if(smsa_vread_buffer != NULL) {
            // Read into buf
            do {
                buf[read_bytes] = smsa_vread_buffer[i];
                read_bytes++;
                i++;
            } while( (i<SMSA_BLOCK_SIZE) && (read_bytes<len) );
            // seek next block
            block++;
            curBlock++;
            smsa_client_operation( SEEK_BLOCK, NULL );
        }
        // If no
        else {
            // Allocate temp buffer
            smsa_vread_buffer = (unsigned char *) malloc(SMSA_BLOCK_SIZE * sizeof(unsigned char));
            // Read from disk
            smsa_client_operation( DISK_READ, smsa_vread_buffer );
            // Put into buf bit by bit
            do {
                buf[read_bytes] = smsa_vread_buffer[i];
                read_bytes++;
                i++;
            } while( (i<SMSA_BLOCK_SIZE) && (read_bytes<len) );
            // Add temp buffer into cache line
            logMessage(LOG_INFO_LEVEL, "Finding a place to put the cache entry...\n");
            err = smsa_put_cache_line(drum, block, smsa_vread_buffer);
            block++;
            curBlock++;
        }
        if(err) {
            logMessage(LOG_ERROR_LEVEL, "Something bad happened in the cache :/\n");
            return -1;
        }
    } while(read_bytes<len);

    return 0;
}