void kmm_pgfault(struct trapframe *tf) { // uint64_t err = tf->tf_err; uintptr_t addr = rcr2(); if (addr >= PBASE && addr < PBASE + PSIZE) { pgd_t *pgd = KADDR_DIRECT(PTE_ADDR(rcr3())); pud_t *pud; pmd_t *pmd; pte_t *ptd; /* PHYSICAL ADDRRESS ACCESSING */ if (last_pgd != NULL) { pud = KADDR_DIRECT(PGD_ADDR(last_pgd[PGX(last_addr)])); pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)])); ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)])); ptd[PTX(last_addr)] = 0; if (ptd == temp_ptd) { pmd[PUX(last_addr)] = 0; if (pmd == temp_pmd) { pud[PUX(last_addr)] = 0; if (pud == temp_pud) last_pgd[PGX(last_addr)] = 0; } if (last_pgd == pgd) { invlpg((void *)last_addr); } } } if (pgd[PGX(last_addr)] == 0) pgd[PGX(last_addr)] = PADDR_DIRECT(temp_pud) | PTE_W | PTE_P; pud = KADDR_DIRECT(PGD_ADDR(pgd[PGX(last_addr)])); if (pud[PUX(last_addr)] == 0) pud[PUX(last_addr)] = PADDR_DIRECT(temp_pmd) | PTE_W | PTE_P; pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)])); if (pmd[PMX(last_addr)] == 0) pmd[PMX(last_addr)] = PADDR_DIRECT(temp_ptd) | PTE_W | PTE_P; ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)])); ptd[PTX(last_addr)] = PADDR_DIRECT(addr) | PTE_W | PTE_P; last_pgd = pgd; last_addr = addr; /* XXX? */ // invlpg((void *)addr); } }
int set_page_data(struct DataTable *tbl, void *va, data_t id) { int i; pge_t *pge = &(tbl->table)[PGX(va)]; if(! *pge) { pthread_mutex_lock(&tbl->lock); *pge = malloc(sizeof(pue_t) * TBLENTRIES); memset(*pge, 0, sizeof(pue_t) * TBLENTRIES); pthread_mutex_unlock(&tbl->lock); } pue_t *pue = &(*pge)[PUX(va)]; if(! *pue) { pthread_mutex_lock(&tbl->lock); *pue = malloc(sizeof(pme_t) * TBLENTRIES); memset(*pue, 0, sizeof(pme_t) * TBLENTRIES); pthread_mutex_unlock(&tbl->lock); } pme_t *pme = &(*pue)[PMX(va)]; if(! *pme) { pthread_mutex_lock(&tbl->lock); *pme = malloc(sizeof(data_t) * TBLENTRIES); memset(*pme, 0, sizeof(data_t) * TBLENTRIES); pthread_mutex_unlock(&tbl->lock); } DEBUG_LOG("set_page_data of %p from %lu to %lu", va, (*pme)[PTX(va)], id); (*pme)[PTX(va)] = id; return 0; }
pmd_t * get_pmd(pgd_t *pgdir, uintptr_t la, bool create) { #if PMXSHIFT == PUXSHIFT return get_pud(pgdir, la, create); #else /* PMXSHIFT == PUXSHIFT */ pud_t *pudp; if ((pudp = get_pud(pgdir, la, create)) == NULL) { return NULL; } if (! ptep_present(pudp)) { struct Page *page; if (!create || (page = alloc_page()) == NULL) { return NULL; } set_page_ref(page, 1); uintptr_t pa = page2pa(page); memset(KADDR(pa), 0, PGSIZE); ptep_map(pudp, pa); ptep_set_u_write(pudp); ptep_set_accessed(pudp); ptep_set_dirty(pudp); } return &((pmd_t *)KADDR(PUD_ADDR(*pudp)))[PMX(la)]; #endif /* PMXSHIFT == PUXSHIFT */ }
int main(int argc,char ** argv){ int * visitado,otimo; Tour pop[TAMPOP], * melhor; struct tms before,after; if(argc != 3){ printf("USO : %s 'instancia' 'otimo' \n\n",argv[0]); return 1; } otimo = atoi(argv[2]); times(&before); read(argv[1],d,n); visitado = new_int(n); init_int(visitado,n); pop[0] = rand_tour(); pop[1] = rand_tour(); createSet(); LinKernighan(pop[0]); LinKernighan(pop[1]); pop[2] = new_tour(); pop[2]->c = new_int(n); pop[2]->pos = new_int(n); pop[3] = new_tour(); pop[3]->c = new_int(n); pop[3]->pos = new_int(n); PMX(pop[2],pop[3],pop[0],pop[1]); LinKernighan(pop[2]); LinKernighan(pop[3]); printf("PAI 1 : \n"); print_tour(pop[0]); printf("PAI 2 : \n"); print_tour(pop[1]); printf("FILHO 1 : \n"); print_tour(pop[2]); printf("FILHO 2 : \n"); print_tour(pop[3]); melhor = &pop[0]; //print_tour(melhor); times(&after); double tempo = (double)(after.tms_utime - before.tms_utime)/(double)100; double gap = ((double)((*(melhor))->cost-otimo)/(double) otimo) * 100.0; printf("%s\t%.2lfs\t%d\t%d\t%.3lf\n",argv[1],tempo,otimo,(*(melhor))->cost,gap); //printf("System time: %ld seconds\n", after.tms_stime - before.tms_stime); return 0; }
static void exit_range_pmd(pmd_t *pmd) { #if PMXSHIFT == PUXSHIFT /* do nothing */ #else uintptr_t la = 0; do { pmd_t *pmdp = &pmd[PMX(la)]; if (ptep_present(pmdp)) { free_page(pmd2page(*pmdp)), *pmdp = 0; } la += PTSIZE; } while (la != PMSIZE); #endif }
int get_page_data(struct DataTable *tbl, void *va, data_t *id_out) { pge_t *pge = &(tbl->table)[PGX(va)]; if(! *pge) goto get_fault; pue_t *pue = &(*pge)[PUX(va)]; if(! *pue) goto get_fault; pme_t *pme = &(*pue)[PMX(va)]; if(! *pme) goto get_fault; *id_out = (*pme)[PTX(va)]; return 0; get_fault: if (tbl->do_get_faults) return -E_NO_ENTRY; *id_out = 0; return 0; }
static void unmap_range_pmd(pgd_t *pgdir, pmd_t *pmd, uintptr_t base, uintptr_t start, uintptr_t end) { #if PMXSHIFT == PUXSHIFT unmap_range_pte(pgdir, pmd, base, start, end); #else assert(start >= 0 && start < end && end <= PMSIZE); size_t off, size; uintptr_t la = ROUNDDOWN(start, PTSIZE); do { off = start - la, size = PTSIZE - off; if (size > end - start) { size = end - start; } pmd_t *pmdp = &pmd[PMX(la)]; if (ptep_present(pmdp)) { unmap_range_pte(pgdir, KADDR(PMD_ADDR(*pmdp)), base + la, off, off + size); } start += size, la += PTSIZE; } while (start != 0 && start < end); #endif }
pmd_t * get_pmd(pgd_t *pgdir, uintptr_t la, bool create) { #if PMXSHIFT == PUXSHIFT return get_pud(pgdir, la, create); #else /* PMXSHIFT == PUXSHIFT */ pud_t *pudp; if ((pudp = get_pud(pgdir, la, create)) == NULL) { return NULL; } if (!(*pudp & PTE_P)) { struct Page *page; if (!create || (page = alloc_page()) == NULL) { return NULL; } set_page_ref(page, 1); uintptr_t pa = page2pa(page); memset(VADDR_DIRECT(pa), 0, PGSIZE); *pudp = pa | PTE_U | PTE_W | PTE_P; } return &((pmd_t *)VADDR_DIRECT(PUD_ADDR(*pudp)))[PMX(la)]; #endif /* PMXSHIFT == PUXSHIFT */ }
/**Function******************************************************************** Synopsis [Genetic algorithm for DD reordering.] Description [Genetic algorithm for DD reordering. The two children of a crossover will be stored in storedd[popsize] and storedd[popsize+1] --- the last two slots in the storedd array. (This will make comparisons and replacement easy.) Returns 1 in case of success; 0 otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ int cuddGa( DdManager * table /* manager */, int lower /* lowest level to be reordered */, int upper /* highest level to be reorderded */) { int i,n,m; /* dummy/loop vars */ int index; #ifdef DD_STATS double average_fitness; #endif int small; /* index of smallest DD in population */ /* Do an initial sifting to produce at least one reasonable individual. */ if (!cuddSifting(table,lower,upper)) return(0); /* Get the initial values. */ numvars = upper - lower + 1; /* number of variables to be reordered */ if (table->populationSize == 0) { popsize = 3 * numvars; /* population size is 3 times # of vars */ if (popsize > 120) { popsize = 120; /* Maximum population size is 120 */ } } else { popsize = table->populationSize; /* user specified value */ } if (popsize < 4) popsize = 4; /* enforce minimum population size */ /* Allocate population table. */ storedd = ALLOC(int,(popsize+2)*(numvars+1)); if (storedd == NULL) { table->errorCode = CUDD_MEMORY_OUT; return(0); } /* Initialize the computed table. This table is made up of two data ** structures: A hash table with the key given by the order, which says ** if a given order is present in the population; and the repeat ** vector, which says how many copies of a given order are stored in ** the population table. If there are multiple copies of an order, only ** one has a repeat count greater than 1. This copy is the one pointed ** by the computed table. */ repeat = ALLOC(int,popsize); if (repeat == NULL) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); return(0); } for (i = 0; i < popsize; i++) { repeat[i] = 0; } computed = st_init_table(array_compare,array_hash); if (computed == NULL) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); return(0); } /* Copy the current DD and its size to the population table. */ for (i = 0; i < numvars; i++) { STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ } STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ /* Store the initial order in the computed table. */ if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[0]++; /* Insert the reverse order as second element of the population. */ for (i = 0; i < numvars; i++) { STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ } /* Now create the random orders. make_random fills the population ** table with random permutations. The successive loop builds and sifts ** the DDs for the reverse order and each random permutation, and stores ** the results in the computed table. */ if (!make_random(table,lower)) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } for (i = 1; i < popsize; i++) { result = build_dd(table,i,lower,upper); /* build and sift order */ if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { repeat[index]++; } else { if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[i]++; } } #if 0 #ifdef DD_STATS /* Print the initial population. */ (void) fprintf(table->out,"Initial population after sifting\n"); for (m = 0; m < popsize; m++) { for (i = 0; i < numvars; i++) { (void) fprintf(table->out," %2d",STOREDD(m,i)); } (void) fprintf(table->out," : %3d (%d)\n", STOREDD(m,numvars),repeat[m]); } #endif #endif small = find_best(); #ifdef DD_STATS average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Decide how many crossovers should be tried. */ if (table->numberXovers == 0) { cross = 3*numvars; if (cross > 60) { /* do a maximum of 50 crossovers */ cross = 60; } } else { cross = table->numberXovers; /* use user specified value */ } /* Perform the crossovers to get the best order. */ for (m = 0; m < cross; m++) { if (!PMX(table->size)) { /* perform one crossover */ table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } /* The offsprings are left in the last two entries of the ** population table. These are now considered in turn. */ for (i = popsize; i <= popsize+1; i++) { result = build_dd(table,i,lower,upper); /* build and sift child */ if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } large = largest(); /* find the largest DD in population */ /* If the new child is smaller than the largest DD in the current ** population, enter it into the population in place of the ** largest DD. */ if (STOREDD(i,numvars) < STOREDD(large,numvars)) { /* Look up the largest DD in the computed table. ** Decrease its repetition count. If the repetition count ** goes to 0, remove the largest DD from the computed table. */ result = st_lookup_int(computed,(char *)&STOREDD(large,0), &index); if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[index]--; if (repeat[index] == 0) { int *pointer = &STOREDD(index,0); result = st_delete(computed, (char **)&pointer,NULL); if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } } /* Copy the new individual to the entry of the ** population table just made available and update the ** computed table. */ for (n = 0; n <= numvars; n++) { STOREDD(large,n) = STOREDD(i,n); } if (st_lookup_int(computed,(char *)&STOREDD(large,0), &index)) { repeat[index]++; } else { if (st_insert(computed,(char *)&STOREDD(large,0), (char *)(long)large) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[large]++; } } } } /* Find the smallest DD in the population and build it; ** that will be the result. */ small = find_best(); /* Print stats on the final population. */ #ifdef DD_STATS average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Clean up, build the result DD, and return. */ st_free_table(computed); computed = NULL; result = build_dd(table,small,lower,upper); FREE(storedd); FREE(repeat); return(result); } /* end of cuddGa */