From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38065) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b76oe-0006om-Ne for qemu-devel@nongnu.org; Sun, 29 May 2016 15:56:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b76oa-0000k2-JA for qemu-devel@nongnu.org; Sun, 29 May 2016 15:56:03 -0400 Received: from mail-lf0-x242.google.com ([2a00:1450:4010:c07::242]:36530) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b76oa-0000jy-4z for qemu-devel@nongnu.org; Sun, 29 May 2016 15:56:00 -0400 Received: by mail-lf0-x242.google.com with SMTP id h68so5402041lfh.3 for ; Sun, 29 May 2016 12:55:59 -0700 (PDT) From: Sergey Fedorov References: <1464138802-23503-1-git-send-email-cota@braap.org> <1464138802-23503-11-git-send-email-cota@braap.org> <574B487B.5080200@gmail.com> Message-ID: <574B494D.2080602@gmail.com> Date: Sun, 29 May 2016 22:55:57 +0300 MIME-Version: 1.0 In-Reply-To: <574B487B.5080200@gmail.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v6 10/15] qht: QEMU's fast, resizable and scalable Hash Table List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Emilio G. Cota" , QEMU Developers , MTTCG Devel Cc: =?UTF-8?Q?Alex_Benn=c3=a9e?= , Paolo Bonzini , Richard Henderson 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