private void EnviarAMemoriaBloqueVSiModificado(BloqueCacheDatos bloqueV) { if (bloqueV.Estado != EstadosB.Invalido) { Directorio directorioBloqueV = bloqueV.Directorio; // Bloqueo directorio de BloqueV directorioBloqueV.Bloquear(this.Nombre); bloqueados.Add(directorioBloqueV); // Se pregunta si el bloque a reemplazar en mi cache está modificado if (bloqueV.Estado == EstadosB.Modificado) { // Envio el bloque a memoria // Este método modifica tanto la cache como el directorio (U en directorio e I en Cache) bloqueV.EnviarAMemoria(); } else { bloqueV.Invalidar(); } // Desbloqueo el directorio del BloqueV directorioBloqueV.Desbloquear(this.Nombre); bloqueados.Remove(directorioBloqueV); } }
/// <summary> /// Se invalida el bloqueMemoria en todas las cachés que lo usen /// </summary> /// <param name="solicitante">Cache de Datos solicitante</param> /// <param name="bloqueMemoria">Bloque para obtener la dirección</param> public void InvalidarBloque(CacheDatos solicitante, Bloque bloque) { Esperar(solicitante); // Solo se puede invalidar un bloqueMemoria si alguien lo está compartiendo Debug.Assert(EstaBloqueado()); Debug.Assert(estados[bloque.IndiceMemoriaPrincipal] == EstadosD.Compartido); Debug.WriteLine("Cache " + solicitante.ID + ": Invalidando a quienes comparten el bloque " + bloque.Direccion); //Obtengo quienes son las caches que tienen bloqueN compartido List <int> lectores = usuarios[bloque.IndiceMemoriaPrincipal]; // Creo una copia de la lista de lectores sin la cache solicitante // Si es que se encuentra List <int> tmp = new List <int>(lectores); tmp.Remove(solicitante.ID); // TODO Mejorar este código para que reintente sobre las caches // Mientras no falle consecutivamente en todas foreach (int id in tmp) { CacheDatos cache = controlador.CachesDatos[id]; // Bloqueo la cache cache.Bloquear(this.Nombre); BloqueCacheDatos bloqueCache = cache[bloque.IndiceCache]; Debug.Assert(bloqueCache.Direccion == bloque.Direccion); // Invalido el bloque bloqueCache.Invalidar(); // Debloqueo la cache cache.Desbloquear(this.Nombre); } // O no hay nadie compartiendo el bloque o la solicitante es la unica que lo comparte Debug.Assert(lectores.Count == 0 || lectores[0] == solicitante.ID && lectores.Count == 1); }