/// <summary> /// Método que realmente se encarga de ejecutar la lógica de leer una palabra. /// Si no puede bloquear algo, tira una excepción del tipo RebootNeededException. /// </summary> /// <param name="info">Información de la palabra que se quiere leer</param> /// <returns>Palabra que se quiere leer</returns> private int Leer(InformacionPalabra info) { int palabraLeida = -1; // Se bloquea la cache this.Bloquear(this.Nombre); bloqueados.Add(this); // Se pregunta si es Hit if (!info.EsHit()) { // Se envia el bloqueV a memoria si está modificado EnviarAMemoriaBloqueVSiModificado(this[info.IndiceCache]); // Bloqueo el directorio que contiene la palabra que busco info.Directorio.Bloquear(this.Nombre); bloqueados.Add(info.Directorio); // Consulto el directorio del bloqueMemoria que contiene la palabra que busco // para ver si alguna cache lo tiene modificado CacheDatos modificante = info.Directorio.GetUsuarioQueModifica(this, info.Bloque); if (modificante == null) { // Traigo el bloqueMemoria de memoria BloqueCacheDatos.TraerBloqueCacheDatos(info.Bloque, controlador, this, true); } else { // Bloqueo la cache que modificó el dato modificante.Bloquear(this.Nombre); bloqueados.Add(modificante); // Se envía el bloque en la cache modificante a memoria modificante[info.IndiceCache].EnviarAMemoria(); // Se actualiza la información del bloque con lo último de memoria info.ActualizarBloque(); // Traigo el dato de la cache modificante BloqueCacheDatos.TraerBloqueCacheDatos(info.Bloque, controlador, this, false); // Desbloqueo la cache que modificó el dato modificante.Desbloquear(this.Nombre); bloqueados.Remove(modificante); } // Desbloqueo el directorio info.Directorio.Desbloquear(this.Nombre); bloqueados.Remove(info.Directorio); } // Leo la palabra palabraLeida = this[info.IndiceCache][info.IndicePalabra]; // Desbloqueo la cache this.Desbloquear(this.Nombre); bloqueados.Remove(this); // Devuelvo la palabra leída return(palabraLeida); }
/// <summary> /// Método que escribe una palabra en una dirección de memoria /// </summary> /// <param name="info">Guarda información de donde debe escribirse la palabra</param> /// <param name="palabra">Palabra que se quiere escribir</param> public void Escribir(InformacionPalabra info, int palabra) { //Se bloquea mi cache this.Bloquear(this.Nombre); bloqueados.Add(this); // Si es hit if (info.EsHit()) { BloqueCacheDatos bloqueN = this[info.IndiceCache]; if (bloqueN.Estado == EstadosB.Modificado) { // Si está en mi cache modificado nada más lo escribo bloqueN[info.IndicePalabra] = palabra; bloqueN.Estado = EstadosB.Modificado; } else { // Si lo tengo compartido, bloqueo el directorio correspondiente info.Directorio.Bloquear(this.Nombre); bloqueados.Add(info.Directorio); // Invalido a todos quienes compartan el bloque info.Directorio.InvalidarBloque(this, info.Bloque); // Escribo la palabra bloqueN[info.IndicePalabra] = palabra; bloqueN.Estado = EstadosB.Modificado; info.Directorio.ModificarBloque(this, bloqueN); // Desbloqueo el directorio info.Directorio.Desbloquear(this.Nombre); bloqueados.Remove(info.Directorio); } } else { // Se envia el bloqueV a memoria si está modificado EnviarAMemoriaBloqueVSiModificado(this[info.IndiceCache]); // Bloqueo el directorio que contiene la palabra que busco info.Directorio.Bloquear(this.Nombre); bloqueados.Add(info.Directorio); // Consulto el directorio del bloqueMemoria que contiene la palabra que busco // para ver si alguna cache lo tiene modificado CacheDatos modificante = info.Directorio.GetUsuarioQueModifica(this, info.Bloque); if (modificante == null) //Si no hay nadie que esté modificando en bloque { if (info.Directorio.CountUsuariosQueComparten(this, info.Bloque) > 0) { //Se les invalida el BloqueN a todas las caches que lo tengan compartido info.Directorio.InvalidarBloque(this, info.Bloque); } // Traigo el bloqueMemoria de memoria // El constructor pone el bloque en la cache BloqueCacheDatos.TraerBloqueCacheDatos(info.Bloque, controlador, this, true); } else { // Bloqueo la cache que modificó el dato modificante.Bloquear(this.Nombre); bloqueados.Add(modificante); // Se envía el bloque en la cache modificante a memoria modificante[info.IndiceCache].EnviarAMemoria(); // Se actualiza la información del bloque info.ActualizarBloque(); // Traigo el dato desde la cache modificante BloqueCacheDatos.TraerBloqueCacheDatos(info.Bloque, controlador, this, false); // Desbloqueo la cache que modificó el dato modificante.Desbloquear(this.Nombre); bloqueados.Remove(modificante); } // Escribo la palabra this[info.IndiceCache][info.IndicePalabra] = palabra; this[info.IndiceCache].Estado = EstadosB.Modificado; this[info.IndiceCache].Directorio.ModificarBloque(this, this[info.IndiceCache]); // Desbloqueo el directorio info.Directorio.Desbloquear(this.Nombre); bloqueados.Remove(info.Directorio); } // Desbloqueo mi cache this.Desbloquear(this.Nombre); bloqueados.Remove(this); }