static void router_test2(void) { int i; struct node_t* node; struct node_t* result[8]; static struct node_t s_nodes[100000]; uint8_t id[N_NODEID] = { 0xAB, 0xCD, 0xEF, 0x89, }; heap_t* heap, *heap2; struct router_t* router; router = router_create(id); heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, 8 + 1); for (i = 0; i < sizeof(s_nodes) / sizeof(s_nodes[0]); i++) { int v = rand(); memset(&s_nodes[i], 0, sizeof(s_nodes[i])); memcpy(s_nodes[i].id, &v, sizeof(v)); s_nodes[i].ref = 1; if (0 == router_add(router, s_nodes[i].id, &s_nodes[i].addr, &node)) { heap_push(heap, node); if (heap_size(heap) > 8) { node_release((struct node_t*)heap_top(heap)); heap_pop(heap); } } } assert(8 == heap_size(heap)); assert(8 == router_nearest(router, id, result, 8)); heap2 = heap_create(node_compare_less, (void*)id); heap_reserve(heap2, 8); for (i = 0; i < 8; i++) { heap_push(heap2, result[i]); } assert(heap_size(heap) == heap_size(heap2)); for (i = 0; i < 8; i++) { assert(heap_top(heap2) == heap_top(heap)); heap_pop(heap); heap_pop(heap2); } router_destroy(router); heap_destroy(heap); heap_destroy(heap2); printf("router test ok!\n"); }
/* ** Realloc by merging the next if it isn't reserved. ** Return 0 if the realloc has been done, -1 otherwise */ static int realloc_by_merge(t_ptr block, size_t size) { size_t total_size; size_t real_size; if (size <= DWORD_SIZE) real_size = size + EXTRA_SIZE; else { real_size = ((size + EXTRA_SIZE + DWORD_SIZE - 1) / DWORD_SIZE) * DWORD_SIZE; } total_size = GET_B_SIZE(block) + GET_B_SIZE(GET_NEXT(block)); if (IS_B_ALLOC(GET_NEXT(block)) || total_size < real_size) return (-1); SET(GET_HEAD(block), PACK(total_size, 0)); SET(GET_FOOT(block), PACK(total_size, 0)); heap_reserve(block, real_size); return (0); }
void *mmio_map(uintptr_t phy, size_t len, vm_acc_t flags) { /* align the address and pad with extra length */ uintptr_t aligned_phy = PAGE_ALIGN_REVERSE(phy); size_t off = phy - aligned_phy; len += off; /* reserve some virtual memory in the heap */ uintptr_t aligned_virt = (uintptr_t) heap_reserve(len); if (!aligned_virt) return 0; /* map the physical memory into virtual memory */ if (!vmm_map_range(aligned_virt, aligned_phy, len, flags)) { heap_free((void *) aligned_virt); return 0; } /* return where the memory is mapped */ return (void *) (aligned_virt + off); }
int router_nearest(struct router_t* router, const uint8_t id[N_NODEID], struct node_t* nodes[], size_t count) { int i, min, diff; uint8_t xor[N_NODEID]; heap_t* heap; struct rbitem_t* item; struct rbtree_node_t* node; const struct rbtree_node_t* prev; const struct rbtree_node_t* next; heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, count + 1); min = N_BITS; locker_lock(&router->locker); rbtree_find(&router->rbtree, id, &node); if (NULL == node) { locker_unlock(&router->locker); return 0; } item = rbtree_entry(node, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); min = min < diff ? min : diff; heap_push(heap, item->node); prev = rbtree_prev(node); next = rbtree_next(node); do { while (prev) { item = rbtree_entry(prev, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); prev = rbtree_prev(prev); if (diff < min) { min = diff; break; // try right } } while (next) { item = rbtree_entry(next, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); next = rbtree_next(next); if (diff < min) { min = diff; break; // try left } } } while (heap_size(heap) < (int)count && (prev || next)); for (i = 0; i < (int)count && !heap_empty(heap); i++) { nodes[i] = heap_top(heap); node_addref(nodes[i]); heap_pop(heap); } locker_unlock(&router->locker); heap_destroy(heap); return i; }