On Tue, Jan 27, 2015 at 4:44 PM, Geoffrey Blake <geoffrey.bl...@arm.com>
wrote:

> From: Geoffrey Blake <geoffrey.bl...@arm.com>
>
> Signed-off-by: Geoffrey Blake <geoffrey.bl...@arm.com>
>

Reviewed-and-tested-by: Bill Fischofer <bill.fischo...@linaro.org>


> ---
> (This document/code contribution attached is provided under the terms of
> agreement LES-LTM-21309)
>  .../include/odp_buffer_pool_internal.h             | 100
> ++++++++++-----------
>  platform/linux-generic/odp_buffer_pool.c           |   6 +-
>  2 files changed, 52 insertions(+), 54 deletions(-)
>
> diff --git a/platform/linux-generic/include/odp_buffer_pool_internal.h
> b/platform/linux-generic/include/odp_buffer_pool_internal.h
> index d6f44d9..1cc4898 100644
> --- a/platform/linux-generic/include/odp_buffer_pool_internal.h
> +++ b/platform/linux-generic/include/odp_buffer_pool_internal.h
> @@ -107,8 +107,8 @@ struct pool_entry_s {
>         size_t                  pool_size;
>         uint32_t                buf_align;
>         uint32_t                buf_stride;
> -       _odp_atomic_ptr_t       buf_freelist;
> -       _odp_atomic_ptr_t       blk_freelist;
> +       _odp_atomic_tptr_t      buf_freelist;
> +       _odp_atomic_tptr_t      blk_freelist;
>         odp_atomic_u32_t        bufcount;
>         odp_atomic_u32_t        blkcount;
>         odp_atomic_u64_t        bufallocs;
> @@ -142,58 +142,55 @@ extern void *pool_entry_ptr[];
>  #define pool_is_secure(pool) 0
>  #endif
>
> -#define TAG_ALIGN ((size_t)16)
> +#define odp_retag_tptr(ptr) \
> +       _odp_atomic_tptr_settag(&ptr, _odp_atomic_tptr_gettag(&ptr) + 1)
>
> -#define odp_cs(ptr, old, new) \
> -       _odp_atomic_ptr_cmp_xchg_strong(&ptr, (void **)&old, (void *)new, \
> -                                       _ODP_MEMMODEL_SC, \
> -                                       _ODP_MEMMODEL_SC)
> -
> -/* Helper functions for pointer tagging to avoid ABA race conditions */
> -#define odp_tag(ptr) \
> -       (((size_t)ptr) & (TAG_ALIGN - 1))
> +#define odp_get_tptr(ptr) \
> +       _odp_atomic_tptr_getptr(&ptr)
>
> -#define odp_detag(ptr) \
> -       ((void *)(((size_t)ptr) & -TAG_ALIGN))
> -
> -#define odp_retag(ptr, tag) \
> -       ((void *)(((size_t)ptr) | odp_tag(tag)))
> +#define odp_set_tptr(ptr, newptr) \
> +       _odp_atomic_tptr_setptr(&ptr, newptr)
>
> +#define odp_cs_tptr(ptr, old, new) \
> +       _odp_atomic_tptr_cmp_xchg_strong(&ptr, &old, &new, \
> +                                       _ODP_MEMMODEL_SC, \
> +                                       _ODP_MEMMODEL_SC)
>
>  static inline void *get_blk(struct pool_entry_s *pool)
>  {
> -       void *oldhead, *myhead, *newhead;
> +       _odp_atomic_tptr_t oldhead, newhead;
>
> -       oldhead = _odp_atomic_ptr_load(&pool->blk_freelist,
> _ODP_MEMMODEL_ACQ);
> +       oldhead = _odp_atomic_tptr_load(&pool->blk_freelist,
> _ODP_MEMMODEL_ACQ);
>
>         do {
> -               size_t tag = odp_tag(oldhead);
> -               myhead = odp_detag(oldhead);
> -               if (odp_unlikely(myhead == NULL))
> +               if (odp_unlikely(odp_get_tptr(oldhead) == NULL))
>                         break;
> -               newhead = odp_retag(((odp_buf_blk_t *)myhead)->next, tag +
> 1);
> -       } while (odp_cs(pool->blk_freelist, oldhead, newhead) == 0);
> +               newhead = oldhead;
> +               odp_set_tptr(newhead,
> +                            ((odp_buf_blk_t
> *)odp_get_tptr(oldhead))->next);
> +               odp_retag_tptr(newhead);
> +       } while (odp_cs_tptr(pool->blk_freelist, oldhead, newhead) == 0);
>
> -       if (odp_unlikely(myhead == NULL))
> +       if (odp_unlikely(odp_get_tptr(oldhead) == NULL))
>                 odp_atomic_inc_u64(&pool->blkempty);
>         else
>                 odp_atomic_dec_u32(&pool->blkcount);
>
> -       return (void *)myhead;
> +       return (void *)odp_get_tptr(oldhead);
>  }
>
>  static inline void ret_blk(struct pool_entry_s *pool, void *block)
>  {
> -       void *oldhead, *myhead, *myblock;
> +       _odp_atomic_tptr_t oldhead, myblock;
>
> -       oldhead = _odp_atomic_ptr_load(&pool->blk_freelist,
> _ODP_MEMMODEL_ACQ);
> +       oldhead = _odp_atomic_tptr_load(&pool->blk_freelist,
> _ODP_MEMMODEL_ACQ);
>
>         do {
> -               size_t tag = odp_tag(oldhead);
> -               myhead = odp_detag(oldhead);
> -               ((odp_buf_blk_t *)block)->next = myhead;
> -               myblock = odp_retag(block, tag + 1);
> -       } while (odp_cs(pool->blk_freelist, oldhead, myblock) == 0);
> +               myblock = oldhead;
> +               ((odp_buf_blk_t *)block)->next = odp_get_tptr(oldhead);
> +               odp_set_tptr(myblock, block);
> +               odp_retag_tptr(myblock);
> +       } while (odp_cs_tptr(pool->blk_freelist, oldhead, myblock) == 0);
>
>         odp_atomic_inc_u32(&pool->blkcount);
>         odp_atomic_inc_u64(&pool->blkfrees);
> @@ -201,23 +198,26 @@ static inline void ret_blk(struct pool_entry_s
> *pool, void *block)
>
>  static inline odp_buffer_hdr_t *get_buf(struct pool_entry_s *pool)
>  {
> -       odp_buffer_hdr_t *oldhead, *myhead, *newhead;
> +       _odp_atomic_tptr_t oldhead, newhead;
> +       odp_buffer_hdr_t *mybuf = NULL;
>
> -       oldhead = _odp_atomic_ptr_load(&pool->buf_freelist,
> _ODP_MEMMODEL_ACQ);
> +       oldhead = _odp_atomic_tptr_load(&pool->buf_freelist,
> _ODP_MEMMODEL_ACQ);
>
>         do {
> -               size_t tag = odp_tag(oldhead);
> -               myhead = odp_detag(oldhead);
> -               if (odp_unlikely(myhead == NULL))
> +               newhead = oldhead;
> +               if (odp_unlikely(odp_get_tptr(oldhead) == NULL))
>                         break;
> -               newhead = odp_retag(myhead->next, tag + 1);
> -       } while (odp_cs(pool->buf_freelist, oldhead, newhead) == 0);
> +               odp_set_tptr(newhead,
> +                            ((odp_buffer_hdr_t
> *)odp_get_tptr(oldhead))->next);
> +               odp_retag_tptr(newhead);
> +       } while (odp_cs_tptr(pool->buf_freelist, oldhead, newhead) == 0);
>
> -       if (odp_unlikely(myhead == NULL)) {
> +       if (odp_unlikely(odp_get_tptr(oldhead) == NULL)) {
>                 odp_atomic_inc_u64(&pool->bufempty);
>         } else {
>                 uint64_t bufcount =
>                         odp_atomic_fetch_sub_u32(&pool->bufcount, 1) - 1;
> +               mybuf = odp_get_tptr(oldhead);
>
>                 /* Check for low watermark condition */
>                 if (bufcount == pool->low_wm && !pool->low_wm_assert) {
> @@ -226,16 +226,16 @@ static inline odp_buffer_hdr_t *get_buf(struct
> pool_entry_s *pool)
>                 }
>
>                 odp_atomic_inc_u64(&pool->bufallocs);
> -               myhead->next = myhead;  /* Mark buffer allocated */
> -               myhead->allocator = odp_thread_id();
> +               mybuf->next = mybuf;  /* Mark buffer allocated */
> +               mybuf->allocator = odp_thread_id();
>         }
>
> -       return (void *)myhead;
> +       return (void *)mybuf;
>  }
>
>  static inline void ret_buf(struct pool_entry_s *pool, odp_buffer_hdr_t
> *buf)
>  {
> -       odp_buffer_hdr_t *oldhead, *myhead, *mybuf;
> +       _odp_atomic_tptr_t oldhead, newhead;
>
>         buf->allocator = ODP_FREEBUF;  /* Mark buffer free */
>
> @@ -249,14 +249,14 @@ static inline void ret_buf(struct pool_entry_s
> *pool, odp_buffer_hdr_t *buf)
>                 buf->size = 0;
>         }
>
> -       oldhead = _odp_atomic_ptr_load(&pool->buf_freelist,
> _ODP_MEMMODEL_ACQ);
> +       oldhead = _odp_atomic_tptr_load(&pool->buf_freelist,
> _ODP_MEMMODEL_ACQ);
>
>         do {
> -               size_t tag = odp_tag(oldhead);
> -               myhead = odp_detag(oldhead);
> -               buf->next = myhead;
> -               mybuf = odp_retag(buf, tag + 1);
> -       } while (odp_cs(pool->buf_freelist, oldhead, mybuf) == 0);
> +               newhead = oldhead;
> +               buf->next = odp_get_tptr(oldhead);
> +               odp_set_tptr(newhead, buf);
> +               odp_retag_tptr(newhead);
> +       } while (odp_cs_tptr(pool->buf_freelist, oldhead, newhead) == 0);
>
>         uint64_t bufcount = odp_atomic_fetch_add_u32(&pool->bufcount, 1) +
> 1;
>
> diff --git a/platform/linux-generic/odp_buffer_pool.c
> b/platform/linux-generic/odp_buffer_pool.c
> index ac12057..6e35197 100644
> --- a/platform/linux-generic/odp_buffer_pool.c
> +++ b/platform/linux-generic/odp_buffer_pool.c
> @@ -291,10 +291,8 @@ odp_pool_t odp_pool_create(const char *name,
>                 pool->s.pool_mdata_addr = mdata_base_addr;
>
>                 pool->s.buf_stride = buf_stride;
> -               _odp_atomic_ptr_store(&pool->s.buf_freelist, NULL,
> -                                     _ODP_MEMMODEL_RLX);
> -               _odp_atomic_ptr_store(&pool->s.blk_freelist, NULL,
> -                                     _ODP_MEMMODEL_RLX);
> +               _odp_atomic_tptr_init(&pool->s.buf_freelist, NULL);
> +               _odp_atomic_tptr_init(&pool->s.blk_freelist, NULL);
>
>                 /* Initialization will increment these to their target
> vals */
>                 odp_atomic_store_u32(&pool->s.bufcount, 0);
> --
> 1.9.1
>
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to