/* deinit allocation manager * Do some check for debug */ void mali_memory_manager_uninit(struct mali_allocation_manager *mgr) { /* check RB tree is empty */ MALI_DEBUG_ASSERT(((void *)(mgr->allocation_mgr_rb.rb_node) == (void *)rb_last(&mgr->allocation_mgr_rb))); /* check allocation List */ MALI_DEBUG_ASSERT(list_empty(&mgr->head)); }
void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence) { struct rb_root *root = self->entries; struct rb_node *nd; switch (whence) { case SEEK_SET: nd = rb_first(root); break; case SEEK_CUR: nd = self->top; break; case SEEK_END: nd = rb_last(root); break; default: return; } if (offset > 0) { while (offset-- != 0) nd = rb_next(nd); } else { while (offset++ != 0) nd = rb_prev(nd); } self->top = nd; }
char *path_for_root(int fd, u64 root) { struct root_lookup root_lookup; struct rb_node *n; char *ret_path = NULL; int ret; ret = __list_subvol_search(fd, &root_lookup); if (ret < 0) return ERR_PTR(ret); ret = __list_subvol_fill_paths(fd, &root_lookup); if (ret < 0) return ERR_PTR(ret); n = rb_last(&root_lookup.root); while (n) { struct root_info *entry; u64 root_id; u64 parent_id; u64 level; char *path; entry = rb_entry(n, struct root_info, rb_node); resolve_root(&root_lookup, entry, &root_id, &parent_id, &level, &path); if (root_id == root) ret_path = path; else free(path); n = rb_prev(n); } return ret_path; }
static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); if (!last) return NULL; return rb_entry(last, struct sched_entity, run_node); }
void map__fixup_end(struct map *map) { struct rb_root *symbols = &map->dso->symbols[map->type]; struct rb_node *nd = rb_last(symbols); if (nd != NULL) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); map->end = sym->end; } }
/** * Get last node in the map. */ static struct tree_node* map_last(const struct map *tmap) { struct rb_node *node; if (!tmap) { return NULL; } node = rb_last(&tmap->root); if (!node) { return NULL; } return container_of(node, struct tree_node, node); }
int list_subvols(int fd, int print_parent) { struct root_lookup root_lookup; struct rb_node *n; int ret; ret = __list_subvol_search(fd, &root_lookup); if (ret) { fprintf(stderr, "ERROR: can't perform the search - %s\n", strerror(errno)); return ret; } /* * now we have an rbtree full of root_info objects, but we need to fill * in their path names within the subvol that is referencing each one. */ ret = __list_subvol_fill_paths(fd, &root_lookup); if (ret < 0) return ret; /* now that we have all the subvol-relative paths filled in, * we have to string the subvols together so that we can get * a path all the way back to the FS root */ n = rb_last(&root_lookup.root); while (n) { struct root_info *entry; u64 root_id; u64 level; u64 parent_id; char *path; entry = rb_entry(n, struct root_info, rb_node); resolve_root(&root_lookup, entry, &root_id, &parent_id, &level, &path); if (print_parent) { printf("ID %llu parent %llu top level %llu path %s\n", (unsigned long long)root_id, (unsigned long long)parent_id, (unsigned long long)level, path); } else { printf("ID %llu top level %llu path %s\n", (unsigned long long)root_id, (unsigned long long)level, path); } free(path); n = rb_prev(n); } return ret; }
static struct rb_node * __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn) { if ((*limit_pfn != iovad->dma_32bit_pfn) || (iovad->cached32_node == NULL)) return rb_last(&iovad->rbroot); else { struct rb_node *prev_node = rb_prev(iovad->cached32_node); struct iova *curr_iova = container_of(iovad->cached32_node, struct iova, node); *limit_pfn = curr_iova->pfn_lo - 1; return prev_node; } }
/* * Get the first inode from the sorted tree, then remove from both. Use * itree_get_inode function to retrieve the inode. Returns 1 if any * errors occurred, otherwise the inode is returned with its refcount * updated. */ int itree_fetch(struct inode_tree *itree, __u8 taskid, int duet_fd, char *path, unsigned long long *uuid, long long *inmem) { int ret = 0; struct rb_node *rbnode; struct itree_node *itnode; *uuid = 0; path[0] = '\0'; again: if (RB_EMPTY_ROOT(&itree->sorted)) return 0; /* Grab last node in the sorted tree, and remove from both trees */ rbnode = rb_last(&itree->sorted); itnode = rb_entry(rbnode, struct itree_node, sorted_node); rb_erase(&itnode->sorted_node, &itree->sorted); rb_erase(&itnode->inodes_node, &itree->inodes); *uuid = itnode->uuid; *inmem = itnode->inmem; free(itnode); itree_dbg("itree: fetch picked uuid %llu, inode %lu\n", *uuid, DUET_UUID_INO(*uuid)); /* Check if we've processed it before */ if (duet_check_done(duet_fd, taskid, *uuid, 1) == 1) goto again; itree_dbg("itree: fetching uuid %llu, inode %lu\n", *uuid, DUET_UUID_INO(*uuid)); /* Get the path for this inode */ if (duet_get_path(duet_fd, taskid, *uuid, path)) { //fprintf(stderr, "itree: inode path not found\n"); goto again; } /* If this isn't a child, mark to avoid, and retry */ if (path[0] == '\0') { //duet_set_done(duet_fd, taskid, *uuid, 1); //itree_dbg("itree: marking uuid %llu, ino %lu for task %u to avoid\n", // *uuid, DUET_UUID_INO(*uuid), taskid); goto again; } return ret; }
rb_node__t* rb_prev(const rb_node__t *node){ if (node == NULL){ return NULL; } rb_node__t* parent = node->parent; if(node->left != NULL) return rb_last(node->left); while(parent != NULL && parent->left == node){ node = parent; parent = node->parent; } return parent; }
/** * find_mean_wl_entry - find wear-leveling entry with medium erase counter. * @ubi: UBI device description object * @root: the RB-tree where to look for * * This function looks for a wear leveling entry with medium erase counter, * but not greater or equivalent than the lowest erase counter plus * %WL_FREE_MAX_DIFF/2. */ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, struct rb_root *root) { struct ubi_wl_entry *e, *first, *last; first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb); if (last->ec - first->ec < WL_FREE_MAX_DIFF) { e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); /* If no fastmap has been written and this WL entry can be used * as anchor PEB, hold it back and return the second best * WL entry such that fastmap can use the anchor PEB later. */ e = may_reserve_for_fm(ubi, e, root); } else
/* No lock taken here as 'root' is not expected to be visible to other * processes. */ static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root) { unsigned int purged = 0; struct rb_node *node; struct ocfs2_meta_cache_item *item; while ((node = rb_last(root)) != NULL) { item = rb_entry(node, struct ocfs2_meta_cache_item, c_node); mlog(0, "Purge item %llu\n", (unsigned long long) item->c_block); rb_erase(&item->c_node, root); kmem_cache_free(ocfs2_uptodate_cachep, item); purged++; } return purged; }
/* Needs the lock */ static void __ocfs2_extent_map_drop(struct inode *inode, u32 new_clusters, struct rb_node **free_head, struct ocfs2_extent_map_entry **tail_ent) { struct rb_node *node, *next; struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map; struct ocfs2_extent_map_entry *ent; *free_head = NULL; ent = NULL; node = rb_last(&em->em_extents); while (node) { next = rb_prev(node); ent = rb_entry(node, struct ocfs2_extent_map_entry, e_node); if (le32_to_cpu(ent->e_rec.e_cpos) < new_clusters) break; rb_erase(&ent->e_node, &em->em_extents); node->rb_right = *free_head; *free_head = node; ent = NULL; node = next; } /* Do we have an entry straddling new_clusters? */ if (tail_ent) { if (ent && ((le32_to_cpu(ent->e_rec.e_cpos) + le32_to_cpu(ent->e_rec.e_clusters)) > new_clusters)) *tail_ent = ent; else *tail_ent = NULL; } }
int main(int argc, char *argv[]) { irb_tree_t irb_tree; irb_node_t *node; unsigned int key; #if 0 for (int i = 0; i < KEY_POOL_CAPS; ++i) { add_key: key = arc4random(); for (int j = i - 1; j >= 0; j--) { if (key == key_pool[j]) { goto add_key; } } key_pool[i] = key; } #else unsigned int j = 0; for (int i = 0; i < KEY_POOL_CAPS; ++i, ++j) { add_key: if (arc4random() % 10 == 0) { ++j; } key_pool[i] = j; } unsigned int a, b; for (int i = 0; i < 30000; ++i) { do { a = arc4random() % KEY_POOL_CAPS; b = arc4random() % KEY_POOL_CAPS; } while (a == b); unsigned int tmp = key_pool[a]; key_pool[a] = key_pool[b]; key_pool[b] = tmp; } #endif printf("Key pool init.\n"); struct timeval rb1,rb2,rb3; irb_tree_init(&irb_tree, data_compare, data_destroy); gettimeofday(&rb1, NULL); for (int i = 0; i < KEY_POOL_CAPS; ++i) { data_node_t *data = (data_node_t *)malloc(sizeof(*data)); data->key = key_pool[i]; irb_insert(&(data->irb_node), &irb_tree); } gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("IRBT INSERT %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); printf("Min:%u\n", irb_entry(irb_first(&irb_tree), data_node_t, irb_node)->key); printf("Max:%u\n", irb_entry(irb_last(&irb_tree), data_node_t, irb_node)->key); gettimeofday(&rb1, NULL); irb_clear(&irb_tree); gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("IRBT CLEAR %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); rb_tree_t rb_tree; rb_tree_init(&rb_tree, data_compare2, data_destroy2); gettimeofday(&rb1, NULL); for (int i = 0; i < KEY_POOL_CAPS; ++i) { unsigned int *data = (unsigned int *)malloc(sizeof(unsigned int)); *data = key_pool[i]; rb_insert(data, &rb_tree); } gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("RBT INSERT %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); printf("Min:%u\n", *(static_cast<unsigned int *>(rb_first(&rb_tree)->data))); printf("Max:%u\n", *(static_cast<unsigned int *>(rb_last(&rb_tree)->data))); gettimeofday(&rb1, NULL); rb_clear(&rb_tree); gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("RBT CLEAR %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); std::set<unsigned int> rb_set; gettimeofday(&rb1, NULL); for (int i = 0; i < KEY_POOL_CAPS; ++i) { rb_set.insert(key_pool[i]); } gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("RBSET INSERT %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); gettimeofday(&rb1, NULL); rb_set.clear(); gettimeofday(&rb2, NULL); timersub(&rb2, &rb1, &rb3); printf("RBSET CLEAR %ld secs, %ld msecs.\n", rb3.tv_sec, rb3.tv_usec); return 0; }
int main(int argc, char *argv[]) { rb_tree_t rb_tree; rb_node_t *node; unsigned int key_pool[KEY_POOL_CAPS]; unsigned int key; for (int i = 0; i < KEY_POOL_CAPS; ++i) { add_key: key = arc4random() % 3000; for (int j = i - 1; j >= 0; j--) { if (key == key_pool[j]) { goto add_key; } } key_pool[i] = key; printf("Add %u into key pool.\n", key_pool[i]); } rb_tree_init(&rb_tree, data_compare, data_destroy); redo: for (int i = 0; i < KEY_POOL_CAPS; ++i) { data_node_t *data = (data_node_t *)malloc(sizeof(*data)); data->key = key_pool[i]; if (rb_insert(&(data->rb_node), &rb_tree)) { printf("Key %u already exist.\n", data->key); } else { printf("Add %u into tree.\n", data->key); } } printf("INIT: ************\n"); printf("Min:%u\n", rb_entry(rb_first(&rb_tree), data_node_t, rb_node)->key); printf("Max:%u\n", rb_entry(rb_last(&rb_tree), data_node_t, rb_node)->key); printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); printf("ERASE: ************\n"); data_node_t search_node; for (int i = 0; i < 5; i++) { unsigned int j = arc4random() % KEY_POOL_CAPS; search_node.key = key_pool[j]; rb_node_t *to_remove = rb_find(&(search_node.rb_node), &rb_tree); if (to_remove) { printf("Remove %u from tree.\n", search_node.key); rb_remove(to_remove, &rb_tree); free(rb_entry(to_remove, data_node_t, rb_node)); } else { printf("Key %u not in tree.\n", search_node.key); } } printf("PRINT: ************\n"); printf("Min:%u\n", rb_entry(rb_first(&rb_tree), data_node_t, rb_node)->key); printf("Max:%u\n", rb_entry(rb_last(&rb_tree), data_node_t, rb_node)->key); printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); rb_clear(&rb_tree); printf("PRINT2: ************\n"); node = rb_first(&rb_tree); if (node) { printf("Min:%u\n", rb_entry(node, data_node_t, rb_node)->key); } node = rb_last(&rb_tree); if (node) { printf("Max:%u\n", rb_entry(node, data_node_t, rb_node)->key); } printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); goto redo; return 0; }
int defrag_file_interactive(struct defrag_ctx *c) { struct rb_node *n = rb_last(&c->free_tree_by_size); struct free_extent *f = rb_entry(n, struct free_extent, size_rb); struct inode *inode; e2_blkcnt_t biggest_size = 0; int ret, num_biggest = 0; ext2_ino_t inode_nr; char improve; print_fragged_inodes(c); if (n) biggest_size = f->end_block - f->start_block + 1; while (n && biggest_size == f->end_block - f->start_block + 1) { num_biggest++; n = rb_prev(n); f = rb_entry(n, struct free_extent, size_rb); } printf("Biggest free space: %llu blocks (%d)\n", biggest_size, num_biggest); do { long number; printf("WARNING: UNTESTED!\n"); printf("Specify inode number.\n"); printf("You can enter -1 for free space consolidation, or 0 to exit.\n"); printf("You can also precede the inode number by an 'i' to improve rather than defragment the file.\n"); printf("Inode number: "); fflush(stdout); number = getchar(); if (number == 'i' || number == 'I') { improve = 1; } else { improve = 0; ungetc(number, stdin); } if (getnumber(&number, -2, c->sb.s_inodes_count) < 0) { switch (errno) { case EDOM: printf("Not a valid number\n"); break; case ERANGE: printf("Inode number out of range\n"); break; default: printf("Error: %s\n", strerror(errno)); return -1; } number = LONG_MIN; } switch (number) { case 0: return 1; case -1: ret = consolidate_free_space(c); if (ret) printf("Error: %s\n", strerror(errno)); if (ret && errno != ENOSPC) return ret; return 0; case -2: ret = 0; while (!ret) ret = consolidate_free_space(c); if (errno == ENOSPC) return 0; return ret; case LONG_MIN: inode_nr = 0; break; default: inode_nr = number; } } while (inode_nr < EXT2_FIRST_INO(&c->sb)); inode = c->inodes[inode_nr]; if (inode == NULL || inode->data->extent_count == 0) { printf("Inode has no data associated\n"); return 0; } if (!improve) ret = do_one_inode(c, inode_nr); else while ((ret = try_improve_inode(c, inode_nr)) > 0); if (ret < 0) printf("Error: %s\n", strerror(errno)); printf("Inode now has %llu fragments\n", c->inodes[inode_nr]->data->extent_count); if (ret && errno != ENOSPC) return ret; else return 0; }