/// <summary> /// Método responsável por validar a necessidade de criar novos semáforos de acordo com os novos intervalos, /// ou se apenas deve-se reaproveitar o semáforo existentes. /// </summary> /// <param name="semaforoPorIntervalo">Semáforo que deseja comparar para verificar se há necessidade de criar novos semáforos</param> /// <param name="inicio">ponto mínimo do intervalo atual</param> /// <param name="final">ponto máximo do intervalo atual</param> /// <returns>Lista de semáforos que se deve esperar</returns> public static void VerificarSemaforosImpactados(ref List <SemaforoPorIntervalo> semaforosImpactadosAguardar, ref List <SemaforoPorIntervalo> semaforosImpactadosNovos, ref List <SemaforoPorIntervalo> semaforosExistentes, SemaforoPorIntervalo semaforoPorIntervalo, short inicio, short final) { if (!(inicio <= final)) { return; } //Verifica se o intervalo está contido no intervalo em verificação atual. if (RnVerificarInicioFinalIntervaloEstaContidoEmOutroIntervalo(inicio, final, semaforoPorIntervalo)) { if (RnValidarAdicionarSemaforoParaAguarde(semaforosImpactadosAguardar, semaforosImpactadosNovos, semaforoPorIntervalo)) { SemaforoPorIntervalo.IncrementarContadorSemaforoEmEspera(semaforoPorIntervalo); semaforosImpactadosAguardar.Add(semaforoPorIntervalo); } return; } //verifica se intervalo irá impactar no intervalo já existente //Se não impactar irá querer criar um novo semáforo. if (!(RnVerificarIntervaloImpactara(inicio, final, semaforoPorIntervalo))) { //Verifica se intervalo não irá impactar nos intervalos já existentes ou nos novos intervalos já existentes if (!(RnVerificarIntervaloImpactara(inicio, final, semaforosImpactadosNovos) || RnVerificarIntervaloImpactara(inicio, final, semaforosImpactadosAguardar) || RnVerificarIntervaloImpactara(inicio, final, semaforosExistentes))) { semaforosImpactadosNovos.Add(new SemaforoPorIntervalo(inicio, final, 1)); semaforosExistentes.Add(new SemaforoPorIntervalo(inicio, final, 1)); } } //Se impactar vai adicionar o semáforo atual na lista de aguarde //e verifica onde irá impactar para realizar as validações para então decidir se irá criar outro semáforo ou não. else { if (RnValidarAdicionarSemaforoParaAguarde(semaforosImpactadosAguardar, semaforosImpactadosNovos, semaforoPorIntervalo)) { SemaforoPorIntervalo.IncrementarContadorSemaforoEmEspera(semaforoPorIntervalo); semaforosImpactadosAguardar.Add(semaforoPorIntervalo); } //Verifica se o intervalo incorpora outro intervalo dentro dele (o intervalo que está sendo verificado) if (RnVerificarInicioFinalCobremIntervaloAtual(inicio, final, semaforoPorIntervalo)) { RnConstruirSemaforoQueAbrangeSemaforoAtual(inicio, final, semaforoPorIntervalo, ref semaforosExistentes, ref semaforosImpactadosNovos); } //Se não quer dizer que ou o início ou final estão impactando em algum semáforo. else { RnConstruirSemaforoQueAbrangeInicioOuFinalSemaforoAtual(inicio, final, semaforoPorIntervalo, ref semaforosExistentes, ref semaforosImpactadosNovos); } } }
/// <summary> /// Método responsável por consultar os semáforos que uma determinada thread de reordenação deverá esperar para então executar sua própria reordenação. /// </summary> /// <param name="oidCronograma">Oid do cronograma (índice do dicionário de cronogramas)</param> /// <param name="inicio">Início do intervalo</param> /// <param name="final">Final do intervalo</param> /// <returns>Retorna uma lista contendo os semáforos que deve-se esperar</returns> public Hashtable ConsultarSemaforosImpactadosPorCronograma(Guid oidCronograma, short inicio, short final, Hashtable semaforos) { List <SemaforoPorIntervalo> semaforosImpactadosAguardar = new List <SemaforoPorIntervalo>(); List <SemaforoPorIntervalo> semaforosImpactadosNovos = new List <SemaforoPorIntervalo>(); lock (semaforosPorCronograma[oidCronograma].semaforos) { EsperarLeituraSemaforos(oidCronograma); if (semaforosPorCronograma[oidCronograma].semaforos.Count == 0) { semaforosImpactadosNovos.Add(new SemaforoPorIntervalo(inicio, final)); } else { for (int i = 0; i < semaforosPorCronograma[oidCronograma].semaforos.Count; i++) { SemaforoPorIntervalo.VerificarSemaforosImpactados(ref semaforosImpactadosAguardar, ref semaforosImpactadosNovos, ref semaforosImpactadosNovos, semaforosPorCronograma[oidCronograma].semaforos[i], inicio, final); if (semaforosImpactadosNovos.Count > 0) { if (semaforosImpactadosAguardar.Count > 0) { for (int indice = 0; indice < semaforosImpactadosAguardar.Count; indice++) { SemaforoPorIntervalo.DecrementarContadorSemaforoEmEspera(semaforosImpactadosAguardar[indice]); } } break; } } } LiberarLeituraSemaforos(oidCronograma); if (semaforosImpactadosNovos.Count > 0) { EsperarEscritaSemaforos(oidCronograma); semaforosImpactadosAguardar.Clear(); semaforosImpactadosNovos.Clear(); List <SemaforoPorIntervalo> semaforosExistentes = semaforosPorCronograma[oidCronograma].semaforos; if (semaforosPorCronograma[oidCronograma].semaforos.Count == 0) { SemaforoPorIntervalo novoSemaforo = new SemaforoPorIntervalo(inicio, final); semaforosPorCronograma[oidCronograma].semaforos.Add(novoSemaforo); semaforosImpactadosNovos.Add(novoSemaforo); } else { for (int i = 0; i < semaforosPorCronograma[oidCronograma].semaforos.Count; i++) { if (semaforosPorCronograma[oidCronograma].semaforos[i].semaforo != null) { SemaforoPorIntervalo.IncrementarContadorSemaforoEmEspera(semaforosPorCronograma[oidCronograma].semaforos[i]); SemaforoPorIntervalo.VerificarSemaforosImpactados(ref semaforosImpactadosAguardar, ref semaforosImpactadosNovos, ref semaforosExistentes, semaforosPorCronograma[oidCronograma].semaforos[i], inicio, final); SemaforoPorIntervalo.DecrementarContadorSemaforoEmEspera(semaforosPorCronograma[oidCronograma].semaforos[i]); } else { semaforosPorCronograma[oidCronograma] = new SemaforosControle() { lockerSemaforos = new ReaderWriterLockSlim(), semaforos = new List <SemaforoPorIntervalo>() }; //cria um semáforo SemaforoPorIntervalo novoSemaforo = new SemaforoPorIntervalo(inicio, final); semaforosImpactadosNovos.Add(novoSemaforo); semaforosPorCronograma[oidCronograma].semaforos.Add(novoSemaforo); } } } LiberarEscritaSemaforos(oidCronograma); } } semaforos.Add(SEMAFOROS_AGUARDAR, semaforosImpactadosAguardar); semaforos.Add(SEMAFOROS_NOVOS, semaforosImpactadosNovos); return(semaforos); }