// Assume new web object is less than MAX_OBJECT_SIZE // Assume new web object is not in the cache already void insert_webobj(cache C, char *URL, char *buf, int len) { // Create a new web_object web_object W = new_webobj(URL, buf, len); // if inserting the new object will exceed MAX_CACHE_SIZE, then // we need to evict LRU web_objects if (C->size + len > MAX_CACHE_SIZE) { // debug: indicate we're deleting items from linked list printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); // Continually evict LRU's until web object will fit into cache while (C->size + len > MAX_CACHE_SIZE) { printf("%%%%%%%%%%%%%%%%\n"); remove_webobj(C, getLRU(C)); } } // debug: indicate we're adding W to the linked list printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); // Adjust the links W->next = C->first; W->prev = C; if (W->next != NULL) W->next->prev = W; C->first = W; // Adjust cache's size C->size += len; }
/* * trySwap - try to swap an fcb */ static void *trySwap( size_t size, int upper_bound, WHO_PTR who ) { void *tmp = NULL; fcb *tfcb; for( ;; ) { /* * find LRU fcb */ tfcb = getLRU( upper_bound ); if( tfcb == NULL ) { break; } /* * swap the LRU fcb, and re-attempt allocation */ SwapFcb( tfcb ); tmp = getMem( size, who ); if( tmp != NULL ) { break; } } return( tmp ); } /* trySwap */
/* * caching_from_server - caching data received from server * * Pamameters: * url: using for matching tag in cache * server_resp: using for store reponse from server */ void caching_from_server(char *url, char *server_resp) { dbg_printf("--------In caching_from_server function ---------\n"); int set_idx = 0; Cache_Set *currSet = &cache.set[set_idx]; Cache_Line *currLine; /* consider eviction */ if (isLineFull) { int idx_lru = getLRU(*currSet, cache.num_lines); currLine = &currSet->line[idx_lru]; } /* there's an empty line, no eviction */ else { int idx_empty_line = getEmptyLine(*currSet, cache.num_lines); if (-1 == idx_empty_line) { printf("Line is full, something wrong\n"); exit(-1); } currLine = &currSet->line[idx_empty_line]; } /* update cache line based on data from server */ strcpy(currLine->tag, url); strcpy(currLine->block, server_resp); dbg_printf("url: %s\n", url); dbg_printf("set->line[idx_lru].tag: %s\n", currLine->tag); if (currLine->v == 0) { currLine->v = 1; } updateLRU(currSet, currLine, cache.num_lines); dbg_printf("--------In caching_from_server function END ---------\n"); }
void FA(Cache modify, size_t addMe){ int index2; modify->memory_access++; long long boff=extract(modify->HMblock,0, addMe); long long tag1=extract(modify->HMtag,modify->HMblock, addMe); for (int j=0;j<modify->numofSet; j++){ if(modify->blocks[j][0].valid==1 && modify->blocks[j][0].tag==tag1){ /*is it the same tag? Hit, update LRU, return*/ if(modify->LRU!=NULL){ SLInsert(modify->LRU, j); modify->hits++; return; } else{ /*do nothing to fifo*/ modify->hits++; return; } } if(modify->blocks[j][0].valid==0){ if(modify->nextLevel!=NULL){ if(strcmp(modify->nextLevel->type, "direct")==0){ direct(modify->nextLevel, addMe); } if((strlen(modify->nextLevel->type)>=7)&&(strncmp(modify->nextLevel->type,"assoc:", 5)==0)){ // printf("I came here"); SA(modify->nextLevel, addMe, modify->nextLevel->assoc); } if((strlen(modify->nextLevel->type)==5)&& (strcmp(modify->nextLevel->type,"assoc")==0)){ FA(modify->nextLevel, addMe); } } modify->cold_misses++; modify->total_misses++; /*updates the queue or DLL*/ if(modify->LRU!=NULL){ SLInsert(modify->LRU, j); } else{ enqueue(modify->FIFO,j); } //printf("%d", j); modify->blocks[j][0].tag=tag1; modify->blocks[j][0].offSet=boff; modify->blocks[j][0].valid=1; // printf("\nj is at %d\n", j); return; } if(modify->blocks[j][0].valid==1 &&modify->blocks[j][0].tag!=tag1 && j==(modify->numofSet-1)){ if(modify->nextLevel!=NULL){ if(strcmp(modify->nextLevel->type, "direct")==0){ direct(modify->nextLevel, addMe); } if((strlen(modify->nextLevel->type)>=7)&&(strncmp(modify->nextLevel->type,"assoc:", 5)==0)){ // printf("I came here"); SA(modify->nextLevel, addMe, modify->nextLevel->assoc); } if((strlen(modify->nextLevel->type)==5)&& (strcmp(modify->nextLevel->type,"assoc")==0)){ FA(modify->nextLevel, addMe); } } // printf("sadI came here %d\n", j); /*it's full. Call LRU*/ modify->total_misses++; if(modify->LRU!=NULL){ index2=getLRU(modify->LRU);} else{ index2=dequeue(modify->FIFO); } // printf("\n num: %d\n", index2); modify->blocks[index2][0].tag=tag1; modify->blocks[index2][0].offSet=boff; if(modify->LRU!=NULL){ SLInsert(modify->LRU, index2); } else{ enqueue(modify->FIFO,index2); } return; } } }
int runTrace (cacheTrace trace) { int index = getIndex (trace.address); int tag = getTag (trace.address); int data = trace.data; int i; int found = 0; int pseudoRandom_victimWay; int PR; if (pseudo_random) { pseudoRandom_victimWay = updatePseudoRandomState(); } for (i=0; i<associativity; i++){ if (cacheLines[index].ways[i].valid && (cacheLines[index].ways[i].tag == tag)){ if (trace.write) { //printf ("Store Hit for Address %d \n", trace.address); updateLRUCnt(index, i); cacheLines[index].ways[i].dirty = 1; found = 1; break; } if (trace.read) { //printf ("Load Hit for Address %d \n", trace.address); updateLRUCnt(index, i); found = 1; break; } } } if (!found) { int LRU = getLRU(index); //Code section to fine a victim for Pseudo random replacement if(pseudo_random) { for(i=0; i<associativity; i++) { if(0 == cacheLines[index].ways[i].valid) { PR = i; break; } } if(i == associativity) { PR = pseudoRandom_victimWay; } //FIXME //This is a hack to reuse below code without change //Better use a variable called victim and assign one of LRU or PR to it LRU = PR; } if (trace.write){ if (cacheLines[index].ways[LRU].valid && (cacheLines[index].ways[LRU].dirty)) { //printf ("Store Miss for Address %d with a Dirty Eviction \n", trace.address); updateLRUCnt(index, LRU); } else { if (cacheLines[index].ways[LRU].valid){ //printf ("Store Miss for Address %d with Eviction \n", trace.address); updateLRUCnt(index, LRU); } else{ //printf ("Store Miss for Address %d \n", trace.address); updateLRUCnt(index, LRU); } } cacheLines[index].ways[LRU].valid = 1; cacheLines[index].ways[LRU].dirty = 1; cacheLines[index].ways[LRU].tag = tag; cacheLines[index].ways[LRU].data = data; } else if (trace.read) { if (cacheLines[index].ways[LRU].valid && (cacheLines[index].ways[LRU].dirty)) { //printf ("Load Miss for Address %d with a Dirty Eviction \n", trace.address); updateLRUCnt(index, LRU); } else { if (cacheLines[index].ways[LRU].valid) { //printf ("Load Miss for Address %d with Eviction \n", trace.address); updateLRUCnt(index, LRU); } else { //printf ("Load Miss for Address %d \n", trace.address); updateLRUCnt(index, LRU); } } cacheLines[index].ways[LRU].valid = 1; cacheLines[index].ways[LRU].dirty = 0; cacheLines[index].ways[LRU].tag = tag; cacheLines[index].ways[LRU].data = data; } } return found; }