/*! * NUR : Retourne le premier bloc free ou celui qui a le plus petit RM */ struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_Block_Header *bloc_NUR = NULL; int min_rm = NULL; /* On cherche d'abord un bloc invalide */ if ((bloc_NUR = Get_Free_Block(pcache)) != NULL) return bloc_NUR; // Pas de bloc libre, on cherche le bloc NUR for (int i = 0; i < pcache->nblocks; ++i) { struct Cache_Block_Header *current = &pcache->headers[i]; // Calcul de rm int rm = evaluate_RM(current); if (0 == rm) return current; else { if (NULL == min_rm || min_rm > rm) { min_rm = rm; bloc_NUR = current; } } } return bloc_NUR; }
/*! * NRU : on parcours les blocs, on prend le premier meilleurs bloc, * dans l'ordre de VALID uniquement, puis MODIF, après B. * Sinon on prend un bloc aleatoire. */ struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_Block_Header *pbh; if ((pbh = Get_Free_Block(pcache)) != NULL){ return pbh; } int min = RANDOM(0, pcache->nblocks); for(int i = 0; i < pcache->nblocks; i++){ if(((pcache->headers)[min].flags & RVM) > ((pcache->headers)[i].flags & RVM)){ min = i; } } #ifdef DEBUG if (((pcache->headers)[min].flags & RVM) == VALID) c1++; else if (((pcache->headers)[min].flags & RVM) == (VALID + MODIF)) c2++; else if (((pcache->headers)[min].flags & RVM) == (VALID + R)) c3++; else c4++; #endif return &(pcache->headers)[min]; }
/** *Invalide le cache, c’est-à-dire met à 0 le bit V de tous les blocs. C’est donc comme si *le cache était vide : aucun bloc ne contient plus d’information utile. **/ Cache_Error Cache_Invalidate(struct Cache *pcache){ for(int i=0; i<pcache->nblocks; i++){ pcache->headers[i].flags &= ~VALID; } pcache->pfree =Get_Free_Block(cache); Strategy_Invalidate(pcache); return CACHE_OK; }
//! Algorithme de remplacement de bloc. // Appel si le cache ne possède plus de block libre struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_List * blocks = (struct Cache_List *) pcache->pstrategy; struct Cache_Block_Header * block = Get_Free_Block(pcache); if(block!=NULL) { Cache_List_Append( blocks, block); return block; } block = Cache_List_Remove_First(blocks); //on le déplace en bout de ligne Cache_List_Append(blocks, block); //return le plus vieux bloc (premier element de la liste pstrategy) return block; }
/*! * LRU : On prend le premier bloc invalide. S'il n'y en a plus, on prend le bloc le moins récemment utilisé. */ struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_Block_Header *pbh; /* On cherche d'abord un bloc invalide */ if ((pbh = Get_Free_Block(pcache)) != NULL) return pbh; if (Cache_List_Is_Empty(pcl)) { perror("vide : pas possible"); exit(1); } pbh = Cache_List_Remove_First(pcl); Cache_List_Append(pcl, pbh); return pbh; }
struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_Block_Header *buffer; struct Cache_List *c_list = C_LIST(pcache); /* S'il existe un cache invalide, on va utiliser celui la */ if ((buffer = Get_Free_Block(pcache)) != NULL) { // Comme on va l'utiliser, on le met en fin de liste Cache_List_Append(c_list, buffer); } else { // On prend le premier de la liste que l'on va retourner buffer = Cache_List_Remove_First(c_list); // Comme on va l'utiliser, on le met en fin de liste Cache_List_Append(c_list, buffer); } return buffer; }
/** *crée une nouvelle cache **/ struct Cache *Cache_Create(const char *fic, unsigned nblocks, unsigned nrecords,size_t recordsz, unsigned nderef){ struct Cache *cache =malloc(sizeof(struct Cache)); //Ouvre le fichier FIC - et le crée si ça n'existe pas encore. if( (file = fopen(fic, "r+b")) == NULL) file = fopen(fic, "w+b"); FILE *file; cache ->fp=file; cache->file= fic; cache->nblocks= nblocks; cache->nrecords=nrecords; cache->blocksz=n*recordsz; cache->ndref= nderef; cache->instrument.n_reads = 0; cache->instrument.n_writes = 0; cache->instrument.n_hits = 0; cache->pstrategy = Strategy_Create(cache); cache->pfree = Get_Free_Block(cache); //1er bloc? cache->headers=create_block(cache); return cache; }
/*! * //! Algorithme de remplacement de bloc. * @author Ulysse Riccio */ struct Cache_Block_Header *Strategy_Replace_Block(struct Cache *pcache) { struct Cache_Block_Header *pbh; struct Cache_List *lru_list = (struct Cache_List *) ( (pcache)->pstrategy ); /* On cherche d'abord un bloc invalide */ if ((pbh = Get_Free_Block(pcache)) != NULL) { /*! Insertion d'un élément à la fin */ // Les blocs invalides a mettre dans la queue Cache_List_Append(lru_list, pbh); return pbh; } /*! Retrait du premier élément */ // Sinon on prend le premier bloc de la liste LRU et on le déplace à la fin pbh = Cache_List_Remove_First(lru_list); /*! Insertion d'un élément à la fin */ Cache_List_Append(lru_list, pbh); return pbh; }