void links_load (const char *path) { FILE *file; char buf[256]; /*char path[256]; sprintf (path, "%s/links", canvas->path);*/ file = fopen (path, "r"); if (!file) { g_warning ("unable to open link file %s for reading", path); return; } while (fgets (buf, 256, file)) { Link *link = link_new (); gint src_x, src_y, src_width, src_height; gint dst_x, dst_y, dst_width, dst_height; sscanf (buf, "%i %i %i %i - %i %i %i %i\n", &src_x, &src_y, &src_width, &src_height, &dst_x, &dst_y, &dst_width, &dst_height); link_set_src (link, src_x, src_y, src_width, src_height); link_set_dst (link, dst_x, dst_y, dst_width, dst_height); links_add (link); } fclose (file); //canvas_draw_links (canvas); }
static void tool_link_set_state_link (Label *label, gpointer data) { Tool *tool = data; Easel *easel = tool->easel; View *view = (View*)easel; ToolLink *tool_link = data; Link *link; if (tool_link->src.width == 0) return; link = link_new (); link_set_src (link, tool_link->src.x, tool_link->src.y, tool_link->src.width, tool_link->src.height); link_set_dst (link, tool_link->dst.x, tool_link->dst.y, tool_link->dst.width, tool_link->dst.height); links_add (link); horizon_status (tool->horizon, "Creating link.."); action (tool->horizon, "refresh"); link_redraw (view_get_canvas (view), link); view_set_rect_visible (view, FALSE); tool_link_set_state_dst (NULL, tool); horizon_status (tool->horizon, "Created link."); }
struct page *alloc_pages(struct buddy *node, unsigned int order) { struct page *page; struct buddy_freelist *freelist; struct links *head, *curr; unsigned int i, n; freelist = &node->freelist[order]; page = NULL; unsigned int irqflag; spin_lock_irqsave(&node->lock, irqflag); for (i = order; i < BUDDY_MAX_ORDER; i++, freelist++) { head = &freelist->list; curr = head->next; if (curr == head) continue; page = get_container_of(curr, struct page, list); RESET_PAGE_FLAG(page, PAGE_BUDDY); links_del(curr); freelist->nr_pageblocks--; /* split in half to add one of them to the current order list * if allocating from a higher order */ while (i > order) { freelist--; i--; n = 1U << i; SET_PAGE_FLAG(&page[n], PAGE_BUDDY); SET_PAGE_ORDER(&page[n], i); links_add(&page[n].list, &freelist->list); freelist->nr_pageblocks++; } node->nr_free -= 1 << order; RESET_PAGE_FLAG(page, PAGE_BUDDY); SET_PAGE_ORDER(page, i); break; } spin_unlock_irqrestore(&node->lock, irqflag); return page; }
static void buddy_freelist_init(struct buddy *node, size_t nr_pages, struct page *mem_map) { extern unsigned int _ram_start; unsigned int order, idx, preserved, nr_free, n; /* Preserve the initial kernel stack to be free later, which is located * at the end of memory */ preserved = nr_pages - PAGE_NR(ALIGN_PAGE(STACK_SIZE)); order = mylog2(PAGE_NR(ALIGN_PAGE(STACK_SIZE))); SET_PAGE_ORDER(&mem_map[preserved], order); /* And mark kernel .data and .bss sections as used. * The region of mem_map array as well. */ idx = PAGE_NR(ALIGN_PAGE(&mem_map[nr_pages]) - (unsigned int)&_ram_start); nr_free = preserved - idx; debug(MSG_DEBUG, "The first free page(idx:%d) - %x", idx, &mem_map[nr_pages]); debug(MSG_DEBUG, "The number of free pages %d", nr_free); struct page *page; while (nr_free) { order = min(mylog2(idx), BUDDY_MAX_ORDER - 1); while ((int)(nr_free - (1U << order)) < 0) order--; page = &mem_map[idx]; SET_PAGE_ORDER(page, order); SET_PAGE_FLAG(page, PAGE_BUDDY); links_add(&page->list, &node->freelist[order].list); node->freelist[order].nr_pageblocks++; debug(MSG_DEBUG, "%02d %x added to %x", order, &page->list, &node->freelist[order].list); n = 1U << order; debug(MSG_DEBUG, "%04d: idx %d buddy %d head %d", n, idx, idx ^ n, idx & ~n); idx += n; nr_free -= n; node->nr_free += n; /* total pages being managed by buddy */ debug(MSG_DEBUG, "order %d, nr_free %d, next %d\n", order, nr_free, idx); } }
/** * Performs Dijkstra's shortest path algorithm over the set of links provided. * start_node should probably be local IP, but could be anything. */ void shortest_path_graph( uint32_t start_node, links_t *links, links_t *out ) { queue_t *queue; link_from_t *node; link_to_t *link; queue_init( &queue ); /* Add all nodes to the queue. * All nodes apart from the starting node will be added with some large * value, starting node will be entered with value 0. */ d_queue_init( queue, links, start_node ); while ( queue->length ) { uint32_t z_distance; queue_data_t *data= queue_dequeue( queue ); /* Grab the list of neighbours for this IP */ for (node= links->head; node != NULL; node= node->next_node) { if (node->ip == data->ip) break; } if ( node == NULL ) { return; } /* For each vertex adjacent to u, such that it is in 'queue' */ for (link= node->links; link != NULL; link= link->next_link ) { if ( (z_distance= d_queue_contains( queue, link->ip )) != -1 ) { if (data->distance+link->distance< z_distance){ z_distance= data->distance+link->distance; d_queue_add( queue, link->ip, node->ip, z_distance ); } } } /* Add link to output graph */ links_add( out, data->ip2, data->ip ); link_update( out, data->ip2, data->ip, data->distance ); } queue_destroy( &queue ); }
void free_pages(struct buddy *node, struct page *page) { struct page *buddy, *mem_map; struct buddy_freelist *freelist; unsigned int order, idx, n; unsigned int irqflag; mem_map = node->mem_map; idx = page - mem_map; order = GET_PAGE_ORDER(page); freelist = &node->freelist[order]; n = 1U << order; spin_lock_irqsave(&node->lock, irqflag); node->nr_free += n; while (order < (BUDDY_MAX_ORDER - 1)) { n = 1U << order; buddy = &mem_map[idx ^ n]; if (!is_buddy_free(page, buddy, order)) break; links_del(&buddy->list); freelist->nr_pageblocks--; RESET_PAGE_FLAG(buddy, PAGE_BUDDY); idx &= ~n; /* grab the head of merging buddies */ order++; freelist++; } page = &mem_map[idx]; links_add(&page->list, &freelist->list); freelist->nr_pageblocks++; SET_PAGE_FLAG(page, PAGE_BUDDY); SET_PAGE_ORDER(page, order); spin_unlock_irqrestore(&node->lock, irqflag); }
void link_add( links_t *g, uint32_t from, uint32_t to, uint32_t weight ) { links_add( g, from, to ); link_update( g, from, to, weight ); }