Point point_max(void) { Point pt; pt.p = list_prev(cur_bp->lines); pt.n = cur_bp->num_lines; pt.o = astr_len(list_prev(cur_bp->lines)->item); return pt; }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); list_entry_t *le = &free_list; struct Page * p; while (p <= base && (le = list_next(le)) != &free_list) p = le2page(le, page_link); for(p=base;p<base+n;p++) { list_add_before(le, &(p->page_link)); p->flags = 0; set_page_ref(p, 0); } base->flags = 0; set_page_ref(base, 0); ClearPageProperty(base); SetPageProperty(base); base->property = n; while (1) { p = le2page(le, page_link); if (base->page_link.next != &free_list && base+base->property==p) { base->property += p->property; p->property = 0; } else break; } le = list_prev(&(base->page_link)); p = le2page(le, page_link); if(le != &free_list && p == base-1) { while (1) { if (p->property) { p->property += base->property; base->property = 0; break; } if (le != &free_list) { le = list_prev(le); p = le2page(le,page_link); } else break; } } nr_free += n; }
//static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); assert(PageReserved(base)); //遍历空闲块链表,找到合适的位置插入回收的地址块 list_entry_t *le = &free_list; struct Page *page = NULL; //寻找第一个空闲块 while ((le = list_next(le)) != &free_list) { page = le2page(le, page_link); if (page > base) { break; } } //插入回收的空闲块:按页插入 for (page=base; page<(base+n); page++) { list_add_before(le, &(page->page_link)); } //重置该块的字段 base->flags = 0; base->property = n; set_page_ref(base, 0); ClearPageProperty(base); SetPageProperty(base); //尝试合并地址相连的空闲地址块 //先查看后一个空闲块 page = le2page(le, page_link); //得到后一个空闲块起始地址 if ((base+n) == page) { base->property += page->property; page->property = 0; } //后查看前一个空闲块 le = list_prev(&(base->page_link)); page = le2page(le, page_link); //此时并不是前一个空闲块,而是前一个page if ((le!= &free_list) && page == (base-1)) { while (le!= &free_list) { if (page->property > 0) { page->property += base->property; base->property =0; break; } le = list_prev(le); page = le2page(le, page_link); } } nr_free += n; return; }
int main(void) { struct parent parent; struct child c1, c2, c3; const struct parent *p; const struct child *c; plan_tests(20); parent.num_children = 0; list_head_init(&parent.children); c1.name = "c1"; list_add(&parent.children, &c1.list); ok1(list_next(&parent.children, &c1, list) == NULL); ok1(list_prev(&parent.children, &c1, list) == NULL); c2.name = "c2"; list_add_tail(&parent.children, &c2.list); ok1(list_next(&parent.children, &c1, list) == &c2); ok1(list_prev(&parent.children, &c1, list) == NULL); ok1(list_next(&parent.children, &c2, list) == NULL); ok1(list_prev(&parent.children, &c2, list) == &c1); c3.name = "c3"; list_add_tail(&parent.children, &c3.list); ok1(list_next(&parent.children, &c1, list) == &c2); ok1(list_prev(&parent.children, &c1, list) == NULL); ok1(list_next(&parent.children, &c2, list) == &c3); ok1(list_prev(&parent.children, &c2, list) == &c1); ok1(list_next(&parent.children, &c3, list) == NULL); ok1(list_prev(&parent.children, &c3, list) == &c2); /* Const variants */ p = &parent; c = &c2; ok1(list_next(&p->children, &c1, list) == &c2); ok1(list_prev(&p->children, &c1, list) == NULL); ok1(list_next(&p->children, c, list) == &c3); ok1(list_prev(&p->children, c, list) == &c1); ok1(list_next(&parent.children, c, list) == &c3); ok1(list_prev(&parent.children, c, list) == &c1); ok1(list_next(&p->children, &c3, list) == NULL); ok1(list_prev(&p->children, &c3, list) == &c2); return exit_status(); }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); assert(PageReserved(base)); list_entry_t *le = &free_list; struct Page * p; while((le=list_next(le)) != &free_list) { p = le2page(le, page_link); if(p>base){ break; } } // 每个page都加入freelist for(p=base;p<base+n;p++){ list_add_before(le, &(p->page_link)); } // 首个page进行设置 base->flags = 0; set_page_ref(base, 0); ClearPageProperty(base); SetPageProperty(base); base->property = n; p = le2page(le,page_link); // 如果后面需要合并 if( base+n == p ){ base->property += p->property; p->property = 0; } le = list_prev(&(base->page_link)); p = le2page(le, page_link); // 如果前面需要合并 if(le!=&free_list && p==base-1){ while(le!=&free_list){ if(p->property){ p->property += base->property; base->property = 0; break; } le = list_prev(le); p = le2page(le,page_link); } } nr_free += n; return ; }
static void default_free_pages(struct Page *base, size_t n) { // 用于释放页 // 我们来仔细看一下释放page的函数吧! assert(n > 0); assert(PageReserved(base)); list_entry_t *le = &free_list; // le指向空闲段链表的头部 struct Page *p; while ((le = list_next(le)) != &free_list) { // 开始遍历 p = le2page(le, page_link); if (p > base) { // free_list里面的数据都是按照地址从小到大排列的吧! break; } } // le现在指向一个恰好在base页面之后的page for (p = base; p < base + n; p++) { // 不断地在前面插入 list_add_before(le, &(p->page_link)); } base->flags = 0; set_page_ref(base, 0); // 引用计数变为了0 ClearPageProperty(base); // SetPageProperty(base); // 只需要这句就行了吧! base->property = n; p = le2page(le, page_link); if (base + n == p) { // 也就是说,前后可以连接起来 base->property += p->property; p->property = 0; } le = list_prev(&(base->page_link)); p = le2page(le, page_link); // 找到free_list中base之前的那个free page if (le != &free_list && p == base - 1) { // 如果两个也可以连起来 while (le != &free_list) { if (p->property) { p->property += base->property; base->property = 0; break; } le = list_prev(le); p = le2page(le, page_link); } } nr_free += n; // 空闲页的计数加n return; }
void *kmem_cache_alloc(struct kmem_cache *cache, uint32_t flags) { struct page *page = list_first(&cache->partial_slabs); if (!page) { page = make_new_slab(cache); if (!page) { return NULL; } list_append(&cache->partial_slabs, page); } void *result = get_free_object(page); if (page->num_allocated == cache->num_objects) { list_remove(&cache->partial_slabs, page); } else { struct page *prev_page = list_prev(&cache->partial_slabs, page); if (prev_page && (prev_page->num_allocated < page->num_allocated)) { list_remove(&cache->partial_slabs, prev_page); list_insert(&cache->partial_slabs, page, prev_page); } } if (flags & KMEM_ZEROED) { memset(result, 0, cache->object_size); } return result; }
static int splat_list_validate(list_t *list, int size, int order, int mult) { list_item_t *li; int i; /* Walk all items in list from head to verify stack or queue * ordering. We bound the for loop by size+1 to ensure that * we still terminate if there is list corruption. We also * intentionally make things a little more complex than they * need to be by using list_head/list_next for queues, and * list_tail/list_prev for stacks. This is simply done for * coverage and to ensure these function are working right. */ for (i = 0, li = (order ? list_head(list) : list_tail(list)); i < size + 1 && li != NULL; i++, li = (order ? list_next(list, li) : list_prev(list, li))) if (li->li_data != i * mult) return -EIDRM; if (i != size) return -E2BIG; return 0; }
void list() { printf(">> LIST\n"); list_t list; list_init(&list); test_list_t a = { "Hello" }; test_list_t b = { "Intrusive" }; test_list_t c = { "World" }; list_push_back(&list, &a.link); list_push_back(&list, &b.link); list_push_back(&list, &c.link); link_t *node = list_head(&list); while (node) { link_t *next = list_next(node); link_t *prev = list_prev(node); test_list_t *c = list_ref(node, test_list_t, link); test_list_t *n = next ? list_ref(next, test_list_t, link) : NULL; test_list_t *p = prev ? list_ref(prev, test_list_t, link) : NULL; printf("current: %s, next: %s, prev: %s\n", c->message, n ? n->message : "(None)", p ? p->message : "(None)"); node = next; } }
static int dsl_pool_txg_history_update(kstat_t *ksp, int rw) { dsl_pool_t *dp = ksp->ks_private; txg_history_t *th; int i = 0; if (rw == KSTAT_WRITE) return (EACCES); if (ksp->ks_data) kmem_free(ksp->ks_data, ksp->ks_data_size); mutex_enter(&dp->dp_lock); ksp->ks_ndata = dp->dp_txg_history_size; ksp->ks_data_size = dp->dp_txg_history_size * sizeof(kstat_txg_t); if (ksp->ks_data_size > 0) ksp->ks_data = kmem_alloc(ksp->ks_data_size, KM_PUSHPAGE); /* Traversed oldest to youngest for the most readable kstat output */ for (th = list_tail(&dp->dp_txg_history); th != NULL; th = list_prev(&dp->dp_txg_history, th)) { mutex_enter(&th->th_lock); ASSERT3S(i + sizeof(kstat_txg_t), <=, ksp->ks_data_size); memcpy(ksp->ks_data + i, &th->th_kstat, sizeof(kstat_txg_t)); i += sizeof(kstat_txg_t); mutex_exit(&th->th_lock); } mutex_exit(&dp->dp_lock); return (0); }
bool list_seek(struct list_cursor *cur, int index) { assert(cur); assert(cur->list); if (index < 0) { if ((unsigned) abs(index) > cur->list->length) return false; list_reset(cur); cur->target = cur->list->tail; while (cur->target && cur->target->dead) { cur->target = cur->target->prev; } list_item_ref(cur->target); while (++index) { bool ok = list_prev(cur); assert(ok); } } else { if ((unsigned) index >= cur->list->length) return false; list_reset(cur); cur->target = cur->list->head; while (cur->target && cur->target->dead) { cur->target = cur->target->next; } list_item_ref(cur->target); while (index--) { bool ok = list_next(cur); assert(ok); } } return true; }
static struct Page* default_alloc_pages(size_t n) { assert(0 < n); if (nr_free < n) { return 0; } struct Page* page = 0; list_entry_t* le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page* p = le2page(le, page_link); if (n <= p->property) { page = p; break; } } if (page) { list_entry_t* prevLe = list_prev(&(page->page_link)); list_del_init(&(page->page_link)); if (n < page->property) { struct Page* p = page + n; p->property = page->property - n; SetPageProperty(p); list_add(prevLe, &(p->page_link)); } nr_free -= n; ClearPageProperty(page); } return page; }
int dup_mmap(struct mm_struct *to, struct mm_struct *from) { assert(to != NULL && from != NULL); list_entry_t *list = &(from->mmap_list), *le = list; while ((le = list_prev(le)) != list) { struct vma_struct *vma, *nvma; vma = le2vma(le, list_link); nvma = vma_create(vma->vm_start, vma->vm_end, vma->vm_flags); if (nvma == NULL) { return -E_NO_MEM; } else { if (vma->vm_flags & VM_SHARE) { nvma->shmem = vma->shmem; nvma->shmem_off = vma->shmem_off; shmem_ref_inc(vma->shmem); } } insert_vma_struct(to, nvma); bool share = (vma->vm_flags & VM_SHARE); if (copy_range(to->pgdir, from->pgdir, vma->vm_start, vma->vm_end, share) != 0) { return -E_NO_MEM; } } return 0; }
static struct link_entry *context_get_entry(HlinkBCImpl *ctxt, ULONG hlid) { struct list *entry; switch (hlid) { case HLID_PREVIOUS: entry = list_prev(&ctxt->links, &ctxt->current->entry); break; case HLID_NEXT: entry = list_next(&ctxt->links, &ctxt->current->entry); break; case HLID_CURRENT: entry = &ctxt->current->entry; break; case HLID_STACKBOTTOM: entry = list_tail(&ctxt->links); break; case HLID_STACKTOP: entry = list_head(&ctxt->links); break; default: WARN("unknown id 0x%x\n", hlid); entry = NULL; } return entry ? LIST_ENTRY(entry, struct link_entry, entry) : NULL; }
//static struct Page * //default_alloc_pages(size_t n) { // assert(n > 0); // if (n > nr_free) { // return NULL; // } // struct Page *page = NULL; // list_entry_t *le = &free_list; // while ((le = list_next(le)) != &free_list) { // struct Page *p = le2page(le,page_link); // if (p->property >= n) { // page = p; // break; // } // } // if (page != NULL) { // le = list_prev(&(page->page_link)); // list_del(&(page->page_link)); // if (page->property > n) { // struct Page *p = page + n; // p->property = page->property-n; // list_add(le, &(p->page_link)); // } // nr_free-= n; // ClearPageProperty(page); // } // return page; //} //static void //default_free_pages(struct Page *base, size_t n) { // assert(n > 0); // struct Page *p = base, *p1; // for (; p != base + n; p ++) { // assert(!PageReserved(p) && !PageProperty(p)); // p->flags = 0; // set_page_ref(p, 0); // } // base->property = n; // SetPageProperty(base); // list_entry_t *le = list_next(&free_list), *pre, *cur; // /* // while (le != &free_list) { // // 算法大致分析: // p = le2page(le, page_link); // // 遍历双向链表中的 page,如果该 page 可以和 // // base+n 合并的话,就将这两个空闲快合并。 // // 否则插入头指针后面。 // le = list_next(le); // // 评价: // if (base + base>property == p) { // // 1.没有维护双向链表的有序性。 // base>property += p>property; // // 2.实现了空闲块的合并。 // ClearPageProperty(p); // list_del(&(p>page_link)); // } // else if (p + p>property == base) { // p>property += base>property; // ClearPageProperty(base); // base = p; // list_del(&(p>page_link)); // } // } // nr_free += n; // list_add(&free_list, &(base>page_link)); // */ // // MY CODE // while (1){ // // 实现空闲页的插入 // if(le == &free_list){ // list_add_before(le, &(base->page_link)); break; // } // p = le2page(le, page_link); // if(&(p->page_link) > &(base->page_link)){ // list_add_before(le, &(base->page_link)); break; // } // le = list_next(le); // } // pre = list_next(&free_list); // cur = list_next(pre); // // 遍历链表,合并连续的空闲块 // while (cur != &free_list && pre != &free_list){ // p = le2page(pre, page_link); // p1 =le2page(cur, page_link); // if(p + p->property == p1){ // p->property += p1->property; // ClearPageProperty(p1); // list_del(&(p1->page_link)); // } // else{ // pre = cur; // } // cur = list_next(cur); // } // nr_free += n; //} static struct Page * default_alloc_pages(size_t n) { assert(n > 0); if (n > nr_free) { return NULL; } struct Page *page = NULL; list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); if (p->property >= n) { page = p; break; } } if (page != NULL) { list_entry_t* pr=list_prev(&page->page_link);//增添代码 list_del(&(page->page_link)); if (page->property > n) { struct Page *p = page + n; p->property = page->property - n; list_add(pr,&(p->page_link));//增添代码 //list_add(&free_list, &(p->page_link)); } nr_free -= n; ClearPageProperty(page); } return page; }
void free(void *ptr) { return; if ( ptr == NULL ) return; mem_chunk_t *mc; mem_chunk_t *nc; mc = ptr - sizeof(mem_chunk_t); if ( mc->avail ) { fprintf(stderr, "freeing bad addr %p\n", ptr); return; } mc->avail = TRUE; /* złączamy sąsiednie chunki */ nc = list_next(&__mem_chunks, mc); if ( nc && nc->avail ) { mc->size = mc->size+nc->size+sizeof(mem_chunk_t); list_remove(&__mem_chunks, nc); } nc = list_prev(&__mem_chunks, mc); if ( nc && nc->avail ) { nc->size = nc->size+mc->size+sizeof(mem_chunk_t); list_remove(&__mem_chunks, mc); } return; }
/* * Insert buffer to the tail of free list */ static void bio_insert_tail(struct buf *bp) { list_insert(list_prev(&free_list), &bp->b_link); sem_post(&free_sem); }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); assert(PageReserved(base)); list_entry_t *le = &free_list; //获取空闲内存页的起始地址 struct Page *p; while((le = list_next(le))!= &free_list){ p = le2page(le, page_link); if( p > base){ //说明base应该接到p的前面,也就是le的前面 break; } } for( p = base; p<base+n; p++){ list_add_before(le, &(p->page_link)); } base->flags = 0; set_page_ref(base, 0); ClearPageProperty(base); SetPageProperty(base); base->property = n; //下面是块的合并 //向后 p = le2page(le, page_link); if(base+n == p){ base->property += p->property; p->property = 0; } //向前 le = list_prev(&(base->page_link)); p = le2page(le, page_link); if(le!=&free_list && p == base-1){ while(le!=&free_list){ if(p->property){ p->property += base->property; base->property = 0; break; } le = list_prev(le); p = le2page(le, page_link); } } nr_free += n; return ; }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); struct Page *p = base; for (; p != base + n; p ++) { assert(PageReserved(p) && !PageProperty(p)); p->flags = p->property = 0; set_page_ref(p, 0); } base->property = n; SetPageProperty(base); list_entry_t *le = list_next(&free_list); while (le != &free_list) { p = le2page(le, page_link); if(p > base) break; le = list_next(le); } list_add_before(le, &(base->page_link)); p = le2page(le, page_link); if(le != &free_list && base + base->property == p) { base->property += p->property; ClearPageProperty(p); list_del(&(p->page_link)); } le = list_prev(&(base->page_link)); p = le2page(le, page_link); if (le != &free_list && p + p->property == base) { p->property += base->property; ClearPageProperty(base); list_del(&(base->page_link)); } nr_free += n; /** while (le != &free_list) { p = le2page(le, page_link); le = list_next(le); if (base + base->property == p) { base->property += p->property; ClearPageProperty(p); list_del(&(p->page_link)); } else if (p + p->property == base) { p->property += base->property; ClearPageProperty(base); base = p; list_del(&(p->page_link)); } } nr_free += n; list_add(&free_list, &(base->page_link)); */ }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); // (5.1) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { if (le2page(le, page_link) > base) { // the first position higher than base break; } } struct Page *p; for (p = base; p < base + n; p++) { // insert these pages p->property = 0; list_add_before(le, &(p->page_link)); } // (5.2) mark base as free page base->flags = 0; SetPageProperty(base); base->property = n; set_page_ref(base, 0); // (5.3) p = le2page(le, page_link); if (p == base + n) { // merge forward base->property += p->property; // merge p into base p->property = 0; } le = list_prev(&(base->page_link)); p = le2page(le, page_link); // prev of base if (p == base - 1) { // merge backward for (; le != &free_list; le = list_prev(le)) { p = le2page(le, page_link); if (p->property > 0) { // find property, merge base into p p->property += base->property; base->property = 0; break; } } } nr_free += n; }
wait_t * wait_queue_last(wait_queue_t *queue) { list_entry_t *le = list_prev(&(queue->wait_head)); if (le != &(queue->wait_head)) { return le2wait(le, wait_link); } return NULL; }
/** * Raises a specified event. Every event handler which is connected * to this event and which is enabled will be called passing the * given event_data to it. * * @note This function is blocking until all event handlers are called. * * @param name name of the event * @param event_data data which will be passed to the event handler functions */ void event_raise(char *name, void *event_data) { List *event_link; List *prev_event_link; List *handler_link; EventInfo *event; EventInfo *prev_event; EventHandlerInfo *handler; // First we have to get the event, if we don't find it, we can return. event_link = _event_get_event_link(name); if (!event_link) return; event = (EventInfo *)event_link->data; // Now iterate through every event handler handler_link = list_first(event->l_event_handlers); while (handler_link) { handler = (EventHandlerInfo *)handler_link->data; // If the handler is enabled, call the event handler function with // the appropriate arguments. if (handler->state == EVENT_HANDLER_ENABLED) { handler->handler(event_data, handler->user_data); } handler_link = list_next(handler_link); } // Increase the counter event->raise_count++; // Check whether the event before this one in the event list has a smaller raise_count. // If yes, exchange the positions. This way the list will always be sorted, so that // often raised event are found quicker in the list. prev_event_link = list_prev(event_link); if (prev_event_link) { prev_event = (EventInfo *)list_prev(event_link)->data; if (prev_event->raise_count < event->raise_count) { prev_event_link->data = event; event_link->data = prev_event; } } }
Point line_beginning_position(int count) { Point pt; /* Copy current point position without offset (beginning of * line). */ pt = cur_bp->pt; pt.o = 0; count--; for (; count < 0 && list_prev(pt.p) != cur_bp->lines; pt.n--, count++) pt.p = list_prev(pt.p); for (; count > 0 && list_next(pt.p) != cur_bp->lines; pt.n++, count--) pt.p = list_next(pt.p); return pt; }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); assert(PageReserved(base)); struct Page *p = base; struct Page * q = NULL; list_entry_t * le = &free_list; while((le = list_next(le)) != &free_list) { q = le2page(le,page_link); if(q > base) break; } //struct Page * q = for(;p < base + n;p++){ list_add_before(le,&(p -> page_link)); } base -> flags = 0; set_page_ref(base,0); ClearPageProperty(base); SetPageProperty(base); base->property = n; if(q == base + n){ base -> property += q -> property; q -> property = 0; } le = list_prev(&(base -> page_link)); q = le2page(le,page_link); if(le != &free_list && q == base -1) { while(le != &free_list){ if(q -> property) { q -> property += base -> property; base -> property = 0; break; } le = list_prev(le); q = le2page(le,page_link); } } nr_free += n; return; }
static void default_free_pages(struct Page *base, size_t n) { assert(n > 0); list_entry_t *le = &free_list; list_entry_t *bef; struct Page* p; while ((le = list_next(le)) != &free_list){ p = le2page(le, page_link); if (p > base) break; } for (p = base; p< base+n; p++){ list_add_before(le, &(p->page_link)); } base ->flags = 0; set_page_ref(base, 0); ClearPageReserved(base); // SetPageProperty(base); base->property = n; p = le2page(le, page_link); if (base + n == p){ base->property += p->property; p->property = 0; } bef = list_prev(&(base->page_link)); p = le2page(bef, page_link); if (bef != &free_list && p == base-1){ while (bef != &free_list){ if (p -> property != 0){ p->property += base->property; base->property = 0; break; } bef = list_prev(bef); p = le2page(bef, page_link); } } nr_free += n; return; }
wait_t * wait_queue_prev(wait_queue_t *queue, wait_t *wait) { assert(!list_empty(&(wait->wait_link)) && wait->wait_queue == queue); list_entry_t *le = list_prev(&(wait->wait_link)); if (le != &(queue->wait_head)) { return le2wait(le, wait_link); } return NULL; }
/** * Zwalnia ciągły obszar. * @param vseg deskryptor segmentu. * @param vaddr adres pierwszej strony w obszarze. * @param size rozmiar. */ void vm_seg_release(vm_seg_t *vseg, vm_addr_t vaddr, vm_size_t size) { bool deleteRegion = FALSE; vm_region_t *region = list_find(&vseg->regions, is_containing_addr, vaddr); KASSERT(region != NULL); // patrzymy, czy wyrzucić cały region, czy skrócić go z początku. if (region->begin == vaddr) { if (region->size == size) { deleteRegion = TRUE; } else { region->begin += size; region->size -= size; } } else // lub skrócić od końca. if (region->end == vaddr+size) { region->end -= size; region->size -= size; } else { // pozostaje tylko podzielić region vm_region_t *newreg = vm_lpool_alloc(&vm_unused_regions); newreg->begin = vaddr+size; newreg->end = region->end; newreg->size = region->end - newreg->begin; newreg->segment = vseg; region->end = vaddr; region->size = region->end - region->begin; list_insert_in_order(&vseg->regions, newreg, is_prev); } if (vseg->flags & VM_SEG_NORMAL) { if (vseg->end == vaddr + size) { vm_region_t *prevreg = list_prev(&vseg->regions, region); vseg->end -= size; vseg->size -= size; if (vaddr == region->begin && prevreg) { // usunelismy caly region, kasujmy wiec dziure przed nim vseg->end -= vaddr - prevreg->end; vseg->size -= vaddr - prevreg->end; } } } else if (vseg->flags & VM_SEG_EXPDOWN) { if (vseg->base == vaddr) { vm_region_t *nextreg = list_next(&vseg->regions, region); vseg->base += size; vseg->size -= size; if (size == region->size && nextreg) { vseg->base = nextreg->begin; vseg->size -= (nextreg->begin - region->end); } } } if (deleteRegion) { list_remove(&vseg->regions, region); vm_lpool_free(&vm_unused_regions, region); } }
/* Returns true only if the list elements A through B (exclusive) are in order according to LESS given auxiliary data AUX. */ static bool is_sorted (struct list_elem *a, struct list_elem *b, list_less_func *less, void *aux) { if (a != b) while ((a = list_next (a)) != b) if (less (a, list_prev (a), aux)) return false; return true; }
void list_reverse(ADTList list) { for (ADTListItem it = list_head(list), next; it; it = next) { next = list_next(it); list_item_set_next(it, list_prev(it)); list_item_set_prev(it, next); } ADTListItem temp = list->head; list->head = list->tail; list->tail = temp; }
void list_rforeach2_second(list_t* list, void (*proc)(void* item_data, void* user_data), void* user_data) { list_item_t* item = list_last(list); while(item){ proc(list_item_data(item), user_data); item = list_prev(item); } }