void test_avl_tree_remove(void)
{
	AVLTree *tree;
	int i;
	int x, y, z;
	int value;
	int expected_entries;

	tree = create_tree();

	/* Try removing invalid entries */

	i = NUM_TEST_VALUES + 100;
	assert(avl_tree_remove(tree, &i) == 0);
	i = -1;
	assert(avl_tree_remove(tree, &i) == 0);

	/* Delete the nodes from the tree */

	expected_entries = NUM_TEST_VALUES;

	/* This looping arrangement causes nodes to be removed in a
	 * randomish fashion from all over the tree. */

	for (x=0; x<4; ++x) {
		for (y=0; y<4; ++y) {
			for (z=0; z<8; ++z) {
				value = z * 16 + (3 - y) * 4 + x;
				assert(avl_tree_remove(tree, &value) != 0);
				validate_tree(tree);
				expected_entries -= 1;
				assert(avl_tree_num_entries(tree)
				       == expected_entries);
			}
		}
	}

	/* All entries removed, should be empty now */

	assert(avl_tree_root_node(tree) == NULL);

	avl_tree_free(tree);
}
Exemple #2
0
static VALUE avl_tree_rremove( VALUE self, VALUE obj )
{
  avl_tree_r *t;
  avl_tree_elem elem = (avl_tree_elem *)obj;

  Data_Get_Struct( self, avl_tree_r, t );

  t->root = avl_tree_remove( t->root, elem, cmp );

  return obj;
}
Exemple #3
0
/** Release a user semaphore.
 * @param sem		Semaphore to release. */
