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 ) ); }
int main () { int blocksize = 8; int cachesize = 32; int type = 1; Cache* myCache; myCache = createAndInitialize(blocksize, cachesize, type); printCache(myCache); printTagArray(myCache); int i; for (i = 0; i < 64; i++) { accessCache(myCache, i); } printTagArray(myCache); }
int evictLRU ( ) { if ( DEBUG ) logMessage ( LOG_INFO_LEVEL, "Evicting Drum [%d], Block [%d], from Cache at First Index", cache[0].drum, cache[0].block ); // Need to evict the oldest item (index 0), so that // there is room at the end of the cache for a new item // which will be written in the function that calls this one for ( int i = 0; i < currentIndex-1; i++ ) { if ( cache[i].drum == cache[i+1].drum && cache[i].block == cache[i+1].block ) { logMessage( LOG_INFO_LEVEL, "_evictLRU: Error: identical blocks in cache at index %d, and %d. drum = %d, block = %d", i, i+1, cache[i].drum, cache[i].block ); printCache(0,0); assert( !(cache[i].drum == cache[i+1].drum && cache[i].block == cache[i+1].block) ); return 1; } //copy the current line in cache to the line above it cache[i].drum = cache[i+1].drum; cache[i].block = cache[i+1].block; gettimeofday( &cache[i].used, NULL ); cache[i].line = cache[i+1].line; } //if the cache is full the write the last cache line to the //second to last cache line. if ( currentIndex == maxIndex-1 ) { cache[currentIndex-1].drum = cache[currentIndex].drum; cache[currentIndex-1].block = cache[currentIndex].block; cache[currentIndex-1].line = cache[currentIndex].line; } return 0; }
int justUsedAdjust ( SMSA_DRUM_ID drm, SMSA_BLOCK_ID blk, unsigned char *buf, int index ) { if ( DEBUG ) logMessage ( LOG_INFO_LEVEL, "Current Position in Cache [%d], with Drum [%d], Block = [%d]", index, currentIndex, drm, blk); //if it is the newest item in the cache already, then we do not //need to update it's postion if ( index == currentIndex-1 && currentIndex != maxIndex-1 ) return 0; // This loop overwrites every index, with the values one index // ahead of it. This eliminates the object data in index 0 (LRU), and // makes room at the very last index for the newest, soon to be // written item. for ( int i = index; i < currentIndex-1; i++ ) { //if there is a duplicate of a line in the cache, then //the cache has failed, and return an error if ( cache[i].drum == cache[i+1].drum && cache[i].block == cache[i+1].block ) { logMessage( LOG_INFO_LEVEL, "_justUsedAdjust: Error: identical blocks in cache at index %d. drum = %d, block = %d", i, cache[i].drum, cache[i].block ); printCache(0,0); assert(!(cache[i].drum == cache[i+1].drum && cache[i].block == cache[i+1].block)); return 1; } //make the current line equal to the one ahead of it cache[i].drum = cache[i+1].drum; cache[i].block = cache[i+1].block; cache[i].used = cache[i+1].used; cache[i].line = cache[i+1].line; } //After the for loop, we have two conditions. Either the cache //is full, and we need to copy the second to last block to the //last block, and then put our just used block in the currentIndex position. //Or, the cache is not full, and we just need to put our just used block //in the currentIndex-1 position. if ( currentIndex == maxIndex-1 ) { cache[currentIndex-1].drum = cache[currentIndex].drum; cache[currentIndex-1].block = cache[currentIndex].block; cache[currentIndex-1].line = cache[currentIndex].line; cache[currentIndex]. drum = drm; cache[currentIndex].block = blk; gettimeofday( &cache[currentIndex].used, NULL ); cache[currentIndex].line = buf; if ( DEBUG ) logMessage ( LOG_INFO_LEVEL, "New Postion in Cache Ss [%d] Out of [%d] Lines, With Drum [%d] and Block [%d]", currentIndex, maxIndex-1, cache[currentIndex].drum, cache[currentIndex].block ); } else { //place the item to be written at the newest point in the cache cache[currentIndex-1]. drum = drm; cache[currentIndex-1].block = blk; gettimeofday( &cache[currentIndex-1].used, NULL ); cache[currentIndex-1].line = buf; if ( DEBUG ) logMessage ( LOG_INFO_LEVEL, "New Postion In Cache is [%d] Out of [%d] Lines, With Drum [%d] and Block [%d]", currentIndex-1, maxIndex-1, cache[currentIndex-1].drum, cache[currentIndex-1].block ); } if ( currentIndex == 0 ) currentIndex++; return 0; }
int main(int argc, char *argv[]){ cache_params_t params; /* file handling stuff */ FILE *tracefile; char instruction_ptr[50]; char instruction; char mem_addr[50]; int count; char *traceData; Cache_t cache; int tagSize, setSize, offsetSize; if(argc == 2 && strcmp(argv[1], "-h") == 0){ printf("help menu\n"); return 1; } if(argc < 2 || argc > 6){ printf("ERROR: incorrect number of arguments\n"); return 1; } /* * TODO: * Check cachesize = numsets x setsize x blocksize */ /* Check if cachesize here and correct*/ /* should check that these are numbers as well */ if(isPowerOfTwo(atoi(argv[1]))){ params.cachesize = atoi(argv[1]); }else{ printf("ERROR: cachesize must be a power of 2\n"); return 1; } /* check if blocksize is here and correct */ if(isPowerOfTwo(atoi(argv[3]))){ params.blocksize = atoi(argv[3]); }else{ printf("ERROR: blocksize must be a power of 2\n"); return 1; } params.setsize = 1; /* check for associativit y */ if(strcmp("direct", argv[2]) == 0){ params.associativity = "direct"; }else if( strcmp("assoc", argv[2]) == 0){ params.associativity = "assoc"; }else{ int i = 0, digit = 0; char* str = argv[2]; char* test; while(str[i] != '\0'){ if(isdigit(str[i])){ digit = i; break; } i++; } /* * setsize = 1 for d-m caches */ params.setsize = 1; test = malloc(strlen(argv[2])); strncpy(test, argv[2], digit); if(strcmp("assoc:", test) == 0){ params.associativity = "n-way"; if(isPowerOfTwo( argv[2][digit] - '0')){ params.setsize = argv[2][digit] - '0'; }else{ printf("ERROR: n must be power of 2\n"); return 1; } }else{ printf("ERROR: invalid associativity format\n"); return 1; } } /* check for writepolicy*/ if(strcmp("wt", argv[4]) == 0){ params.writepolicy = "wt"; }else if(strcmp("wb", argv[4]) == 0){ params.writepolicy = "wb"; }else{ printf("ERROR: invalid writepolicy format\n"); return 1; } /* check for tracefile */ if(!(tracefile = fopen(argv[5], "r"))){ printf("ERROR: could not find tracefile: %s\n", argv[5]); return 1; }else{ traceData = readFile(argv[5]); } /* <<<<<<< HEAD * create the new cache, do initialization stuff ======= * create the new cache, do initializatino stuff >>>>>>> 59f4c294c92c026c0d9d15ccfd2984234f2a3158 */ cache = *newCache(params.cachesize, params.blocksize, params.setsize, params.associativity, params.writepolicy); /* * read each line of the tracefile * * DIRECT MAP ONLY RIGHT NOW */ count = 0; while(fscanf(tracefile, "%s %c %s", instruction_ptr, &instruction, mem_addr) == 3) { int tag_size; int lines; int offset_size; int set_size; int set_lines; unsigned int addr_int; char *addr_bin; char *formatted_bin; char *tag; char *setid; char *offset; formatted_bin = (char*) malloc(sizeof(char) * 35); addr_bin = (char*) malloc(sizeof(char) * 33); lines = (int)(params.cachesize / params.blocksize); set_lines = (int)(params.cachesize / (params.blocksize * params.setsize)); if(strcmp(params.associativity,"n-way") == 0){ set_size = (int) ceil((log10(set_lines)/log10(2.0))); }else{ set_size = (int) ceil((log10(lines)/log10(2.0))); } offset_size = ceil((log10(params.blocksize)/log10(2.0))); tag_size = (32 - (offset_size+set_size)); /* * just for output */ tagSize = tag_size; setSize = set_size; offsetSize = offset_size; tag = (char*) malloc(sizeof(char)*tag_size+1); setid = (char*) malloc(sizeof(char)*set_size+1); offset = (char*) malloc(sizeof(char)*offset_size+1); addr_int = htoi(mem_addr); addr_bin = itob(addr_int); memcpy(tag, &addr_bin[0], tag_size); tag[tag_size+1] = '\0'; memcpy(setid, &addr_bin[tag_size], set_size); setid[set_size+1] = '\0'; memcpy(offset, &addr_bin[(tag_size+set_size)], offset_size); offset[offset_size+1] = '\0'; if(DEBUG) { printf("------\n%s\n",mem_addr); printf("%s %s %s \n", tag, setid, offset); printf("tag: %i, set: %i, offset: %i\n", tagSize, setSize, offsetSize); } /* * Write to the cache */ if('W' == instruction){ if(DEBUG){ printf("Write instruction\n Cache State:\n"); printCache(&cache); if( isInCache(&cache, addr_bin, tag, setid, offset)){ printf("\ncache already contains %s\n",mem_addr); }else{ printf("\ncache does not contain %s\n",mem_addr); } if( isInCache(&cache, addr_bin, tag, setid, offset)){ printf("\ncache contains %s\n",mem_addr); } printf("\nCache State:\n"); printCache(&cache); } writeToCache(&cache, addr_bin, tag, setid, offset, lines); /* * Read from the cache */ }else if('R' == instruction ){ if(DEBUG) { printf("Read instruction\n Cache State:\n"); printCache(&cache); if( isInCache(&cache, addr_bin, tag, setid, offset)){ printf("\ncache already contains %s\n",mem_addr); }else{ printf("\ncache does not contain %s\n",mem_addr); } if( isInCache(&cache, addr_bin, tag, setid, offset)){ printf("\ncache contains %s\n",mem_addr); } printf("\nCache State:\n"); printCache(&cache); } readFromCache(&cache, addr_bin, tag, setid, offset, lines); } count++; } printCache(&cache); return 1; }