rv = alloc_arena_next (h);
alloc_arena_next (h) += nbytes;
- if (rv >= (alloc_arena (h) + alloc_arena_size (h)))
+ if (rv >= alloc_arena_size (h))
os_out_of_memory ();
return (void *) (uword) (rv + alloc_arena (h));
void BV (clib_bihash_free) (BVT (clib_bihash) * h)
{
vec_free (h->working_copies);
+ vec_free (h->working_copy_lengths);
#if BIHASH_32_64_SVM == 0
vec_free (h->freelists);
#else
(void) close (h->memfd);
#endif
clib_mem_vm_free ((void *) (uword) (alloc_arena (h)), alloc_arena_size (h));
- memset (h, 0, sizeof (*h));
+ clib_memset (h, 0, sizeof (*h));
}
static
* if we replace (1<<log2_pages) with vec_len(rv).
* No clue.
*/
- memset (rv, 0xff, sizeof (*rv) * (1 << log2_pages));
+ clib_memset (rv, 0xff, sizeof (*rv) * (1 << log2_pages));
return rv;
}
ASSERT (vec_len (h->freelists) > log2_pages);
if (CLIB_DEBUG > 0)
- memset (v, 0xFE, sizeof (*v) * (1 << log2_pages));
+ clib_memset (v, 0xFE, sizeof (*v) * (1 << log2_pages));
v->next_free_as_u64 = (u64) h->freelists[log2_pages];
h->freelists[log2_pages] = (u64) BV (clib_bihash_get_offset) (h, v);
(h, sizeof (working_copy[0]) * (1 << b->log2_pages));
h->working_copy_lengths[thread_index] = b->log2_pages;
h->working_copies[thread_index] = working_copy;
+
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_working_copy_lost,
+ 1ULL << b->log2_pages);
}
v = BV (clib_bihash_get_value) (h, b->offset);
- clib_memcpy (working_copy, v, sizeof (*v) * (1 << b->log2_pages));
+ clib_memcpy_fast (working_copy, v, sizeof (*v) * (1 << b->log2_pages));
working_bucket.as_u64 = b->as_u64;
working_bucket.offset = BV (clib_bihash_get_offset) (h, working_copy);
CLIB_MEMORY_BARRIER ();
/* Empty slot */
if (BV (clib_bihash_is_free) (&(new_v->kvp[j])))
{
- clib_memcpy (&(new_v->kvp[j]), &(old_values->kvp[i]),
- sizeof (new_v->kvp[j]));
+ clib_memcpy_fast (&(new_v->kvp[j]), &(old_values->kvp[i]),
+ sizeof (new_v->kvp[j]));
goto doublebreak;
}
}
if (BV (clib_bihash_is_free) (&(new_values->kvp[j])))
{
/* Copy the old value and move along */
- clib_memcpy (&(new_values->kvp[j]), &(old_values->kvp[i]),
- sizeof (new_values->kvp[j]));
+ clib_memcpy_fast (&(new_values->kvp[j]), &(old_values->kvp[i]),
+ sizeof (new_values->kvp[j]));
j++;
goto doublebreak;
}
tmp_b.refcnt = 1;
CLIB_MEMORY_BARRIER ();
- b->as_u64 = tmp_b.as_u64;
- BV (clib_bihash_unlock_bucket) (b);
+ b->as_u64 = tmp_b.as_u64; /* unlocks the bucket */
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_alloc_add, 1);
+
return (0);
}
*/
for (i = 0; i < limit; i++)
{
- if (!memcmp (&(v->kvp[i]), &add_v->key, sizeof (add_v->key)))
+ if (BV (clib_bihash_key_compare) (v->kvp[i].key, add_v->key))
{
CLIB_MEMORY_BARRIER (); /* Add a delay */
- clib_memcpy (&(v->kvp[i]), add_v, sizeof (*add_v));
+ clib_memcpy_fast (&(v->kvp[i]), add_v, sizeof (*add_v));
BV (clib_bihash_unlock_bucket) (b);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_replace, 1);
return (0);
}
}
* Copy the value first, so that if a reader manages
* to match the new key, the value will be right...
*/
- clib_memcpy (&(v->kvp[i].value),
- &add_v->value, sizeof (add_v->value));
+ clib_memcpy_fast (&(v->kvp[i].value),
+ &add_v->value, sizeof (add_v->value));
CLIB_MEMORY_BARRIER (); /* Make sure the value has settled */
- clib_memcpy (&(v->kvp[i]), &add_v->key, sizeof (add_v->key));
+ clib_memcpy_fast (&(v->kvp[i]), &add_v->key,
+ sizeof (add_v->key));
b->refcnt++;
ASSERT (b->refcnt > 0);
BV (clib_bihash_unlock_bucket) (b);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_add, 1);
return (0);
}
}
if (is_stale_cb (&(v->kvp[i]), arg))
{
CLIB_MEMORY_BARRIER ();
- clib_memcpy (&(v->kvp[i]), add_v, sizeof (*add_v));
+ clib_memcpy_fast (&(v->kvp[i]), add_v, sizeof (*add_v));
BV (clib_bihash_unlock_bucket) (b);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_replace, 1);
return (0);
}
}
for (i = 0; i < limit; i++)
{
/* Found the key? Kill it... */
- if (!memcmp (&(v->kvp[i]), &add_v->key, sizeof (add_v->key)))
+ if (BV (clib_bihash_key_compare) (v->kvp[i].key, add_v->key))
{
- memset (&(v->kvp[i]), 0xff, sizeof (*(add_v)));
+ clib_memset (&(v->kvp[i]), 0xff, sizeof (*(add_v)));
/* Is the bucket empty? */
if (PREDICT_TRUE (b->refcnt > 1))
{
b->refcnt--;
BV (clib_bihash_unlock_bucket) (b);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_del, 1);
return (0);
}
else /* yes, free it */
v = BV (clib_bihash_get_value) (h, tmp_b.offset);
BV (value_free) (h, v, tmp_b.log2_pages);
BV (clib_bihash_alloc_unlock) (h);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_del_free,
+ 1);
return (0);
}
}
old_log2_pages = h->saved_bucket.log2_pages;
new_log2_pages = old_log2_pages + 1;
mark_bucket_linear = 0;
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_split_add, 1);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_splits, old_log2_pages);
working_copy = h->working_copies[thread_index];
resplit_once = 0;
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_splits, 1);
new_v = BV (split_and_rehash) (h, working_copy, old_log2_pages,
new_log2_pages);
BV (split_and_rehash_linear) (h, working_copy, old_log2_pages,
new_log2_pages);
mark_bucket_linear = 1;
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_linear, 1);
}
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_resplit, 1);
+ BV (clib_bihash_increment_stat) (h, BIHASH_STAT_splits,
+ old_log2_pages + 1);
}
/* Try to add the new entry */
{
if (BV (clib_bihash_is_free) (&(new_v->kvp[i])))
{
- clib_memcpy (&(new_v->kvp[i]), add_v, sizeof (*add_v));
+ clib_memcpy_fast (&(new_v->kvp[i]), add_v, sizeof (*add_v));
goto expand_ok;
}
}
tmp_b.lock = 0;
CLIB_MEMORY_BARRIER ();
b->as_u64 = tmp_b.as_u64;
+ /* free the old bucket */
+ v = BV (clib_bihash_get_value) (h, h->saved_bucket.offset);
+ BV (value_free) (h, v, h->saved_bucket.log2_pages);
BV (clib_bihash_alloc_unlock) (h);
return (0);
}
{
s = format (s, " %d: %U\n",
j * BIHASH_KVP_PER_PAGE + k,
- h->fmt_fn, &(v->kvp[k]));
+ h->fmt_fn, &(v->kvp[k]), verbose);
}
else
{