예제 #1
0
        /// <summary>
        /// Trae un bloque de memoria o desde otra cache
        /// </summary>
        /// <param name="bloque">Bloque</param>
        /// <param name="controlador">Controlador</param>
        /// <param name="cache">Cache dueña del bloque</param>
        /// <param name="vieneDeMemoria">Indica si viene de memoria (true) o de otra cache (false)</param>
        public static BloqueCacheDatos TraerBloqueCacheDatos(Bloque bloque, Controlador controlador, CacheDatos cache, bool vieneDeMemoria)
        {
            // Se copian los datos del bloque
            BloqueCacheDatos bloqueCache = new BloqueCacheDatos(controlador, cache);

            bloqueCache.id = bloque.ID;
            bloqueCache.direccionInicial       = bloque.Direccion;
            bloqueCache.indiceMemoriaPrincipal = bloque.IndiceMemoriaPrincipal;
            for (int i = 0; i < PalabrasPorBloque; ++i)
            {
                bloqueCache.palabras[i] = bloque[i];
            }

            // Asigna el controlador y la cache
            bloqueCache.controlador = controlador;
            bloqueCache.cache       = cache;

            Debug.Assert(cache.EstaBloqueado());
            Debug.Assert(bloqueCache.Directorio.EstaBloqueado());

            // Se espera que el bloque venga de memoria
            bloqueCache.EsperarTraida(vieneDeMemoria);

            // Se pone el bloque como compartido
            bloqueCache.estado = EstadosB.Compartido;

            // Me pongo en la cache
            cache[bloqueCache.IndiceCache] = bloqueCache;

            // Se refleja el cambio en el directorio
            // Se pone como compartido en el directorio
            bloqueCache.Directorio.AgregarUsuarioBloque(cache, bloqueCache);

            return(bloqueCache);
        }
예제 #2
0
 /// <summary>
 /// Crea los bloques de la memoriaPrincipal memoriaPrincipal.
 /// Se inicializa en ceros
 /// </summary>
 public MemoriaPrincipal(Controlador controlador, int id)
 {
     this.id = id;
     for (int i = 0; i < BloquesPorMemoria; ++i)
     {
         bloques[i] = new Bloque(id, id * BytesPorMemoria + i * BytesPorBloque, i);
     }
 }
예제 #3
0
 /// <summary>
 /// Constrctor por copia para los hijos
 /// </summary>
 /// <param name="bloqueMemoria">Bloque a copiar</param>
 protected Bloque(Bloque bloque)
 {
     this.id = bloque.id;
     this.direccionInicial       = bloque.direccionInicial;
     this.indiceMemoriaPrincipal = bloque.indiceMemoriaPrincipal;
     for (int i = 0; i < PalabrasPorBloque; i++)
     {
         this.palabras[i] = bloque.palabras[i];
     }
 }
예제 #4
0
        /// <summary>
        /// Método que devuelve cuantos usuarios comparten un bloque menos yo
        /// </summary>
        /// <param name="bloqueMemoria">Bloque para obtener el índice de memoria principal</param>
        /// <returns>Lista de Caches que comparten el bloqueMemoria</returns>
        public int CountUsuariosQueComparten(CacheDatos solicitante, Bloque bloque)
        {
            Esperar(solicitante);

            Debug.Assert(EstaBloqueado());

            List <int> tmp = new List <int>(usuarios[bloque.IndiceMemoriaPrincipal]);

            tmp.Remove(solicitante.ID);

            return(tmp.Count);
        }
예제 #5
0
        /// <summary>
        /// Método que devuelve la cache que modificó un bloqueMemoria.
        /// Devuelve null si nadie ha modificado el bloqueMemoria.
        /// </summary>
        /// <param name="solicitante">Solicitante del cambio</param>
        /// <param name="bloqueMemoria">Bloque para obtener el id</param>
        /// <returns>Cache que modificó una palabra del bloqueMemoria</returns>
        public CacheDatos GetUsuarioQueModifica(CacheDatos solicitante, Bloque bloque)
        {
            Esperar(solicitante);

            Debug.Assert(EstaBloqueado());

            CacheDatos cache  = null;
            int        indice = bloque.IndiceMemoriaPrincipal;

            if (estados[indice] == EstadosD.Modificado && usuarios[indice].Count == 1)
            {
                cache = controlador.CachesDatos[usuarios[indice][0]];
            }
            return(cache);
        }
예제 #6
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);
        }
예제 #7
0
 /// <summary>
 /// Actualiza la información del bloque con lo último que se tiene desde memoria principal
 /// </summary>
 public void ActualizarBloque()
 {
     this.bloqueMemoria = controlador.MemoriasPrincipales[id][indiceBloqueMemoria];
 }