__init void module_load() { kprintf("module - loading modules", module_count); for(uint32_t i = 0; i < module_count; i++) { kprintf("module - #%u loaded", i + 1); uint32_t num_pages = DIV_UP(modules[i].end - modules[i].start, PAGE_SIZE); void *virt = map_pages(modules[i].start, num_pages); rootramfs_load(virt, modules[i].end - modules[i].start); //TODO unmap pages } uint32_t freed_pages = 0; for(uint32_t i = 0; i < module_count; i++) { uint32_t first_page = DIV_UP(modules[i].start, PAGE_SIZE); uint32_t last_page = DIV_DOWN(modules[i].end, PAGE_SIZE); claim_pages(first_page, last_page - first_page); } kprintf("module - %u pages reclaimed", freed_pages); }
/* * clique_find_all() * * Find all cliques with weight at least min_weight and at most max_weight. * * g - the graph * min_weight - minimum weight of cliques to search for. If min_weight==0, * searches for maximum weight cliques. * max_weight - maximum weight of cliques to search for. If max_weight==0, * no upper limit is used. If min_weight==0, max_weight must * also be 0. * maximal - require cliques to be maximal cliques * opts - time printing and clique storage options * * Returns the number of cliques found. This can be less than the number * of cliques in the graph iff opts->time_function() or opts->user_function() * returns FALSE (request abort). * * The cliques found are stored in opts->clique_list[] and * opts->user_function() is called with them (if non-NULL). The cliques * stored in opts->clique_list[] are newly allocated, and can be freed * by set_free(). * * Note: Automatically uses clique_unweighted_find_all if all vertex * weights are the same. */ int clique_find_all(graph_t *g, int min_weight, int max_weight, boolean maximal, clique_options *opts) { int i,n; int *table; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_weight>=0); ASSERT(max_weight>=0); ASSERT((max_weight==0) || (min_weight <= max_weight)); ASSERT(!((min_weight==0) && (max_weight>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_weight>0) && (min_weight>max_weight)) { /* state was not changed */ entrance_level--; return 0; } if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); if (!graph_weighted(g)) { min_weight=DIV_UP(min_weight,g->weights[0]); if (max_weight) { max_weight=DIV_DOWN(max_weight,g->weights[0]); if (max_weight < min_weight) { /* state was not changed */ entrance_level--; return 0; } } weight_multiplier = g->weights[0]; entrance_level--; i=clique_unweighted_find_all(g,min_weight,max_weight,maximal, opts); ENTRANCE_RESTORE(); return i; } /* Dynamic allocation */ current_clique=set_new(g->n); best_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); memset(clique_size, 0, g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; /* "start clock" */ gettimeofday(&realtimer,NULL); times(&cputimer); /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,TRUE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); /* First phase */ n=weighted_clique_search_single(table,min_weight,INT_MAX,g,opts); if (n==0) { /* Requested clique has not been found. */ goto cleanreturn; } if (min_weight==0) { min_weight=n; max_weight=n; maximal=FALSE; /* They're maximum cliques already. */ } if (max_weight==0) max_weight=INT_MAX; for (i=0; i < g->n; i++) if ((clique_size[table[i]] >= min_weight) || (clique_size[table[i]] == 0)) break; /* Second phase */ n=weighted_clique_search_all(table,i,min_weight,max_weight,maximal, g,opts); cleanreturn: /* Free resources */ for (i=0; i < temp_count; i++) free(temp_list[i]); free(temp_list); free(table); set_free(current_clique); set_free(best_clique); free(clique_size); ENTRANCE_RESTORE(); entrance_level--; return n; }
/* * clique_find_single() * * Returns a clique with weight at least min_weight and at most max_weight. * * g - the graph * min_weight - minimum weight of clique to search for. If min_weight==0, * searches for a maximum weight clique. * max_weight - maximum weight of clique to search for. If max_weight==0, * no upper limit is used. If min_weight==0, max_weight must * also be 0. * maximal - require returned clique to be maximal * opts - time printing options * * Returns the set of vertices forming the clique, or NULL if a clique * of requested weight/maximality does not exist in the graph (or if * opts->time_function() requests abort). * * The returned clique is newly allocated and can be freed by set_free(). * * Note: Does NOT use opts->user_function() or opts->clique_list[]. * Note: Automatically uses clique_unweighted_find_single if all vertex * weights are the same. */ set_t clique_find_single(graph_t *g,int min_weight,int max_weight, boolean maximal, clique_options *opts) { int i; int *table; set_t s; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_weight>=0); ASSERT(max_weight>=0); ASSERT((max_weight==0) || (min_weight <= max_weight)); ASSERT(!((min_weight==0) && (max_weight>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_weight>0) && (min_weight>max_weight)) { /* state was not changed */ entrance_level--; return NULL; } if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); /* Check whether we can use unweighted routines. */ if (!graph_weighted(g)) { min_weight=DIV_UP(min_weight,g->weights[0]); if (max_weight) { max_weight=DIV_DOWN(max_weight,g->weights[0]); if (max_weight < min_weight) { /* state was not changed */ entrance_level--; return NULL; } } weight_multiplier = g->weights[0]; entrance_level--; s=clique_unweighted_find_single(g,min_weight,max_weight, maximal,opts); ENTRANCE_RESTORE(); return s; } /* Dynamic allocation */ current_clique=set_new(g->n); best_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); memset(clique_size, 0, g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; clique_list_count=0; /* "start clock" */ gettimeofday(&realtimer,NULL); times(&cputimer); /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,TRUE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); if (max_weight==0) max_weight=INT_MAX; if (weighted_clique_search_single(table,min_weight,max_weight, g,opts)==0) { /* Requested clique has not been found. */ set_free(best_clique); best_clique=NULL; goto cleanreturn; } if (maximal && (min_weight>0)) { maximalize_clique(best_clique,g); if (graph_subgraph_weight(g,best_clique) > max_weight) { clique_options localopts; localopts.time_function = opts->time_function; localopts.output = opts->output; localopts.user_function = false_function; localopts.clique_list = &best_clique; localopts.clique_list_length = 1; for (i=0; i < g->n-1; i++) if ((clique_size[table[i]] >= min_weight) || (clique_size[table[i]] == 0)) break; if (!weighted_clique_search_all(table,i,min_weight, max_weight,maximal, g,&localopts)) { set_free(best_clique); best_clique=NULL; } } } cleanreturn: s=best_clique; /* Free resources */ for (i=0; i < temp_count; i++) free(temp_list[i]); free(temp_list); temp_list=NULL; temp_count=0; free(table); set_free(current_clique); current_clique=NULL; free(clique_size); clique_size=NULL; ENTRANCE_RESTORE(); entrance_level--; return s; }