int main(int argc, char **argv) { while (1) { char tecla; int i; u16 *vga; MemoryMessage mem; /* Request VGA memory. */ mem.action = CreatePrivate; mem.bytes = PAGESIZE; mem.virtualAddress = ZERO; mem.physicalAddress = VGA_PADDR; mem.protection = PAGE_RW | PAGE_PINNED; mem.ipc(MEMSRV_PID, SendReceive, sizeof(mem)); /* Point to the VGA mapping. */ vga = (u16 *) mem.virtualAddress; for (i=0; i < 36; i++) { vga[i] = VGA_CHAR(' ', GREEN, GREEN); } vga[36] = VGA_CHAR('A', BLACK, GREEN); vga[37] = VGA_CHAR('m', BLACK, GREEN); vga[38] = VGA_CHAR('a', BLACK, GREEN); vga[39] = VGA_CHAR('y', BLACK, GREEN); vga[40] = VGA_CHAR('a', BLACK, GREEN); vga[41] = VGA_CHAR('O', BLACK, GREEN); vga[42] = VGA_CHAR('S', BLACK, GREEN); for (i=43; i < 80; i++) { vga[i] = VGA_CHAR(' ', GREEN, GREEN); } for (i=80; i < 1920; i++) { vga[i] = VGA_CHAR(' ', WHITE, WHITE); } vga[1920] = VGA_CHAR(' ', BROWN, BROWN); vga[1921] = VGA_CHAR('M', BLUE, BROWN); vga[1922] = VGA_CHAR('e', BLUE, BROWN); vga[1923] = VGA_CHAR('n', BLUE, BROWN); vga[1924] = VGA_CHAR('u', BLUE, BROWN); vga[1925] = VGA_CHAR('(', BLUE, BROWN); vga[1926] = VGA_CHAR('M', BLUE, BROWN); vga[1927] = VGA_CHAR(')', BLUE, BROWN); for (i=1928; i <= 2000; i++) { vga[i] = VGA_CHAR(' ', BROWN, BROWN); } memoria(); do { tecla = getchar(); } while (tecla != 'M'&& tecla != 'm'); if (tecla == 'M'|| tecla == 'm') { if (menu() == -1) { char clean[] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x4a, '\0'}; printf("%s", clean); return 0; } } } }
std::pair<int, int> simulacion(int bloques, int bloque_size, int vias, int accesos, int pagina_size) { int paginas_disco, paginas_mem, fallos_pagina, fallos_cache, bits_offset, div_virt, div_fisica; std::cout << "Numero de bloques: " << bloques << std::endl; std::cout << "Tamano de bloque: " << bloque_size << std::endl; std::cout << "Numero de vias: " << vias << std::endl; std::cout << "Numero de accesos: " << accesos << std::endl; std::cout << "Tamanio de pagina: " << pagina_size << std::endl; std::cout << "Inicializando..."; std::random_device rseed; // Para numeros aleatorios std::mt19937 rgen(rseed()); // mersenne_twister std::uniform_int_distribution<int> idist(0, DIR_VIRUTALES - 1); // [0,4095] std::uniform_int_distribution<int> odist(0, 1); // [0,1] std::uniform_int_distribution<int> ddist(0, 255); // [0,255] std::uniform_int_distribution<int> nueva_dist(256, 511); // [0,255] /* ins_virtuales[*][x], x: 0 - direccion, 1 - lectura/escritura, 2 - dato */ std::vector<std::vector<int> > ins_virtuales (accesos, std::vector<int> (3,0)); std::vector<int> memoria (POS_MEMORIA); std::vector<int> disco (POS_DISCO); t_tabla tabla; /* Creamos la cache */ Cache mem_cache (vias, bloques, bloque_size); /* Inicializacion */ paginas_disco = POS_DISCO / pagina_size; paginas_mem = POS_MEMORIA / pagina_size; std::uniform_int_distribution<int> mdist(0, paginas_mem-1); // [0,paginas_memoria] fallos_pagina = 0; fallos_cache = 0; bits_offset = bits_para(pagina_size); div_virt = potencia(bits_offset);// para posterior division div_fisica = potencia(bits_para(bloque_size));// para posterior division std::cout << " Inicializacion terminada!" << std::endl; std::cout << "Paginas Memoria: " << paginas_mem << std::endl; std::cout << "Paginas Disco: " << paginas_disco << std::endl; std::cout << "Generando instrucciones..." << std::endl; /* Generar instrucciones virtuales */ for (int i = 0; i < accesos; ++i) { ins_virtuales[i][0] = idist(rgen); ins_virtuales[i][1] = odist(rgen); ins_virtuales[i][2] = nueva_dist(rgen); } std::cout << " Terminado!" << std::endl; std::cout << "Generando tabla de traduccion..." << std::endl; /* Generamos la tabla de traduccion */ int contador; for (contador = 0; contador < accesos; ++contador) { int tmp = ins_virtuales[contador][0]/div_virt; if(tabla.size() > paginas_mem) break; if(tabla.count(tmp) == 0) { tabla[tmp].push_back(odist(rgen)); /* 1 - memoria principal */ tabla[tmp].push_back(0); /* 1 - dato en disco mem llena */ tabla[tmp].push_back(contador); /* dir fisica */ } } for (; contador < accesos; ++contador) { int tmp = ins_virtuales[contador][0]/div_virt; if(tabla.size() >= (paginas_mem + paginas_disco)) break; if(tabla.count(tmp) == 0) { tabla[tmp].push_back(0); /* 1 - memoria principal */ tabla[tmp].push_back(1); /* 1 - dato en disco mem llena */ tabla[tmp].push_back(contador); /* dir disco */ } } std::cout << " Terminado!" << std::endl; std::cout << " Tamaño tabla: " << tabla.size() << std::endl; /* leemos la memoria y el disco */ std::ifstream inputmem; std::ifstream inputdisc; std::string outmem; std::string outdisc; int valor_io; int contador_io = 0; std::cout << "Leyendo memoria..." << std::endl; inputmem.open("memoria.txt", std::ifstream::in); while(inputmem >> valor_io) { memoria[contador_io] = valor_io; contador_io++; } inputmem.close(); std::cout << " Terminado!" << std::endl; if (contador_io == 0) { std::cout << "Memoria vacia, abortando!" << std::endl; return std::make_pair(0,0); } std::cout << "Leyendo disco..." << std::endl; inputdisc.open("disco.txt", std::ifstream::in); contador_io = 0; while(inputdisc >> valor_io) { disco[contador_io] = valor_io; contador_io++; } inputdisc.close(); std::cout << " Terminado!" << std::endl; if (contador_io == 0) { std::cout << "Disco vacio, abortando!" << std::endl; return std::make_pair(0,0); } std::cout << "Procesando instrucciones..." << std::endl; /* Iteramos en cada instruccion */ int dir_fisica, tmp, tmp2; std::vector<int> movimiento (bloque_size,0); std::vector<int> respuesta_cache; for (int i = 0; i < accesos; ++i) { /* Traducimos direccion virtual a fisica */ dir_fisica = ins_virtuales[i][0]/div_virt; /* No esta en memoria principal? */ if(tabla[dir_fisica][0] == 0) { //std::cout << "Fallo Pagina!" << std::endl; tabla[dir_fisica][0] = 1; fallos_pagina++; // nuevo fallo de pagina tmp2 = tabla[dir_fisica][2]; // direccion disco /* no esta asigana? */ if(tabla[dir_fisica][1] == 1) { tabla[dir_fisica][1] = 0; tmp = mdist(rgen); // nueva asignacion. tabla[dir_fisica][2] = tmp; /* Movemos de disco a memoria */ } else tmp = tmp2; // Si esta asignada disco - memoria concuerdan. tmp = tmp * div_virt; tmp2 = tmp2 * div_virt; for(int j = 0; j < pagina_size; ++j) { memoria[tmp + j] = disco[tmp2 + j]; } } /* El dato ya esta en memoria principal */ /* Extraemos direccion fisica */ dir_fisica = tabla[dir_fisica][2] * div_virt; /* Agregamos el offset */ dir_fisica = dir_fisica + (ins_virtuales[i][0] % div_virt); /* Cargamos los datos que hay en la memoria por si hay un miss en cache */ tmp = dir_fisica - (dir_fisica % div_fisica); // quitamos el offset de un bloque. for (int j = 0; j < bloque_size; ++j) { movimiento[j] = memoria[tmp + j]; } /* Lectura o escritura */ if (ins_virtuales[i][1] == 0) { //std::cout << "Read" << std::endl; respuesta_cache = mem_cache.read_cache(dir_fisica, movimiento); } else { //::cout << "Write" << std::endl; respuesta_cache = mem_cache.write_cache(dir_fisica, movimiento, ins_virtuales[i][2]); } /* Analimamos la respuesta de la cache */ /* no fue un hit? */ if(respuesta_cache[0] != 1) fallos_cache++; /* hay que escribir en memoria, por write-back? */ if (respuesta_cache[1] == 1) { //std::cout << "write-back" << std::endl; tmp = respuesta_cache[2]; // donde, escribir tmp = tmp - (tmp % div_fisica); // quitamos el offset del bloque. for (int j = 0; j < bloque_size; ++j) { memoria[tmp + j] = respuesta_cache[3+j]; } } } std::cout << " Terminado!" << std::endl; std::cout << "Reescribiendo memoria..." << std::endl; /* Excribimos en los archivos */ std::ofstream ofm ("memoria.txt", std::ofstream::out); for (int i = 0; i < POS_MEMORIA; ++i) { ofm << memoria[i] << "\n"; } ofm.close(); std::cout << "Terminado!" << std::endl; std::cout << "Reescribiendo disco..." << std::endl; std::ofstream ofd ("disco.txt", std::ofstream::out); for (int i = 0; i < POS_DISCO; ++i) { ofd << disco[i] << "\n"; } ofd.close(); std::cout << "Terminado!" << std::endl; std::cout << fallos_pagina << " " << fallos_cache << std::endl; return std::make_pair(fallos_pagina, fallos_cache); }
int menu() { char tecla; int i; u16 *vga; MemoryMessage mem; /* Request VGA memory. */ mem.action = CreatePrivate; mem.bytes = PAGESIZE; mem.virtualAddress = ZERO; mem.physicalAddress = VGA_PADDR; mem.protection = PAGE_RW | PAGE_PINNED; mem.ipc(MEMSRV_PID, SendReceive, sizeof(mem)); /* Point to the VGA mapping. */ vga = (u16 *) mem.virtualAddress; for (i=0; i < 36; i++) { vga[i] = VGA_CHAR(' ', GREEN, GREEN); } vga[36] = VGA_CHAR('A', BLACK, GREEN); vga[37] = VGA_CHAR('m', BLACK, GREEN); vga[38] = VGA_CHAR('a', BLACK, GREEN); vga[39] = VGA_CHAR('y', BLACK, GREEN); vga[40] = VGA_CHAR('a', BLACK, GREEN); vga[41] = VGA_CHAR('O', BLACK, GREEN); vga[42] = VGA_CHAR('S', BLACK, GREEN); for (i=43; i < 80; i++) { vga[i] = VGA_CHAR(' ', GREEN, GREEN); } for (i=80; i < 1680; i++) { vga[i] = VGA_CHAR(' ', WHITE, WHITE); } vga[1520] = VGA_CHAR('A', BLUE, BROWN); vga[1521] = VGA_CHAR('m', BLUE, BROWN); vga[1522] = VGA_CHAR('a', BLUE, BROWN); vga[1523] = VGA_CHAR('C', BLUE, BROWN); vga[1524] = VGA_CHAR('A', BLUE, BROWN); vga[1525] = VGA_CHAR('L', BLUE, BROWN); vga[1526] = VGA_CHAR('C', BLUE, BROWN); vga[1527] = VGA_CHAR(' ', BLUE, BROWN); vga[1528] = VGA_CHAR('(', BLUE, BROWN); vga[1529] = VGA_CHAR('A', BLUE, BROWN); vga[1530] = VGA_CHAR(')', BLUE, BROWN); vga[1531] = VGA_CHAR(' ', BLUE, BROWN); vga[1600] = VGA_CHAR('H', BLUE, BROWN); vga[1601] = VGA_CHAR('a', BLUE, BROWN); vga[1602] = VGA_CHAR('n', BLUE, BROWN); vga[1603] = VGA_CHAR('g', BLUE, BROWN); vga[1604] = VGA_CHAR('m', BLUE, BROWN); vga[1605] = VGA_CHAR('a', BLUE, BROWN); vga[1606] = VGA_CHAR('n', BLUE, BROWN); vga[1607] = VGA_CHAR(' ', BLUE, BROWN); vga[1608] = VGA_CHAR('(', BLUE, BROWN); vga[1609] = VGA_CHAR('H', BLUE, BROWN); vga[1610] = VGA_CHAR(')', BLUE, BROWN); vga[1611] = VGA_CHAR(' ', BLUE, BROWN); vga[1680] = VGA_CHAR('W', BLUE, BROWN); vga[1681] = VGA_CHAR('a', BLUE, BROWN); vga[1682] = VGA_CHAR('m', BLUE, BROWN); vga[1683] = VGA_CHAR('a', BLUE, BROWN); vga[1684] = VGA_CHAR('/', BLUE, BROWN); vga[1685] = VGA_CHAR('W', BLUE, BROWN); vga[1686] = VGA_CHAR('A', BLUE, BROWN); vga[1687] = VGA_CHAR('+', BLUE, BROWN); vga[1688] = VGA_CHAR('(', BLUE, BROWN); vga[1689] = VGA_CHAR('W', BLUE, BROWN); vga[1690] = VGA_CHAR(')', BLUE, BROWN); vga[1691] = VGA_CHAR(' ', BLUE, BROWN); for (i=1692; i < 1760; i++) { vga[i] = VGA_CHAR(' ', WHITE, WHITE); } vga[1760] = VGA_CHAR('R', BLUE, BROWN); vga[1761] = VGA_CHAR('e', BLUE, BROWN); vga[1762] = VGA_CHAR('i', BLUE, BROWN); vga[1763] = VGA_CHAR('n', BLUE, BROWN); vga[1764] = VGA_CHAR('i', BLUE, BROWN); vga[1765] = VGA_CHAR('c', BLUE, BROWN); vga[1766] = VGA_CHAR('i', BLUE, BROWN); vga[1767] = VGA_CHAR('a', BLUE, BROWN); vga[1768] = VGA_CHAR('r', BLUE, BROWN); vga[1769] = VGA_CHAR('(', BLUE, BROWN); vga[1770] = VGA_CHAR('R', BLUE, BROWN); vga[1771] = VGA_CHAR(')', BLUE, BROWN); for (i=1772; i < 1840; i++) { vga[i] = VGA_CHAR(' ', WHITE, WHITE); } vga[1840] = VGA_CHAR('S', BLUE, BROWN); vga[1841] = VGA_CHAR('h', BLUE, BROWN); vga[1842] = VGA_CHAR('e', BLUE, BROWN); vga[1843] = VGA_CHAR('l', BLUE, BROWN); vga[1844] = VGA_CHAR('l', BLUE, BROWN); vga[1845] = VGA_CHAR('(', BLUE, BROWN); vga[1846] = VGA_CHAR('S', BLUE, BROWN); vga[1847] = VGA_CHAR(')', BLUE, BROWN); vga[1848] = VGA_CHAR(' ', BLUE, BROWN); vga[1849] = VGA_CHAR(' ', BLUE, BROWN); vga[1850] = VGA_CHAR(' ', BLUE, BROWN); vga[1851] = VGA_CHAR(' ', BLUE, BROWN); memoria(); do { tecla = getchar(); } while (tecla != 'R'&& tecla != 'r'&& tecla != 'S'&& tecla != 's'&& 'M'&& tecla != 'm'&& tecla != 'W'&& tecla != 'w' &&tecla != 'H'&& tecla != 'h' &&tecla != 'A'&& tecla != 'a'); if (tecla == 'M'|| tecla == 'm') { return 0; } if (tecla == 'R'|| tecla == 'r') { return PrivExec(Reboot); } if (tecla == 'S'|| tecla == 's') { return -1; } if (tecla == 'W'|| tecla == 'w') { wama(); } /* if (tecla == 'P'|| tecla == 'p') { game(); } */ if (tecla == 'H'|| tecla == 'h') { hangman(); } if (tecla == 'A'|| tecla == 'a') { ama_calc(); } return 0; }