static void user_semaphore_release(user_semaphore_t *sem) {
	if(refcount_dec(&sem->count) == 0) {
		rwlock_write_lock(&semaphore_tree_lock);
		avl_tree_remove(&semaphore_tree, &sem->tree_link);
		rwlock_unlock(&semaphore_tree_lock);

		object_destroy(&sem->obj);
		id_allocator_free(&semaphore_id_allocator, sem->id);
		kfree(sem);
	}
}
Exemple #4
0
/* remove process from list */
static void remove_process_from_list(process_t *process)
{
    unsigned long irqs_state;

    /* acquire lock before access */
    irqs_state = spin_lock_irqsave(&processes_lock);

    /* remove process */
    xlist_remove_unsafe(&processes_list, &process->procs_list_node);

    /* remove process from tree */
    if(!avl_tree_remove(&processes_tree, process))
      panic("remove_process_from_list(): failed to remove process from tree!\n");

    /* release lock */
    spin_unlock_irqrstor(&processes_lock, irqs_state);
}
Exemple #5
0
void writer(uss_t *srv, uss_connection_t *conn,
            int error, driver_core_t *core) {
    driver_core_connection_state_t *s = conn->priv;

    if (error) {
        LOG(LOG_LEVEL_WARN, "Couldn't send buffer to client: %s\n",
            strerror(errno));
        avl_tree_remove(&core->connection_state, conn->fd);
        unix_socket_server_close_connection(srv, conn);
        return;
    }

    s->argc = s->args_received = 0;
    s->last_argument_offset = 0;

    buffer_realloc(&conn->read_task.b, 0);

    unix_socket_server_recv(srv, conn, sizeof(pr_signature_t),
                            (uss_reader_t)reader,
                            core);
}
void perform_avl_tree_test (avl_tree_t *avlt, int use_odd_numbers)
{
    int i, lo, hi, d, fail_search;
    int rv;
    int fine, not_fine;
    char *oddness = use_odd_numbers ? "odd" : "even";
    char *reverse = use_odd_numbers ? "even" : "odd";
    unsigned long long int bytes_used;
    double megabytes_used;
    void *fwdata, *searched, *found, *removed;
    chunk_manager_parameters_t chparams;

    printf("size of ONE avl node is: %lu bytes\n",
            sizeof(avl_node_t));

    /* 
    ** Fill opposing ends of array, converge in middle.
    ** This gives some sort of randomness to data.
    */
    printf("filling array of size %d with %s number data\n", 
        MAX_SZ, oddness);
    d = use_odd_numbers ? 1 : 0;
    lo = 0; 
    hi = MAX_SZ - 1;
    while (1) {
        data[lo++] = d;
        d += 2;
        data[hi--] = d;
        d += 2;
        if (lo > hi) break;
    }

    if (max_value_reached < d) {
        max_value_reached = d + 10;
        printf("max value recorded so far is %d\n", max_value_reached);
    }

    chparams.initial_number_of_chunks = max_value_reached + 10;
    chparams.grow_size = 1024;

    avl_tree_init(avlt, 1, int_compare, NULL, &chparams);

    /* enter all array data into avl tree */
    printf("now entering all %s number data into the avl tree\n", oddness);
    timer_start(&timr);
    for (i = 0; i < MAX_SZ; i++) {
        fwdata = &data[i];
        rv = avl_tree_insert(avlt, fwdata, &found);
        if (rv != 0) {
            printf("populate_data: avl_tree_insert error: %d failed\n", i);
        }
    }
    timer_end(&timr);
    timer_report(&timr, MAX_SZ, NULL);
    OBJECT_MEMORY_USAGE(avlt, bytes_used, megabytes_used);
    printf("total memory used by the avl tree of %d nodes: %llu bytes (%lf Mbytes)\n",
        avlt->n, bytes_used, megabytes_used);

    printf("searching for non existant data\n");
    fine = not_fine = 0;
    timer_start(&timr);
    for (i = max_value_reached; i < (max_value_reached + EXTRA); i++) {
        searched = &i;
        rv = avl_tree_search(avlt, searched, &found);
        if ((rv == 0) || found) {
            not_fine++;
        } else {
            fine++;
        }
    }
    timer_end(&timr);
    timer_report(&timr, EXTRA, NULL);
    printf("expected %d, NOT expected %d\n", fine, not_fine);

    /* now search all data that should be found (all of them) */
    printf("now searching all %s numbers in the avl tree\n", oddness);
    fine = not_fine = 0;
    timer_start(&timr);
    for (i = 0; i < MAX_SZ; i++) {
        searched = &data[i];
        rv = avl_tree_search(avlt, searched, &found);

        if ((rv != 0) || (data[i] != *((int*) found))) {
            not_fine++;
        } else {
            fine++;
        }
    }
    timer_end(&timr);
    timer_report(&timr, MAX_SZ, NULL);
    printf("found %d as expected and %d as NOT expected\n", fine, not_fine);

    /* now search for all entries that should NOT be in the tree */
    printf("now searching for all %s numbers in the avl tree\n", reverse);
    fine = not_fine = 0;
    d = use_odd_numbers ? 0 : 1;
    timer_start(&timr);
    for (i = 0; i < MAX_SZ; i++) {
        searched = &d;
        rv = avl_tree_search(avlt, searched, &found);
        if ((rv == 0) || found) {
            not_fine++;
        } else {
            fine++;
        }
        d += 2;
    }
    timer_end(&timr);
    timer_report(&timr, MAX_SZ, NULL);
    printf("%d as expected and %d as NOT expected\n", fine, not_fine);

#if 0

int tree_nodes = avlt->n;
printf("now deleting the whole tree (%d nodes)\n", tree_nodes);
timer_start(&timr);
avl_tree_destroy(avlt);
timer_end(&timr);
timer_report(&timr, tree_nodes, NULL);
return;

#endif // 0

    /* now delete one entry at a time and search it (should not be there) */
    printf("now deleting and searching\n");
    fine = not_fine = fail_search = 0;
    timer_start(&timr);
    for (i = 0; i < MAX_SZ; i++) {
        searched =  &data[i];
        rv = avl_tree_remove(avlt, searched, &removed);
        if ((rv != 0) || (data[i] != *((int*) removed))) {
            not_fine++;
        } else {
            fine++;
        }
        rv = avl_tree_search(avlt, searched, &found);
        if ((rv == 0) || found) {
            fail_search++;
        }
    }
    timer_end(&timr);
    timer_report(&timr, MAX_SZ*2, NULL);
    printf("deleted %d, could NOT delete %d, erroneous search %d\n",
        fine, not_fine, fail_search);

    OBJECT_MEMORY_USAGE(avlt, bytes_used, megabytes_used);
    printf("total memory used by the avl tree (%d nodes) after deletes: "
        "%llu bytes (%f Mbytes)\n",
        avlt->n, bytes_used, megabytes_used);

    avl_tree_destroy(avlt);
}
Exemple #7
0
/************ definitions ************/
void reader(uss_t *srv, uss_connection_t *conn,
            int error, driver_core_t *core) {
    const pr_signature_t *s;
    pr_driver_response_t *response_header;
    const pr_driver_command_t *dc;
    const pr_driver_command_argument_t *dca;
    const uint8_t *dca_value;
    uint8_t argc, arg_idx;
    uint8_t cmd_idx;
    size_t required_length;
    driver_command_t *comm;
    buffer_t response;
    driver_core_connection_state_t *state;

    if (error) {
        LOG(LOG_LEVEL_WARN, "Couldn't recv from client: %s\n",
            strerror(errno));
        avl_tree_remove(&core->connection_state, conn->fd);
        unix_socket_server_close_connection(srv, conn);
        return;
    }

    if (conn->eof) {
        LOG_MSG(LOG_LEVEL_DEBUG, "Another one EOF\n");
        avl_tree_remove(&core->connection_state, conn->fd);
        unix_socket_server_close_connection(srv, conn);
        return;
    }

    s = (const pr_signature_t *)(conn->read_task.b.data);

    if (PR_DRV_COMMAND != s->s) {
        LOG(LOG_LEVEL_WARN, "Invalid signature received: %#02x\n",
            s->s);
        avl_tree_remove(&core->connection_state, conn->fd);
        unix_socket_server_close_connection(srv, conn);
        return;
    }

    if (conn->read_task.b.user_size < sizeof(pr_driver_command_t)) {
        conn->read_task.b.offset = conn->read_task.b.user_size;
        unix_socket_server_recv(
            srv, conn,
            sizeof(pr_driver_command_t) - conn->read_task.b.user_size,
            (uss_reader_t)reader,
            core);

        return;
    }

    state = (driver_core_connection_state_t *)conn->priv;
    dc = (const pr_driver_command_t *)s;
    argc = dc->argc;
    cmd_idx = dc->cmd_idx;
    dca = (const pr_driver_command_argument_t *)(dc + 1);

    state->argc = argc;

    comm = (driver_command_t *)vector_get(&core->payload->commands, cmd_idx);
    if (argc > comm->max_arity) {
        LOG(LOG_LEVEL_WARN, "Maximum command arity exceeded: %#02x vs %#02x\n",
            (unsigned int)argc, (unsigned int)comm->max_arity);
        avl_tree_remove(&core->connection_state, conn->fd);
        unix_socket_server_close_connection(srv, conn);
        return;
    }

    if (!argc) {
        LOG(LOG_LEVEL_DEBUG, "Calling %*s with no arguments\n",
            comm->name_len, comm->name);
        buffer_init(&response, sizeof(*response_header), bp_non_shrinkable);
        comm->handler(cmd_idx,
                      comm->name, comm->name_len,
                      argc, NULL, &response);

        if (response.user_size < sizeof(*response_header)) {
            LOG_MSG(LOG_LEVEL_FATAL,
                    "Comand handler malforms response buffer\n");
            abort();
        }

        response_header = (pr_driver_response_t *)response.data;
        response_header->s.s = PR_DRV_RESPONSE;
        response_header->len = response.user_size - sizeof(*response_header);

        unix_socket_server_send(srv, conn, response.data, response.user_size,
                                (uss_writer_t)writer, core);
        buffer_deinit(&response);
        return;
    }   /* if (!argc) */

    if (state->argc == state->args_received) {
        LOG(LOG_LEVEL_DEBUG, "Calling %*s with %d arguments\n",
            comm->name_len, comm->name, state->argc);
        driver_command_argument_t argv[state->argc];

        for (arg_idx = 0; arg_idx < state->argc; ++arg_idx) {
            argv[arg_idx].arg = (const char *)(dca + 1);
            argv[arg_idx].arg_len = dca->len;

            dca = (const pr_driver_command_argument_t *)(
                (const uint8_t *)(dca + 1) + dca->len);
        }

        buffer_init(&response, 0, bp_non_shrinkable);
        comm->handler(cmd_idx,
                      comm->name, comm->name_len,
                      state->argc, argv, &response);
        unix_socket_server_send(srv, conn, response.data, response.user_size,
                                (uss_writer_t)writer, core);
        buffer_deinit(&response);

        return;
    }   /* if (state->argc == state->args_received) */

    /* TODO receive full arguments vector */
    if (0 == state->last_argument_offset)
        state->last_argument_offset = sizeof(*dc);

    dca = (const pr_driver_command_argument_t *)(
        (const uint8_t *)s + state->last_argument_offset
    );

    if (conn->read_task.b.user_size < state->last_argument_offset
                                            + sizeof(*dca)) {
        required_length = state->last_argument_offset + sizeof(*dca);
        conn->read_task.b.offset = conn->read_task.b.user_size;
        unix_socket_server_recv(
            srv, conn,
            required_length - conn->read_task.b.user_size,
            (uss_reader_t)reader,
            core);

        return;
    }

    if (conn->read_task.b.user_size < state->last_argument_offset
                                            + sizeof(*dca) + dca->len) {
        required_length = state->last_argument_offset + sizeof(*dca)
                            + dca->len;
        conn->read_task.b.offset = conn->read_task.b.user_size;
        unix_socket_server_recv(
            srv, conn,
            required_length - conn->read_task.b.user_size,
            (uss_reader_t)reader,
            core);

        return;
    }

    ++state->args_received;
    state->last_argument_offset += sizeof(*dca) + dca->len;
    required_length = state->last_argument_offset + sizeof(*dca);

    if (state->args_received < state->argc) {
        conn->read_task.b.offset = conn->read_task.b.user_size;
        unix_socket_server_recv(
            srv, conn,
            required_length - conn->read_task.b.user_size,
            (uss_reader_t)reader,
            core);

        return;
    }

    LOG(LOG_LEVEL_DEBUG, "Calling %*s with %d arguments\n",
        comm->name_len, comm->name, state->argc);
    driver_command_argument_t argv[state->argc];

    for (arg_idx = 0; arg_idx < state->argc; ++arg_idx) {
        argv[arg_idx].arg = (const char *)(dca + 1);
        argv[arg_idx].arg_len = dca->len;

        dca = (const pr_driver_command_argument_t *)(
            (const uint8_t *)(dca + 1) + dca->len);
    }

    buffer_init(&response, sizeof(*response_header), bp_non_shrinkable);
    comm->handler(cmd_idx,
                  comm->name, comm->name_len,
                  state->argc, argv, &response);

    if (response.user_size < sizeof(*response_header)) {
        LOG_MSG(LOG_LEVEL_FATAL,
                "Comand handler malforms response buffer\n");
        abort();
    }

    response_header = (pr_driver_response_t *)response.data;
    response_header->s.s = PR_DRV_RESPONSE;
    response_header->len = response.user_size - sizeof(*response_header);

    unix_socket_server_send(srv, conn, response.data, response.user_size,
                            (uss_writer_t)writer, core);
    buffer_deinit(&response);
}