Example #1
0
        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);
            }
        }
Example #2
0
        /// <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);
        }