Esempio n. 1
0
Test(gnix_hashtable_advanced, insert_8K_lookup_128K_random)
{
	int ret, i, index;
	gnix_test_element_t *test_elements;
	gnix_test_element_t *found = NULL, *to_find = NULL;
	gnix_test_element_t *item;
	gnix_bitmap_t allocated = {0};
	int test_size = 8 * 1024;
	int bitmap_size = 64 * test_size;
	int lookups = 128 * 1024;

	test_elements = calloc(test_size, sizeof(gnix_test_element_t));
	cr_assert(test_elements != NULL);

	ret = _gnix_alloc_bitmap(&allocated, bitmap_size);
	cr_assert(ret == 0);

	srand(time(NULL));

	for (i = 0; i < test_size; ++i) {
		do {
			index = rand() % bitmap_size;
		} while (_gnix_test_and_set_bit(&allocated, index));

		item = &test_elements[i];

		item->key = index;
		item->val = rand() % lookups;
		item->magic = __GNIX_MAGIC_VALUE;
	}

	for (i = 0; i < test_size; ++i) {
		item = &test_elements[i];

		ret = _gnix_ht_insert(test_ht,
				item->key, item);
		cr_assert(ret == 0);
		cr_assert(atomic_get(&test_ht->ht_elements) == (i + 1));
	}

	cr_assert(atomic_get(&test_ht->ht_elements) == test_size);

	for (i = 0; i < lookups; ++i) {
		to_find = &test_elements[rand() % test_size];
		found = _gnix_ht_lookup(test_ht, to_find->key);
		cr_assert(found != NULL);
		cr_assert(found == to_find);
		cr_assert(found->magic == __GNIX_MAGIC_VALUE);
	}

	ret = _gnix_free_bitmap(&allocated);
	cr_expect(ret == 0);

	free(test_elements);
}
Esempio n. 2
0
/**
 * Fill all of the fields of an mbox to be returned to the requester.
 *
 * @param[in] handle	Handle to the allocator being used.
 * @param[in] slab	Slab which the mbox is allocated from.
 * @param[in] position	Position of the mbox in the slab.
 * @param[out] ptr	Contains the allocated mbox upon success.
 *
 * @return FI_SUCCESS	Upon successfully filling an mbox with relevant data.
 * @return -FI_EINVAL	Upon receiving invalid input, or finding the bitmap in
 * a corrupted state.
 * @return -FI_ENOMEM	Upon failure to create the mbox structure using calloc.
 */
static int __fill_mbox(struct gnix_mbox_alloc_handle *handle,
		       struct gnix_slab *slab, size_t position,
		       struct gnix_mbox **ptr)
{
	struct gnix_mbox *out;
	int ret = FI_SUCCESS;
	char error_buf[256];
	size_t mapped_size;
	char *error;

	out = calloc(1, sizeof(*out));
	if (!out) {
		error = strerror_r(errno, error_buf, sizeof(error_buf));
		GNIX_WARN(FI_LOG_EP_CTRL,
			  "Error allocating mbox: %s\n",
			  error);
		ret = -FI_ENOMEM;
		goto err_mbox_calloc;
	}

	mapped_size = handle->page_size * __page_count(handle);

	out->slab = slab;
	out->base = slab->base;
	out->offset = (position * handle->mbox_size);
	out->memory_handle = &slab->memory_handle;

	if (out->offset > mapped_size) {
		GNIX_WARN(FI_LOG_EP_CTRL, "Mbox out of bounds.\n");
		ret = -FI_EINVAL;
		goto err_invalid;
	}

	/* On some systems, the page may not be zero'd from first use.
		Memset it here */
	memset((void *) ((uint64_t) out->base + out->offset),
		0x0, handle->mbox_size);

	ret = _gnix_test_and_set_bit(slab->used, position);
	if (ret != 0) {
		GNIX_WARN(FI_LOG_EP_CTRL,
			  "Bit already set when creating mbox.\n");
		ret = -FI_EINVAL;
		goto err_invalid;
	}

	*ptr = out;

	return ret;

err_invalid:
	free(out);
err_mbox_calloc:
	return ret;
}
Esempio n. 3
0
/* Schedule the VC for RX progress. */
int _gnix_vc_rx_schedule(struct gnix_vc *vc)
{
	struct gnix_nic *nic = vc->ep->nic;

	if (!_gnix_test_and_set_bit(&vc->flags, GNIX_VC_FLAG_RX_SCHEDULED)) {
		fastlock_acquire(&nic->rx_vc_lock);
		dlist_insert_tail(&vc->rx_list, &nic->rx_vcs);
		fastlock_release(&nic->rx_vc_lock);
		GNIX_INFO(FI_LOG_EP_CTRL, "Scheduled RX VC (%p)\n", vc);
	}

	return FI_SUCCESS;
}
Esempio n. 4
0
/* Schedule the VC for work progress. */
static int __gnix_vc_work_schedule(struct gnix_vc *vc)
{
	struct gnix_nic *nic = vc->ep->nic;

	/* Don't bother scheduling if there's no work to do. */
	if (slist_empty(&vc->work_queue))
		return FI_SUCCESS;

	if (!_gnix_test_and_set_bit(&vc->flags, GNIX_VC_FLAG_WORK_SCHEDULED)) {
		fastlock_acquire(&nic->work_vc_lock);
		dlist_insert_tail(&vc->work_list, &nic->work_vcs);
		fastlock_release(&nic->work_vc_lock);
		GNIX_INFO(FI_LOG_EP_CTRL, "Scheduled work VC (%p)\n", vc);
	}

	return FI_SUCCESS;
}