On 29/05/16 22:52, Sergey Fedorov wrote:
> On 25/05/16 04:13, Emilio G. Cota wrote:
>> +
>> +/* call with head->lock held */
>> +static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
>> +                               struct qht_bucket *head, void *p, uint32_t 
>> hash,
>> +                               bool *needs_resize)
>> +{
>> +    struct qht_bucket *b = head;
>> +    struct qht_bucket *prev = NULL;
>> +    struct qht_bucket *new = NULL;
>> +    int i;
>> +
>> +    for (;;) {
>> +        if (b == NULL) {
>> +            b = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*b));
>> +            memset(b, 0, sizeof(*b));
>> +            new = b;
>> +            atomic_inc(&map->n_added_buckets);
>> +            if (unlikely(qht_map_needs_resize(map)) && needs_resize) {
>> +                *needs_resize = true;
>> +            }
>> +        }
>> +        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
>> +            if (b->pointers[i]) {
>> +                if (unlikely(b->pointers[i] == p)) {
>> +                    return false;
>> +                }
>> +                continue;
>> +            }
>> +            /* found an empty key: acquire the seqlock and write */
>> +            seqlock_write_begin(&head->sequence);
>> +            if (new) {
>> +                atomic_rcu_set(&prev->next, b);
>> +            }
>> +            b->hashes[i] = hash;
>> +            atomic_set(&b->pointers[i], p);
>> +            seqlock_write_end(&head->sequence);
>> +            return true;
>> +        }
>> +        prev = b;
>> +        b = b->next;
>> +    }
>> +}
> Here is my attempt:

static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
                               struct qht_bucket *head, void *p,
uint32_t hash,
                               bool *needs_resize)
{
    struct qht_bucket **bpp = &head, *new;
    int i = 0;

    do {
        while (i < QHT_BUCKET_ENTRIES) {
            if ((*bpp)->pointers[i]) {
                if (unlikely((*bpp)->pointers[i] == p)) {
                    return false;
                }
                i++;
                continue;
            }
            goto found;
        }
        bpp = &(*bpp)->next;
        i = 0;
    } while (*bpp);

    new = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*new));
    memset(new, 0, sizeof(*new));
    atomic_rcu_set(bpp, new);
    atomic_inc(&map->n_added_buckets);
    if (unlikely(qht_map_needs_resize(map)) && needs_resize) {
        *needs_resize = true;
    }
found:
    /* found an empty key: acquire the seqlock and write */
    seqlock_write_begin(&head->sequence);
    (*bpp)->hashes[i] = hash;
    atomic_set(&(*bpp)->pointers[i], p);
    seqlock_write_end(&head->sequence);
    return true;
}

> Feel free to use it as you wish.

Sorry for the chopped email. Hope this one will be better :)

Kind regards,
Sergey

Reply via email to