Esempio n. 1
0
/* verify that all API calls are exported */
static void test_api(void) {
        CRBTree t = {};
        CRBNode n = C_RBNODE_INIT(n);

        assert(!c_rbnode_is_linked(&n));

        /* init, is_linked, add, remove, remove_init */

        c_rbtree_add(&t, NULL, &t.root, &n);
        assert(c_rbnode_is_linked(&n));

        c_rbtree_remove_init(&t, &n);
        assert(!c_rbnode_is_linked(&n));

        c_rbtree_add(&t, NULL, &t.root, &n);
        assert(c_rbnode_is_linked(&n));

        c_rbtree_remove(&t, &n);
        assert(c_rbnode_is_linked(&n)); /* @n wasn't touched */

        c_rbnode_init(&n);
        assert(!c_rbnode_is_linked(&n));

        /* first, last, leftmost, rightmost, next, prev */

        assert(!c_rbtree_first(&t));
        assert(!c_rbtree_last(&t));
        assert(&n == c_rbnode_leftmost(&n));
        assert(&n == c_rbnode_rightmost(&n));
        assert(!c_rbnode_next(&n));
        assert(!c_rbnode_prev(&n));
}
Esempio n. 2
0
/**
 * b1_node_implement() - implement interface on node
 * @node:               node to operate on
 * @interface:          interface to implement
 *
 * Extend @node to support the interface given as @interface. From then on, the
 * node will dispatch incoming method calls on this interface.
 *
 * This fails, if the given interface is already implemented by @node.
 *
 * Return: 0 on success, negative error code on failure.
 */
_c_public_ int b1_node_implement(B1Node *node, B1Interface *interface) {
        B1Implementation *implementation;
        CRBNode **slot, *p;

        assert(node);
        assert(interface);

        if (node->live || node->slot)
                return -EBUSY;

        slot = c_rbtree_find_slot(&node->implementations, implementations_compare, interface->name, &p);
        if (!slot)
                return -ENOTUNIQ;

        implementation = calloc(1, sizeof(*implementation));
        if (!implementation)
                return -ENOMEM;

        c_rbnode_init(&implementation->rb);
        implementation->interface = b1_interface_ref(interface);
        interface->implemented = true;

        c_rbtree_add(&node->implementations, p, slot, &implementation->rb);
        return 0;
}
Esempio n. 3
0
int b1_handle_acquire(B1Handle **handlep, B1Peer *peer, uint64_t handle_id) {
        B1Handle *handle;
        CRBNode **slot, *p;
        int r;

        assert(handlep);
        assert(peer);

        if (handle_id == BUS1_HANDLE_INVALID) {
                *handlep = NULL;
                return 0;
        }

        slot = c_rbtree_find_slot(&peer->handles, handles_compare, &handle_id, &p);
        if (slot) {
                r = b1_handle_new(peer, handle_id, &handle);
                if (r < 0)
                        return r;

                c_rbtree_add(&peer->handles, p, slot, &handle->rb);
        } else {
                handle = c_container_of(p, B1Handle, rb);
                b1_handle_ref(handle);
                b1_handle_release(handle);
        }

        *handlep = handle;

        return 0;
}
Esempio n. 4
0
static void test_child1(TestContext *ctx) {
        CRBNode *p, **slot;
        size_t i;

        for (i = 0; i < ctx->n_nodes; ++i) {
                child_assert(!c_rbnode_is_linked(ctx->nodes[i]));
                slot = c_rbtree_find_slot(ctx->tree, compare, ctx->nodes[i], &p);
                c_rbtree_add(ctx->tree, p, slot, ctx->nodes[i]);
        }
}
Esempio n. 5
0
/* run tests against the c_rbtree_find*() helpers */
static void test_map(void) {
        CRBNode **slot, *p;
        CRBTree t = {};
        Node *nodes[2048];
        unsigned long i;

        /* allocate and initialize all nodes */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                nodes[i] = malloc(sizeof(*nodes[i]));
                assert(nodes[i]);
                nodes[i]->key = i;
                c_rbnode_init(&nodes[i]->rb);
        }

        /* shuffle nodes */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));

        /* add all nodes, and verify that each node is linked */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                assert(!c_rbnode_is_linked(&nodes[i]->rb));
                assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));

                slot = c_rbtree_find_slot(&t, compare, (void *)nodes[i]->key, &p);
                assert(slot);
                c_rbtree_add(&t, p, slot, &nodes[i]->rb);

                assert(c_rbnode_is_linked(&nodes[i]->rb));
                assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
        }

        /* shuffle nodes again */
        shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));

        /* remove all nodes (in different order) */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
                assert(c_rbnode_is_linked(&nodes[i]->rb));
                assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));

                c_rbtree_remove_init(&t, &nodes[i]->rb);

                assert(!c_rbnode_is_linked(&nodes[i]->rb));
                assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
        }

        /* free nodes again */
        for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
                free(nodes[i]);
}
Esempio n. 6
0
int b1_handle_link(B1Handle *handle) {
        CRBNode **slot, *p;

        assert(handle);
        assert(handle->id != BUS1_HANDLE_INVALID);
        assert(handle->holder);

        slot = c_rbtree_find_slot(&handle->holder->handles,
                                  handles_compare, &handle->id, &p);
        if (!slot)
                return -ENOTUNIQ;

        c_rbtree_add(&handle->holder->handles, p, slot, &handle->rb);

        return 0;

}
Esempio n. 7
0
int b1_node_link(B1Node *node) {
        CRBNode **slot, *p;

        assert(node);
        assert(node->id != BUS1_HANDLE_INVALID);
        assert(node->owner);

        slot = c_rbtree_find_slot(&node->owner->nodes,
                                  nodes_compare, &node->id, &p);
        if (!slot)
                return -ENOTUNIQ;

        c_rbtree_add(&node->owner->nodes, p, slot, &node->rb);

        return 0;

}
Esempio n. 8
0
int b1_handle_acquire(B1Peer *peer, B1Handle **handlep, uint64_t handle_id) {
        B1Handle *handle;
        CRBNode **slot, *p;
        int r;

        assert(peer);
        assert(handlep);

        if (handle_id == BUS1_HANDLE_INVALID) {
                *handlep = NULL;
                return 0;
        }

        slot = c_rbtree_find_slot(&peer->handles, handles_compare, &handle_id, &p);
        if (slot) {
                r = b1_handle_new(peer, &handle);
                if (r < 0)
                        return r;

                handle->ref_kernel = (CRef)C_REF_INIT;
                handle->live = true;
                handle->id = handle_id;

                c_rbtree_add(&peer->handles, p, slot, &handle->rb);
        } else {
                handle = c_container_of(p, B1Handle, rb);
                if (handle->live) {
                        c_ref_inc(&handle->ref_kernel);
                        /* reusing existing handle, drop redundant reference from kernel */
                        r = bus1_peer_handle_release(handle->holder->peer, handle->id);
                        if (r < 0)
                                return r;
                } else {
                        handle->ref_kernel = (CRef)C_REF_INIT;
                        handle->live = true;
                }
                c_ref_inc(&handle->ref);
        }

        *handlep = handle;
        return 0;
}
Esempio n. 9
0
static void insert(CRBTree *t, CRBNode *n) {
        CRBNode **i, *p;

        assert(t);
        assert(n);
        assert(!c_rbnode_is_linked(n));

        i = &t->root;
        p = NULL;
        while (*i) {
                p = *i;
                if (n < *i) {
                        i = &(*i)->left;
                } else {
                        assert(n > *i);
                        i = &(*i)->right;
                }
        }

        c_rbtree_add(t, p, i, n);
}