Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>
---
 platform/linux-generic/Makefile.am                 |   4 +-
 .../linux-generic/include/odp_buffer_inlines.h     |   2 +-
 .../include/odp_buffer_pool_internal.h             | 380 -------------
 .../include/odp_classification_datamodel.h         |   2 +-
 .../linux-generic/include/odp_packet_internal.h    |   2 +-
 platform/linux-generic/include/odp_pool_internal.h | 380 +++++++++++++
 .../linux-generic/include/odp_timer_internal.h     |   2 +-
 platform/linux-generic/odp_buffer.c                |   2 +-
 platform/linux-generic/odp_buffer_pool.c           | 617 ---------------------
 platform/linux-generic/odp_classification.c        |   2 +-
 platform/linux-generic/odp_pool.c                  | 617 +++++++++++++++++++++
 platform/linux-generic/odp_queue.c                 |   2 +-
 platform/linux-generic/odp_timer.c                 |   2 +-
 13 files changed, 1007 insertions(+), 1007 deletions(-)
 delete mode 100644 platform/linux-generic/include/odp_buffer_pool_internal.h
 create mode 100644 platform/linux-generic/include/odp_pool_internal.h
 delete mode 100644 platform/linux-generic/odp_buffer_pool.c
 create mode 100644 platform/linux-generic/odp_pool.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 16adccc..eac8fec 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -105,7 +105,6 @@ noinst_HEADERS = \
                  
${top_srcdir}/platform/linux-generic/include/odp_atomic_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_buffer_inlines.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_buffer_internal.h \
-                 
${top_srcdir}/platform/linux-generic/include/odp_buffer_pool_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_classification_datamodel.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_classification_inlines.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_classification_internal.h \
@@ -116,6 +115,7 @@ noinst_HEADERS = \
                  
${top_srcdir}/platform/linux-generic/include/odp_packet_io_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_packet_io_queue.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_packet_socket.h \
+                 
${top_srcdir}/platform/linux-generic/include/odp_pool_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_queue_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_schedule_internal.h \
                  
${top_srcdir}/platform/linux-generic/include/odp_spin_internal.h \
@@ -137,7 +137,6 @@ subdirheaders_HEADERS = \
 __LIB__libodp_la_SOURCES = \
                           odp_barrier.c \
                           odp_buffer.c \
-                          odp_buffer_pool.c \
                           odp_classification.c \
                           odp_cpumask.c \
                           odp_crypto.c \
@@ -150,6 +149,7 @@ __LIB__libodp_la_SOURCES = \
                           odp_packet_flags.c \
                           odp_packet_io.c \
                           odp_packet_socket.c \
+                          odp_pool.c \
                           odp_queue.c \
                           odp_ring.c \
                           odp_rwlock.c \
diff --git a/platform/linux-generic/include/odp_buffer_inlines.h 
b/platform/linux-generic/include/odp_buffer_inlines.h
index f6eef3d..3ba3941 100644
--- a/platform/linux-generic/include/odp_buffer_inlines.h
+++ b/platform/linux-generic/include/odp_buffer_inlines.h
@@ -18,7 +18,7 @@ extern "C" {
 #endif
 
 #include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 
 static inline odp_buffer_t odp_buffer_encode_handle(odp_buffer_hdr_t *hdr)
 {
diff --git a/platform/linux-generic/include/odp_buffer_pool_internal.h 
b/platform/linux-generic/include/odp_buffer_pool_internal.h
deleted file mode 100644
index c5354e5..0000000
--- a/platform/linux-generic/include/odp_buffer_pool_internal.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-
-/**
- * @file
- *
- * ODP buffer pool - internal header
- */
-
-#ifndef ODP_BUFFER_POOL_INTERNAL_H_
-#define ODP_BUFFER_POOL_INTERNAL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <odp/std_types.h>
-#include <odp/align.h>
-#include <odp_align_internal.h>
-#include <odp/pool.h>
-#include <odp_buffer_internal.h>
-#include <odp/hints.h>
-#include <odp/config.h>
-#include <odp/debug.h>
-#include <odp/shared_memory.h>
-#include <odp/atomic.h>
-#include <odp_atomic_internal.h>
-#include <string.h>
-
-/**
- * Buffer initialization routine prototype
- *
- * @note Routines of this type MAY be passed as part of the
- * _odp_buffer_pool_init_t structure to be called whenever a
- * buffer is allocated to initialize the user metadata
- * associated with that buffer.
- */
-typedef void (_odp_buf_init_t)(odp_buffer_t buf, void *buf_init_arg);
-
-/**
- * Buffer pool initialization parameters
- * Used to communicate buffer pool initialization options. Internal for now.
- */
-typedef struct _odp_buffer_pool_init_t {
-       size_t udata_size;         /**< Size of user metadata for each buffer */
-       _odp_buf_init_t *buf_init; /**< Buffer initialization routine to use */
-       void *buf_init_arg;        /**< Argument to be passed to buf_init() */
-} _odp_buffer_pool_init_t;         /**< Type of buffer initialization struct */
-
-/* Local cache for buffer alloc/free acceleration */
-typedef struct local_cache_t {
-       odp_buffer_hdr_t *buf_freelist;  /* The local cache */
-       uint64_t bufallocs;              /* Local buffer alloc count */
-       uint64_t buffrees;               /* Local buffer free count */
-} local_cache_t;
-
-/* Use ticketlock instead of spinlock */
-#define POOL_USE_TICKETLOCK
-
-/* Extra error checks */
-/* #define POOL_ERROR_CHECK */
-
-
-#ifdef POOL_USE_TICKETLOCK
-#include <odp/ticketlock.h>
-#define POOL_LOCK(a)      odp_ticketlock_lock(a)
-#define POOL_UNLOCK(a)    odp_ticketlock_unlock(a)
-#define POOL_LOCK_INIT(a) odp_ticketlock_init(a)
-#else
-#include <odp/spinlock.h>
-#define POOL_LOCK(a)      odp_spinlock_lock(a)
-#define POOL_UNLOCK(a)    odp_spinlock_unlock(a)
-#define POOL_LOCK_INIT(a) odp_spinlock_init(a)
-#endif
-
-struct pool_entry_s {
-#ifdef POOL_USE_TICKETLOCK
-       odp_ticketlock_t        lock ODP_ALIGNED_CACHE;
-#else
-       odp_spinlock_t          lock ODP_ALIGNED_CACHE;
-#endif
-
-       char                    name[ODP_POOL_NAME_LEN];
-       odp_pool_param_t        params;
-       _odp_buffer_pool_init_t init_params;
-       odp_pool_t              pool_hdl;
-       uint32_t                pool_id;
-       odp_shm_t               pool_shm;
-       union {
-               uint32_t all;
-               struct {
-                       uint32_t has_name:1;
-                       uint32_t user_supplied_shm:1;
-                       uint32_t unsegmented:1;
-                       uint32_t zeroized:1;
-                       uint32_t predefined:1;
-               };
-       } flags;
-       uint32_t                quiesced;
-       uint32_t                low_wm_assert;
-       uint8_t                *pool_base_addr;
-       uint8_t                *pool_mdata_addr;
-       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_u32_t        bufcount;
-       odp_atomic_u32_t        blkcount;
-       odp_atomic_u64_t        bufallocs;
-       odp_atomic_u64_t        buffrees;
-       odp_atomic_u64_t        blkallocs;
-       odp_atomic_u64_t        blkfrees;
-       odp_atomic_u64_t        bufempty;
-       odp_atomic_u64_t        blkempty;
-       odp_atomic_u64_t        high_wm_count;
-       odp_atomic_u64_t        low_wm_count;
-       uint32_t                seg_size;
-       uint32_t                high_wm;
-       uint32_t                low_wm;
-       uint32_t                headroom;
-       uint32_t                tailroom;
-};
-
-typedef union pool_entry_u {
-       struct pool_entry_s s;
-
-       uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))];
-} pool_entry_t;
-
-extern void *pool_entry_ptr[];
-
-#if defined(ODP_CONFIG_SECURE_POOLS) && (ODP_CONFIG_SECURE_POOLS == 1)
-#define buffer_is_secure(buf) (buf->flags.zeroized)
-#define pool_is_secure(pool) (pool->flags.zeroized)
-#else
-#define buffer_is_secure(buf) 0
-#define pool_is_secure(pool) 0
-#endif
-
-#define TAG_ALIGN ((size_t)16)
-
-#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_detag(ptr) \
-       ((void *)(((size_t)ptr) & -TAG_ALIGN))
-
-#define odp_retag(ptr, tag) \
-       ((void *)(((size_t)ptr) | odp_tag(tag)))
-
-
-static inline void *get_blk(struct pool_entry_s *pool)
-{
-       void *oldhead, *myhead, *newhead;
-
-       oldhead = _odp_atomic_ptr_load(&pool->blk_freelist, _ODP_MEMMODEL_ACQ);
-
-       do {
-               size_t tag = odp_tag(oldhead);
-               myhead = odp_detag(oldhead);
-               if (odp_unlikely(myhead == NULL))
-                       break;
-               newhead = odp_retag(((odp_buf_blk_t *)myhead)->next, tag + 1);
-       } while (odp_cs(pool->blk_freelist, oldhead, newhead) == 0);
-
-       if (odp_unlikely(myhead == NULL))
-               odp_atomic_inc_u64(&pool->blkempty);
-       else
-               odp_atomic_dec_u32(&pool->blkcount);
-
-       return (void *)myhead;
-}
-
-static inline void ret_blk(struct pool_entry_s *pool, void *block)
-{
-       void *oldhead, *myhead, *myblock;
-
-       oldhead = _odp_atomic_ptr_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);
-
-       odp_atomic_inc_u32(&pool->blkcount);
-       odp_atomic_inc_u64(&pool->blkfrees);
-}
-
-static inline odp_buffer_hdr_t *get_buf(struct pool_entry_s *pool)
-{
-       odp_buffer_hdr_t *oldhead, *myhead, *newhead;
-
-       oldhead = _odp_atomic_ptr_load(&pool->buf_freelist, _ODP_MEMMODEL_ACQ);
-
-       do {
-               size_t tag = odp_tag(oldhead);
-               myhead = odp_detag(oldhead);
-               if (odp_unlikely(myhead == NULL))
-                       break;
-               newhead = odp_retag(myhead->next, tag + 1);
-       } while (odp_cs(pool->buf_freelist, oldhead, newhead) == 0);
-
-       if (odp_unlikely(myhead == NULL)) {
-               odp_atomic_inc_u64(&pool->bufempty);
-       } else {
-               uint64_t bufcount =
-                       odp_atomic_fetch_sub_u32(&pool->bufcount, 1) - 1;
-
-               /* Check for low watermark condition */
-               if (bufcount == pool->low_wm && !pool->low_wm_assert) {
-                       pool->low_wm_assert = 1;
-                       odp_atomic_inc_u64(&pool->low_wm_count);
-               }
-
-               odp_atomic_inc_u64(&pool->bufallocs);
-               myhead->next = myhead;  /* Mark buffer allocated */
-               myhead->allocator = odp_thread_id();
-       }
-
-       return (void *)myhead;
-}
-
-static inline void ret_buf(struct pool_entry_s *pool, odp_buffer_hdr_t *buf)
-{
-       odp_buffer_hdr_t *oldhead, *myhead, *mybuf;
-
-       buf->allocator = ODP_FREEBUF;  /* Mark buffer free */
-
-       if (!buf->flags.hdrdata && buf->type != ODP_EVENT_BUFFER) {
-               while (buf->segcount > 0) {
-                       if (buffer_is_secure(buf) || pool_is_secure(pool))
-                               memset(buf->addr[buf->segcount - 1],
-                                      0, buf->segsize);
-                       ret_blk(pool, buf->addr[--buf->segcount]);
-               }
-               buf->size = 0;
-       }
-
-       oldhead = _odp_atomic_ptr_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);
-
-       uint64_t bufcount = odp_atomic_fetch_add_u32(&pool->bufcount, 1) + 1;
-
-       /* Check if low watermark condition should be deasserted */
-       if (bufcount == pool->high_wm && pool->low_wm_assert) {
-               pool->low_wm_assert = 0;
-               odp_atomic_inc_u64(&pool->high_wm_count);
-       }
-
-       odp_atomic_inc_u64(&pool->buffrees);
-}
-
-static inline void *get_local_buf(local_cache_t *buf_cache,
-                                 struct pool_entry_s *pool,
-                                 size_t totsize)
-{
-       odp_buffer_hdr_t *buf = buf_cache->buf_freelist;
-
-       if (odp_likely(buf != NULL)) {
-               buf_cache->buf_freelist = buf->next;
-
-               if (odp_unlikely(buf->size < totsize)) {
-                       intmax_t needed = totsize - buf->size;
-
-                       do {
-                               void *blk = get_blk(pool);
-                               if (odp_unlikely(blk == NULL)) {
-                                       ret_buf(pool, buf);
-                                       buf_cache->buffrees--;
-                                       return NULL;
-                               }
-                               buf->addr[buf->segcount++] = blk;
-                               needed -= pool->seg_size;
-                       } while (needed > 0);
-
-                       buf->size = buf->segcount * pool->seg_size;
-               }
-
-               buf_cache->bufallocs++;
-               buf->allocator = odp_thread_id();  /* Mark buffer allocated */
-       }
-
-       return buf;
-}
-
-static inline void ret_local_buf(local_cache_t *buf_cache,
-                               odp_buffer_hdr_t *buf)
-{
-       buf->allocator = ODP_FREEBUF;
-       buf->next = buf_cache->buf_freelist;
-       buf_cache->buf_freelist = buf;
-
-       buf_cache->buffrees++;
-}
-
-static inline void flush_cache(local_cache_t *buf_cache,
-                              struct pool_entry_s *pool)
-{
-       odp_buffer_hdr_t *buf = buf_cache->buf_freelist;
-       uint32_t flush_count = 0;
-
-       while (buf != NULL) {
-               odp_buffer_hdr_t *next = buf->next;
-               ret_buf(pool, buf);
-               buf = next;
-               flush_count++;
-       }
-
-       odp_atomic_add_u64(&pool->bufallocs, buf_cache->bufallocs);
-       odp_atomic_add_u64(&pool->buffrees, buf_cache->buffrees - flush_count);
-
-       buf_cache->buf_freelist = NULL;
-       buf_cache->bufallocs = 0;
-       buf_cache->buffrees = 0;
-}
-
-static inline odp_pool_t pool_index_to_handle(uint32_t pool_id)
-{
-       return _odp_cast_scalar(odp_pool_t, pool_id);
-}
-
-static inline uint32_t pool_handle_to_index(odp_pool_t pool_hdl)
-{
-       return _odp_typeval(pool_hdl);
-}
-
-static inline void *get_pool_entry(uint32_t pool_id)
-{
-       return pool_entry_ptr[pool_id];
-}
-
-static inline pool_entry_t *odp_pool_to_entry(odp_pool_t pool)
-{
-       return (pool_entry_t *)get_pool_entry(pool_handle_to_index(pool));
-}
-
-static inline pool_entry_t *odp_buf_to_pool(odp_buffer_hdr_t *buf)
-{
-       return odp_pool_to_entry(buf->pool_hdl);
-}
-
-static inline uint32_t odp_buffer_pool_segment_size(odp_pool_t pool)
-{
-       return odp_pool_to_entry(pool)->s.seg_size;
-}
-
-static inline uint32_t odp_buffer_pool_headroom(odp_pool_t pool)
-{
-       return odp_pool_to_entry(pool)->s.headroom;
-}
-
-static inline uint32_t odp_buffer_pool_tailroom(odp_pool_t pool)
-{
-       return odp_pool_to_entry(pool)->s.tailroom;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h 
b/platform/linux-generic/include/odp_classification_datamodel.h
index 83500b0..6f9e1b8 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -21,7 +21,7 @@ extern "C" {
 
 #include <odp/spinlock.h>
 #include <odp/classification.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
 #include <odp_queue_internal.h>
diff --git a/platform/linux-generic/include/odp_packet_internal.h 
b/platform/linux-generic/include/odp_packet_internal.h
index bbc105a..c3dcdd8 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -21,7 +21,7 @@ extern "C" {
 #include <odp/align.h>
 #include <odp/debug.h>
 #include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp_buffer_inlines.h>
 #include <odp/packet.h>
 #include <odp/packet_io.h>
diff --git a/platform/linux-generic/include/odp_pool_internal.h 
b/platform/linux-generic/include/odp_pool_internal.h
new file mode 100644
index 0000000..46c2961
--- /dev/null
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -0,0 +1,380 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP buffer pool - internal header
+ */
+
+#ifndef ODP_POOL_INTERNAL_H_
+#define ODP_POOL_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/std_types.h>
+#include <odp/align.h>
+#include <odp_align_internal.h>
+#include <odp/pool.h>
+#include <odp_buffer_internal.h>
+#include <odp/hints.h>
+#include <odp/config.h>
+#include <odp/debug.h>
+#include <odp/shared_memory.h>
+#include <odp/atomic.h>
+#include <odp_atomic_internal.h>
+#include <string.h>
+
+/**
+ * Buffer initialization routine prototype
+ *
+ * @note Routines of this type MAY be passed as part of the
+ * _odp_buffer_pool_init_t structure to be called whenever a
+ * buffer is allocated to initialize the user metadata
+ * associated with that buffer.
+ */
+typedef void (_odp_buf_init_t)(odp_buffer_t buf, void *buf_init_arg);
+
+/**
+ * Buffer pool initialization parameters
+ * Used to communicate buffer pool initialization options. Internal for now.
+ */
+typedef struct _odp_buffer_pool_init_t {
+       size_t udata_size;         /**< Size of user metadata for each buffer */
+       _odp_buf_init_t *buf_init; /**< Buffer initialization routine to use */
+       void *buf_init_arg;        /**< Argument to be passed to buf_init() */
+} _odp_buffer_pool_init_t;         /**< Type of buffer initialization struct */
+
+/* Local cache for buffer alloc/free acceleration */
+typedef struct local_cache_t {
+       odp_buffer_hdr_t *buf_freelist;  /* The local cache */
+       uint64_t bufallocs;              /* Local buffer alloc count */
+       uint64_t buffrees;               /* Local buffer free count */
+} local_cache_t;
+
+/* Use ticketlock instead of spinlock */
+#define POOL_USE_TICKETLOCK
+
+/* Extra error checks */
+/* #define POOL_ERROR_CHECK */
+
+
+#ifdef POOL_USE_TICKETLOCK
+#include <odp/ticketlock.h>
+#define POOL_LOCK(a)      odp_ticketlock_lock(a)
+#define POOL_UNLOCK(a)    odp_ticketlock_unlock(a)
+#define POOL_LOCK_INIT(a) odp_ticketlock_init(a)
+#else
+#include <odp/spinlock.h>
+#define POOL_LOCK(a)      odp_spinlock_lock(a)
+#define POOL_UNLOCK(a)    odp_spinlock_unlock(a)
+#define POOL_LOCK_INIT(a) odp_spinlock_init(a)
+#endif
+
+struct pool_entry_s {
+#ifdef POOL_USE_TICKETLOCK
+       odp_ticketlock_t        lock ODP_ALIGNED_CACHE;
+#else
+       odp_spinlock_t          lock ODP_ALIGNED_CACHE;
+#endif
+
+       char                    name[ODP_POOL_NAME_LEN];
+       odp_pool_param_t        params;
+       _odp_buffer_pool_init_t init_params;
+       odp_pool_t              pool_hdl;
+       uint32_t                pool_id;
+       odp_shm_t               pool_shm;
+       union {
+               uint32_t all;
+               struct {
+                       uint32_t has_name:1;
+                       uint32_t user_supplied_shm:1;
+                       uint32_t unsegmented:1;
+                       uint32_t zeroized:1;
+                       uint32_t predefined:1;
+               };
+       } flags;
+       uint32_t                quiesced;
+       uint32_t                low_wm_assert;
+       uint8_t                *pool_base_addr;
+       uint8_t                *pool_mdata_addr;
+       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_u32_t        bufcount;
+       odp_atomic_u32_t        blkcount;
+       odp_atomic_u64_t        bufallocs;
+       odp_atomic_u64_t        buffrees;
+       odp_atomic_u64_t        blkallocs;
+       odp_atomic_u64_t        blkfrees;
+       odp_atomic_u64_t        bufempty;
+       odp_atomic_u64_t        blkempty;
+       odp_atomic_u64_t        high_wm_count;
+       odp_atomic_u64_t        low_wm_count;
+       uint32_t                seg_size;
+       uint32_t                high_wm;
+       uint32_t                low_wm;
+       uint32_t                headroom;
+       uint32_t                tailroom;
+};
+
+typedef union pool_entry_u {
+       struct pool_entry_s s;
+
+       uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pool_entry_s))];
+} pool_entry_t;
+
+extern void *pool_entry_ptr[];
+
+#if defined(ODP_CONFIG_SECURE_POOLS) && (ODP_CONFIG_SECURE_POOLS == 1)
+#define buffer_is_secure(buf) (buf->flags.zeroized)
+#define pool_is_secure(pool) (pool->flags.zeroized)
+#else
+#define buffer_is_secure(buf) 0
+#define pool_is_secure(pool) 0
+#endif
+
+#define TAG_ALIGN ((size_t)16)
+
+#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_detag(ptr) \
+       ((void *)(((size_t)ptr) & -TAG_ALIGN))
+
+#define odp_retag(ptr, tag) \
+       ((void *)(((size_t)ptr) | odp_tag(tag)))
+
+
+static inline void *get_blk(struct pool_entry_s *pool)
+{
+       void *oldhead, *myhead, *newhead;
+
+       oldhead = _odp_atomic_ptr_load(&pool->blk_freelist, _ODP_MEMMODEL_ACQ);
+
+       do {
+               size_t tag = odp_tag(oldhead);
+               myhead = odp_detag(oldhead);
+               if (odp_unlikely(myhead == NULL))
+                       break;
+               newhead = odp_retag(((odp_buf_blk_t *)myhead)->next, tag + 1);
+       } while (odp_cs(pool->blk_freelist, oldhead, newhead) == 0);
+
+       if (odp_unlikely(myhead == NULL))
+               odp_atomic_inc_u64(&pool->blkempty);
+       else
+               odp_atomic_dec_u32(&pool->blkcount);
+
+       return (void *)myhead;
+}
+
+static inline void ret_blk(struct pool_entry_s *pool, void *block)
+{
+       void *oldhead, *myhead, *myblock;
+
+       oldhead = _odp_atomic_ptr_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);
+
+       odp_atomic_inc_u32(&pool->blkcount);
+       odp_atomic_inc_u64(&pool->blkfrees);
+}
+
+static inline odp_buffer_hdr_t *get_buf(struct pool_entry_s *pool)
+{
+       odp_buffer_hdr_t *oldhead, *myhead, *newhead;
+
+       oldhead = _odp_atomic_ptr_load(&pool->buf_freelist, _ODP_MEMMODEL_ACQ);
+
+       do {
+               size_t tag = odp_tag(oldhead);
+               myhead = odp_detag(oldhead);
+               if (odp_unlikely(myhead == NULL))
+                       break;
+               newhead = odp_retag(myhead->next, tag + 1);
+       } while (odp_cs(pool->buf_freelist, oldhead, newhead) == 0);
+
+       if (odp_unlikely(myhead == NULL)) {
+               odp_atomic_inc_u64(&pool->bufempty);
+       } else {
+               uint64_t bufcount =
+                       odp_atomic_fetch_sub_u32(&pool->bufcount, 1) - 1;
+
+               /* Check for low watermark condition */
+               if (bufcount == pool->low_wm && !pool->low_wm_assert) {
+                       pool->low_wm_assert = 1;
+                       odp_atomic_inc_u64(&pool->low_wm_count);
+               }
+
+               odp_atomic_inc_u64(&pool->bufallocs);
+               myhead->next = myhead;  /* Mark buffer allocated */
+               myhead->allocator = odp_thread_id();
+       }
+
+       return (void *)myhead;
+}
+
+static inline void ret_buf(struct pool_entry_s *pool, odp_buffer_hdr_t *buf)
+{
+       odp_buffer_hdr_t *oldhead, *myhead, *mybuf;
+
+       buf->allocator = ODP_FREEBUF;  /* Mark buffer free */
+
+       if (!buf->flags.hdrdata && buf->type != ODP_EVENT_BUFFER) {
+               while (buf->segcount > 0) {
+                       if (buffer_is_secure(buf) || pool_is_secure(pool))
+                               memset(buf->addr[buf->segcount - 1],
+                                      0, buf->segsize);
+                       ret_blk(pool, buf->addr[--buf->segcount]);
+               }
+               buf->size = 0;
+       }
+
+       oldhead = _odp_atomic_ptr_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);
+
+       uint64_t bufcount = odp_atomic_fetch_add_u32(&pool->bufcount, 1) + 1;
+
+       /* Check if low watermark condition should be deasserted */
+       if (bufcount == pool->high_wm && pool->low_wm_assert) {
+               pool->low_wm_assert = 0;
+               odp_atomic_inc_u64(&pool->high_wm_count);
+       }
+
+       odp_atomic_inc_u64(&pool->buffrees);
+}
+
+static inline void *get_local_buf(local_cache_t *buf_cache,
+                                 struct pool_entry_s *pool,
+                                 size_t totsize)
+{
+       odp_buffer_hdr_t *buf = buf_cache->buf_freelist;
+
+       if (odp_likely(buf != NULL)) {
+               buf_cache->buf_freelist = buf->next;
+
+               if (odp_unlikely(buf->size < totsize)) {
+                       intmax_t needed = totsize - buf->size;
+
+                       do {
+                               void *blk = get_blk(pool);
+                               if (odp_unlikely(blk == NULL)) {
+                                       ret_buf(pool, buf);
+                                       buf_cache->buffrees--;
+                                       return NULL;
+                               }
+                               buf->addr[buf->segcount++] = blk;
+                               needed -= pool->seg_size;
+                       } while (needed > 0);
+
+                       buf->size = buf->segcount * pool->seg_size;
+               }
+
+               buf_cache->bufallocs++;
+               buf->allocator = odp_thread_id();  /* Mark buffer allocated */
+       }
+
+       return buf;
+}
+
+static inline void ret_local_buf(local_cache_t *buf_cache,
+                               odp_buffer_hdr_t *buf)
+{
+       buf->allocator = ODP_FREEBUF;
+       buf->next = buf_cache->buf_freelist;
+       buf_cache->buf_freelist = buf;
+
+       buf_cache->buffrees++;
+}
+
+static inline void flush_cache(local_cache_t *buf_cache,
+                              struct pool_entry_s *pool)
+{
+       odp_buffer_hdr_t *buf = buf_cache->buf_freelist;
+       uint32_t flush_count = 0;
+
+       while (buf != NULL) {
+               odp_buffer_hdr_t *next = buf->next;
+               ret_buf(pool, buf);
+               buf = next;
+               flush_count++;
+       }
+
+       odp_atomic_add_u64(&pool->bufallocs, buf_cache->bufallocs);
+       odp_atomic_add_u64(&pool->buffrees, buf_cache->buffrees - flush_count);
+
+       buf_cache->buf_freelist = NULL;
+       buf_cache->bufallocs = 0;
+       buf_cache->buffrees = 0;
+}
+
+static inline odp_pool_t pool_index_to_handle(uint32_t pool_id)
+{
+       return _odp_cast_scalar(odp_pool_t, pool_id);
+}
+
+static inline uint32_t pool_handle_to_index(odp_pool_t pool_hdl)
+{
+       return _odp_typeval(pool_hdl);
+}
+
+static inline void *get_pool_entry(uint32_t pool_id)
+{
+       return pool_entry_ptr[pool_id];
+}
+
+static inline pool_entry_t *odp_pool_to_entry(odp_pool_t pool)
+{
+       return (pool_entry_t *)get_pool_entry(pool_handle_to_index(pool));
+}
+
+static inline pool_entry_t *odp_buf_to_pool(odp_buffer_hdr_t *buf)
+{
+       return odp_pool_to_entry(buf->pool_hdl);
+}
+
+static inline uint32_t odp_buffer_pool_segment_size(odp_pool_t pool)
+{
+       return odp_pool_to_entry(pool)->s.seg_size;
+}
+
+static inline uint32_t odp_buffer_pool_headroom(odp_pool_t pool)
+{
+       return odp_pool_to_entry(pool)->s.headroom;
+}
+
+static inline uint32_t odp_buffer_pool_tailroom(odp_pool_t pool)
+{
+       return odp_pool_to_entry(pool)->s.tailroom;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp_timer_internal.h 
b/platform/linux-generic/include/odp_timer_internal.h
index 588eb6b..90af62c 100644
--- a/platform/linux-generic/include/odp_timer_internal.h
+++ b/platform/linux-generic/include/odp_timer_internal.h
@@ -17,7 +17,7 @@
 #include <odp/align.h>
 #include <odp/debug.h>
 #include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp/timer.h>
 
 /**
diff --git a/platform/linux-generic/odp_buffer.c 
b/platform/linux-generic/odp_buffer.c
index 5d51c21..a9d0e24 100644
--- a/platform/linux-generic/odp_buffer.c
+++ b/platform/linux-generic/odp_buffer.c
@@ -5,7 +5,7 @@
  */
 
 #include <odp/buffer.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp_buffer_internal.h>
 #include <odp_buffer_inlines.h>
 #include <odp_debug_internal.h>
diff --git a/platform/linux-generic/odp_buffer_pool.c 
b/platform/linux-generic/odp_buffer_pool.c
deleted file mode 100644
index f8e35b4..0000000
--- a/platform/linux-generic/odp_buffer_pool.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-#include <odp/std_types.h>
-#include <odp/pool.h>
-#include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
-#include <odp_buffer_inlines.h>
-#include <odp_packet_internal.h>
-#include <odp_timer_internal.h>
-#include <odp_align_internal.h>
-#include <odp/shared_memory.h>
-#include <odp/align.h>
-#include <odp_internal.h>
-#include <odp/config.h>
-#include <odp/hints.h>
-#include <odp_debug_internal.h>
-#include <odp_atomic_internal.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-
-#if ODP_CONFIG_POOLS > ODP_BUFFER_MAX_POOLS
-#error ODP_CONFIG_POOLS > ODP_BUFFER_MAX_POOLS
-#endif
-
-
-typedef union buffer_type_any_u {
-       odp_buffer_hdr_t  buf;
-       odp_packet_hdr_t  pkt;
-       odp_timeout_hdr_t tmo;
-} odp_anybuf_t;
-
-_ODP_STATIC_ASSERT((sizeof(union buffer_type_any_u) % 8) == 0,
-                  "BUFFER_TYPE_ANY_U__SIZE_ERR");
-
-/* Any buffer type header */
-typedef struct {
-       union buffer_type_any_u any_hdr;    /* any buffer type */
-} odp_any_buffer_hdr_t;
-
-typedef struct odp_any_hdr_stride {
-       uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(odp_any_buffer_hdr_t))];
-} odp_any_hdr_stride;
-
-
-typedef struct pool_table_t {
-       pool_entry_t pool[ODP_CONFIG_POOLS];
-} pool_table_t;
-
-
-/* The pool table */
-static pool_table_t *pool_tbl;
-
-/* Pool entry pointers (for inlining) */
-void *pool_entry_ptr[ODP_CONFIG_POOLS];
-
-/* Local cache for buffer alloc/free acceleration */
-static __thread local_cache_t local_cache[ODP_CONFIG_POOLS];
-
-int odp_buffer_pool_init_global(void)
-{
-       uint32_t i;
-       odp_shm_t shm;
-
-       shm = odp_shm_reserve("odp_buffer_pools",
-                             sizeof(pool_table_t),
-                             sizeof(pool_entry_t), 0);
-
-       pool_tbl = odp_shm_addr(shm);
-
-       if (pool_tbl == NULL)
-               return -1;
-
-       memset(pool_tbl, 0, sizeof(pool_table_t));
-
-       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
-               /* init locks */
-               pool_entry_t *pool = &pool_tbl->pool[i];
-               POOL_LOCK_INIT(&pool->s.lock);
-               pool->s.pool_hdl = pool_index_to_handle(i);
-               pool->s.pool_id = i;
-               pool_entry_ptr[i] = pool;
-       }
-
-       ODP_DBG("\nBuffer pool init global\n");
-       ODP_DBG("  pool_entry_s size     %zu\n", sizeof(struct pool_entry_s));
-       ODP_DBG("  pool_entry_t size     %zu\n", sizeof(pool_entry_t));
-       ODP_DBG("  odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t));
-       ODP_DBG("\n");
-       return 0;
-}
-
-/**
- * Pool creation
- */
-
-odp_pool_t odp_pool_create(const char *name,
-                          odp_shm_t shm,
-                          odp_pool_param_t *params)
-{
-       odp_pool_t pool_hdl = ODP_POOL_INVALID;
-       pool_entry_t *pool;
-       uint32_t i, headroom = 0, tailroom = 0;
-
-       /* Default size and align for timeouts */
-       if (params->type == ODP_POOL_TIMEOUT) {
-               params->buf.size  = 0; /* tmo.__res1 */
-               params->buf.align = 0; /* tmo.__res2 */
-       }
-
-       /* Default initialization paramters */
-       static _odp_buffer_pool_init_t default_init_params = {
-               .udata_size = 0,
-               .buf_init = NULL,
-               .buf_init_arg = NULL,
-       };
-
-       _odp_buffer_pool_init_t *init_params = &default_init_params;
-
-       if (params == NULL)
-               return ODP_POOL_INVALID;
-
-       /* Restriction for v1.0: All non-packet buffers are unsegmented */
-       int unseg = 1;
-
-       /* Restriction for v1.0: No zeroization support */
-       const int zeroized = 0;
-
-       /* Restriction for v1.0: No udata support */
-       uint32_t udata_stride = (init_params->udata_size > sizeof(void *)) ?
-               ODP_CACHE_LINE_SIZE_ROUNDUP(init_params->udata_size) :
-               0;
-
-       uint32_t blk_size, buf_stride;
-       uint32_t buf_align;
-
-       if (params->type == ODP_POOL_PACKET)
-               buf_align = 0;
-       else
-               buf_align = params->buf.align;
-
-       /* Validate requested buffer alignment */
-       if (buf_align > ODP_CONFIG_BUFFER_ALIGN_MAX ||
-           buf_align != ODP_ALIGN_ROUNDDOWN_POWER_2(buf_align, buf_align))
-               return ODP_POOL_INVALID;
-
-       /* Set correct alignment based on input request */
-       if (buf_align == 0)
-               buf_align = ODP_CACHE_LINE_SIZE;
-       else if (buf_align < ODP_CONFIG_BUFFER_ALIGN_MIN)
-               buf_align = ODP_CONFIG_BUFFER_ALIGN_MIN;
-
-       /* Calculate space needed for buffer blocks and metadata */
-       switch (params->type) {
-       case ODP_POOL_BUFFER:
-       case ODP_POOL_TIMEOUT:
-               blk_size = params->buf.size;
-
-               /* Optimize small raw buffers */
-               if (blk_size > ODP_MAX_INLINE_BUF || params->buf.align != 0)
-                       blk_size = ODP_ALIGN_ROUNDUP(blk_size, buf_align);
-
-               buf_stride = params->type == ODP_POOL_BUFFER ?
-                       sizeof(odp_buffer_hdr_stride) :
-                       sizeof(odp_timeout_hdr_stride);
-               break;
-
-       case ODP_POOL_PACKET:
-               headroom = ODP_CONFIG_PACKET_HEADROOM;
-               tailroom = ODP_CONFIG_PACKET_TAILROOM;
-               unseg = params->pkt.seg_len > ODP_CONFIG_PACKET_BUF_LEN_MAX;
-
-               if (unseg)
-                       blk_size = ODP_ALIGN_ROUNDUP(
-                               headroom + params->pkt.seg_len + tailroom,
-                               buf_align);
-               else
-                       blk_size = ODP_ALIGN_ROUNDUP(
-                               headroom + params->pkt.seg_len + tailroom,
-                               ODP_CONFIG_PACKET_SEG_LEN_MIN);
-
-               buf_stride = params->type == ODP_POOL_PACKET ?
-                       sizeof(odp_packet_hdr_stride) :
-                       sizeof(odp_any_hdr_stride);
-               break;
-
-       default:
-               return ODP_POOL_INVALID;
-       }
-
-       /* Validate requested number of buffers against addressable limits */
-       if (params->buf.num >
-           (ODP_BUFFER_MAX_BUFFERS / (buf_stride / ODP_CACHE_LINE_SIZE)))
-               return ODP_POOL_INVALID;
-
-       /* Find an unused buffer pool slot and iniitalize it as requested */
-       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
-               pool = get_pool_entry(i);
-
-               POOL_LOCK(&pool->s.lock);
-               if (pool->s.pool_shm != ODP_SHM_INVALID) {
-                       POOL_UNLOCK(&pool->s.lock);
-                       continue;
-               }
-
-               /* found free pool */
-               size_t block_size, pad_size, mdata_size, udata_size;
-
-               pool->s.flags.all = 0;
-
-               if (name == NULL) {
-                       pool->s.name[0] = 0;
-               } else {
-                       strncpy(pool->s.name, name,
-                               ODP_POOL_NAME_LEN - 1);
-                       pool->s.name[ODP_POOL_NAME_LEN - 1] = 0;
-                       pool->s.flags.has_name = 1;
-               }
-
-               pool->s.params = *params;
-               pool->s.init_params = *init_params;
-               pool->s.buf_align = buf_align;
-
-               /* Optimize for short buffers: Data stored in buffer hdr */
-               if (blk_size <= ODP_MAX_INLINE_BUF) {
-                       block_size = 0;
-                       pool->s.buf_align = blk_size == 0 ? 0 : sizeof(void *);
-               } else {
-                       block_size = params->buf.num * blk_size;
-                       pool->s.buf_align = buf_align;
-               }
-
-               pad_size = ODP_CACHE_LINE_SIZE_ROUNDUP(block_size) - block_size;
-               mdata_size = params->buf.num * buf_stride;
-               udata_size = params->buf.num * udata_stride;
-
-               pool->s.pool_size = ODP_PAGE_SIZE_ROUNDUP(block_size +
-                                                         pad_size +
-                                                         mdata_size +
-                                                         udata_size);
-
-               if (shm == ODP_SHM_NULL) {
-                       shm = odp_shm_reserve(pool->s.name,
-                                             pool->s.pool_size,
-                                             ODP_PAGE_SIZE, 0);
-                       if (shm == ODP_SHM_INVALID) {
-                               POOL_UNLOCK(&pool->s.lock);
-                               return ODP_POOL_INVALID;
-                       }
-                       pool->s.pool_base_addr = odp_shm_addr(shm);
-               } else {
-                       odp_shm_info_t info;
-                       if (odp_shm_info(shm, &info) != 0 ||
-                           info.size < pool->s.pool_size) {
-                               POOL_UNLOCK(&pool->s.lock);
-                               return ODP_POOL_INVALID;
-                       }
-                       pool->s.pool_base_addr = odp_shm_addr(shm);
-                       void *page_addr =
-                               ODP_ALIGN_ROUNDUP_PTR(pool->s.pool_base_addr,
-                                                     ODP_PAGE_SIZE);
-                       if (pool->s.pool_base_addr != page_addr) {
-                               if (info.size < pool->s.pool_size +
-                                   ((size_t)page_addr -
-                                    (size_t)pool->s.pool_base_addr)) {
-                                       POOL_UNLOCK(&pool->s.lock);
-                                       return ODP_POOL_INVALID;
-                               }
-                               pool->s.pool_base_addr = page_addr;
-                       }
-                       pool->s.flags.user_supplied_shm = 1;
-               }
-
-               pool->s.pool_shm = shm;
-
-               /* Now safe to unlock since pool entry has been allocated */
-               POOL_UNLOCK(&pool->s.lock);
-
-               pool->s.flags.unsegmented = unseg;
-               pool->s.flags.zeroized = zeroized;
-               pool->s.seg_size = unseg ?
-                       blk_size : ODP_CONFIG_PACKET_SEG_LEN_MIN;
-
-
-               uint8_t *block_base_addr = pool->s.pool_base_addr;
-               uint8_t *mdata_base_addr =
-                       block_base_addr + block_size + pad_size;
-               uint8_t *udata_base_addr = mdata_base_addr + mdata_size;
-
-               /* Pool mdata addr is used for indexing buffer metadata */
-               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);
-
-               /* Initialization will increment these to their target vals */
-               odp_atomic_store_u32(&pool->s.bufcount, 0);
-               odp_atomic_store_u32(&pool->s.blkcount, 0);
-
-               uint8_t *buf = udata_base_addr - buf_stride;
-               uint8_t *udat = udata_stride == 0 ? NULL :
-                       block_base_addr - udata_stride;
-
-               /* Init buffer common header and add to pool buffer freelist */
-               do {
-                       odp_buffer_hdr_t *tmp =
-                               (odp_buffer_hdr_t *)(void *)buf;
-
-                       /* Iniitalize buffer metadata */
-                       tmp->allocator = ODP_FREEBUF;
-                       tmp->flags.all = 0;
-                       tmp->flags.zeroized = zeroized;
-                       tmp->size = 0;
-                       odp_atomic_store_u32(&tmp->ref_count, 0);
-                       tmp->type = params->type;
-                       tmp->pool_hdl = pool->s.pool_hdl;
-                       tmp->udata_addr = (void *)udat;
-                       tmp->udata_size = init_params->udata_size;
-                       tmp->segcount = 0;
-                       tmp->segsize = pool->s.seg_size;
-                       tmp->handle.handle = odp_buffer_encode_handle(tmp);
-
-                       /* Set 1st seg addr for zero-len buffers */
-                       tmp->addr[0] = NULL;
-
-                       /* Special case for short buffer data */
-                       if (blk_size <= ODP_MAX_INLINE_BUF) {
-                               tmp->flags.hdrdata = 1;
-                               if (blk_size > 0) {
-                                       tmp->segcount = 1;
-                                       tmp->addr[0] = &tmp->addr[1];
-                                       tmp->size = blk_size;
-                               }
-                       }
-
-                       /* Push buffer onto pool's freelist */
-                       ret_buf(&pool->s, tmp);
-                       buf  -= buf_stride;
-                       udat -= udata_stride;
-               } while (buf >= mdata_base_addr);
-
-               /* Form block freelist for pool */
-               uint8_t *blk =
-                       block_base_addr + block_size - pool->s.seg_size;
-
-               if (blk_size > ODP_MAX_INLINE_BUF)
-                       do {
-                               ret_blk(&pool->s, blk);
-                               blk -= pool->s.seg_size;
-                       } while (blk >= block_base_addr);
-
-               /* Initialize pool statistics counters */
-               odp_atomic_store_u64(&pool->s.bufallocs, 0);
-               odp_atomic_store_u64(&pool->s.buffrees, 0);
-               odp_atomic_store_u64(&pool->s.blkallocs, 0);
-               odp_atomic_store_u64(&pool->s.blkfrees, 0);
-               odp_atomic_store_u64(&pool->s.bufempty, 0);
-               odp_atomic_store_u64(&pool->s.blkempty, 0);
-               odp_atomic_store_u64(&pool->s.high_wm_count, 0);
-               odp_atomic_store_u64(&pool->s.low_wm_count, 0);
-
-               /* Reset other pool globals to initial state */
-               pool->s.low_wm_assert = 0;
-               pool->s.quiesced = 0;
-               pool->s.low_wm_assert = 0;
-               pool->s.headroom = headroom;
-               pool->s.tailroom = tailroom;
-
-               /* Watermarks are hard-coded for now to control caching */
-               pool->s.high_wm = params->buf.num / 2;
-               pool->s.low_wm = params->buf.num / 4;
-
-               pool_hdl = pool->s.pool_hdl;
-               break;
-       }
-
-       return pool_hdl;
-}
-
-
-odp_pool_t odp_pool_lookup(const char *name)
-{
-       uint32_t i;
-       pool_entry_t *pool;
-
-       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
-               pool = get_pool_entry(i);
-
-               POOL_LOCK(&pool->s.lock);
-               if (strcmp(name, pool->s.name) == 0) {
-                       /* found it */
-                       POOL_UNLOCK(&pool->s.lock);
-                       return pool->s.pool_hdl;
-               }
-               POOL_UNLOCK(&pool->s.lock);
-       }
-
-       return ODP_POOL_INVALID;
-}
-
-int odp_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
-{
-       uint32_t pool_id = pool_handle_to_index(pool_hdl);
-       pool_entry_t *pool = get_pool_entry(pool_id);
-
-       if (pool == NULL || info == NULL)
-               return -1;
-
-       info->name = pool->s.name;
-       info->shm  = pool->s.flags.user_supplied_shm ?
-               pool->s.pool_shm : ODP_SHM_INVALID;
-       info->params.buf.size  = pool->s.params.buf.size;
-       info->params.buf.align = pool->s.params.buf.align;
-       info->params.buf.num   = pool->s.params.buf.num;
-       info->params.type      = pool->s.params.type;
-
-       return 0;
-}
-
-int odp_pool_destroy(odp_pool_t pool_hdl)
-{
-       uint32_t pool_id = pool_handle_to_index(pool_hdl);
-       pool_entry_t *pool = get_pool_entry(pool_id);
-
-       if (pool == NULL)
-               return -1;
-
-       POOL_LOCK(&pool->s.lock);
-
-       /* Call fails if pool is not allocated or predefined*/
-       if (pool->s.pool_shm == ODP_SHM_INVALID ||
-           pool->s.flags.predefined) {
-               POOL_UNLOCK(&pool->s.lock);
-               return -1;
-       }
-
-       /* Make sure local cache is empty */
-       flush_cache(&local_cache[pool_id], &pool->s);
-
-       /* Call fails if pool has allocated buffers */
-       if (odp_atomic_load_u32(&pool->s.bufcount) < pool->s.params.buf.num) {
-               POOL_UNLOCK(&pool->s.lock);
-               return -1;
-       }
-
-       if (!pool->s.flags.user_supplied_shm)
-               odp_shm_free(pool->s.pool_shm);
-
-       pool->s.pool_shm = ODP_SHM_INVALID;
-       POOL_UNLOCK(&pool->s.lock);
-
-       return 0;
-}
-
-odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size)
-{
-       uint32_t pool_id = pool_handle_to_index(pool_hdl);
-       pool_entry_t *pool = get_pool_entry(pool_id);
-       uintmax_t totsize = pool->s.headroom + size + pool->s.tailroom;
-       odp_anybuf_t *buf;
-
-       /* Reject oversized allocation requests */
-       if ((pool->s.flags.unsegmented && totsize > pool->s.seg_size) ||
-           (!pool->s.flags.unsegmented &&
-            totsize > ODP_CONFIG_PACKET_BUF_LEN_MAX))
-               return ODP_BUFFER_INVALID;
-
-       /* Try to satisfy request from the local cache */
-       buf = (odp_anybuf_t *)(void *)get_local_buf(&local_cache[pool_id],
-                                                   &pool->s, totsize);
-
-       /* If cache is empty, satisfy request from the pool */
-       if (odp_unlikely(buf == NULL)) {
-               buf = (odp_anybuf_t *)(void *)get_buf(&pool->s);
-
-               if (odp_unlikely(buf == NULL))
-                       return ODP_BUFFER_INVALID;
-
-               /* Get blocks for this buffer, if pool uses application data */
-               if (buf->buf.size < totsize) {
-                       intmax_t needed = totsize - buf->buf.size;
-                       do {
-                               uint8_t *blk = get_blk(&pool->s);
-                               if (blk == NULL) {
-                                       ret_buf(&pool->s, &buf->buf);
-                                       return ODP_BUFFER_INVALID;
-                               }
-                               buf->buf.addr[buf->buf.segcount++] = blk;
-                               needed -= pool->s.seg_size;
-                       } while (needed > 0);
-                       buf->buf.size = buf->buf.segcount * pool->s.seg_size;
-               }
-       }
-
-       /* By default, buffers inherit their pool's zeroization setting */
-       buf->buf.flags.zeroized = pool->s.flags.zeroized;
-
-       if (buf->buf.type == ODP_EVENT_PACKET) {
-               packet_init(pool, &buf->pkt, size);
-
-               if (pool->s.init_params.buf_init != NULL)
-                       (*pool->s.init_params.buf_init)
-                               (buf->buf.handle.handle,
-                                pool->s.init_params.buf_init_arg);
-       }
-
-       return odp_hdr_to_buf(&buf->buf);
-}
-
-odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl)
-{
-       return buffer_alloc(pool_hdl,
-                           odp_pool_to_entry(pool_hdl)->s.params.buf.size);
-}
-
-void odp_buffer_free(odp_buffer_t buf)
-{
-       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
-       pool_entry_t *pool = odp_buf_to_pool(buf_hdr);
-
-       if (odp_unlikely(pool->s.low_wm_assert))
-               ret_buf(&pool->s, buf_hdr);
-       else
-               ret_local_buf(&local_cache[pool->s.pool_id], buf_hdr);
-}
-
-void _odp_flush_caches(void)
-{
-       int i;
-
-       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
-               pool_entry_t *pool = get_pool_entry(i);
-               flush_cache(&local_cache[i], &pool->s);
-       }
-}
-
-void odp_pool_print(odp_pool_t pool_hdl)
-{
-       pool_entry_t *pool;
-       uint32_t pool_id;
-
-       pool_id = pool_handle_to_index(pool_hdl);
-       pool    = get_pool_entry(pool_id);
-
-       uint32_t bufcount  = odp_atomic_load_u32(&pool->s.bufcount);
-       uint32_t blkcount  = odp_atomic_load_u32(&pool->s.blkcount);
-       uint64_t bufallocs = odp_atomic_load_u64(&pool->s.bufallocs);
-       uint64_t buffrees  = odp_atomic_load_u64(&pool->s.buffrees);
-       uint64_t blkallocs = odp_atomic_load_u64(&pool->s.blkallocs);
-       uint64_t blkfrees  = odp_atomic_load_u64(&pool->s.blkfrees);
-       uint64_t bufempty  = odp_atomic_load_u64(&pool->s.bufempty);
-       uint64_t blkempty  = odp_atomic_load_u64(&pool->s.blkempty);
-       uint64_t hiwmct    = odp_atomic_load_u64(&pool->s.high_wm_count);
-       uint64_t lowmct    = odp_atomic_load_u64(&pool->s.low_wm_count);
-
-       ODP_DBG("Pool info\n");
-       ODP_DBG("---------\n");
-       ODP_DBG(" pool            %" PRIu64 "\n",
-               odp_pool_to_u64(pool->s.pool_hdl));
-       ODP_DBG(" name            %s\n",
-               pool->s.flags.has_name ? pool->s.name : "Unnamed Pool");
-       ODP_DBG(" pool type       %s\n",
-               pool->s.params.type == ODP_POOL_BUFFER ? "buffer" :
-              (pool->s.params.type == ODP_POOL_PACKET ? "packet" :
-              (pool->s.params.type == ODP_POOL_TIMEOUT ? "timeout" :
-               "unknown")));
-       ODP_DBG(" pool storage    %sODP managed\n",
-               pool->s.flags.user_supplied_shm ?
-               "application provided, " : "");
-       ODP_DBG(" pool status     %s\n",
-               pool->s.quiesced ? "quiesced" : "active");
-       ODP_DBG(" pool opts       %s, %s, %s\n",
-               pool->s.flags.unsegmented ? "unsegmented" : "segmented",
-               pool->s.flags.zeroized ? "zeroized" : "non-zeroized",
-               pool->s.flags.predefined  ? "predefined" : "created");
-       ODP_DBG(" pool base       %p\n",  pool->s.pool_base_addr);
-       ODP_DBG(" pool size       %zu (%zu pages)\n",
-               pool->s.pool_size, pool->s.pool_size / ODP_PAGE_SIZE);
-       ODP_DBG(" pool mdata base %p\n",  pool->s.pool_mdata_addr);
-       ODP_DBG(" udata size      %zu\n", pool->s.init_params.udata_size);
-       ODP_DBG(" headroom        %u\n",  pool->s.headroom);
-       ODP_DBG(" buf size        %zu\n", pool->s.params.buf.size);
-       ODP_DBG(" tailroom        %u\n",  pool->s.tailroom);
-       ODP_DBG(" buf align       %u requested, %u used\n",
-               pool->s.params.buf.align, pool->s.buf_align);
-       ODP_DBG(" num bufs        %u\n",  pool->s.params.buf.num);
-       ODP_DBG(" bufs available  %u %s\n", bufcount,
-               pool->s.low_wm_assert ? " **low wm asserted**" : "");
-       ODP_DBG(" bufs in use     %u\n",  pool->s.params.buf.num - bufcount);
-       ODP_DBG(" buf allocs      %lu\n", bufallocs);
-       ODP_DBG(" buf frees       %lu\n", buffrees);
-       ODP_DBG(" buf empty       %lu\n", bufempty);
-       ODP_DBG(" blk size        %zu\n",
-               pool->s.seg_size > ODP_MAX_INLINE_BUF ? pool->s.seg_size : 0);
-       ODP_DBG(" blks available  %u\n",  blkcount);
-       ODP_DBG(" blk allocs      %lu\n", blkallocs);
-       ODP_DBG(" blk frees       %lu\n", blkfrees);
-       ODP_DBG(" blk empty       %lu\n", blkempty);
-       ODP_DBG(" high wm value   %lu\n", pool->s.high_wm);
-       ODP_DBG(" high wm count   %lu\n", hiwmct);
-       ODP_DBG(" low wm value    %lu\n", pool->s.low_wm);
-       ODP_DBG(" low wm count    %lu\n", lowmct);
-}
-
-
-odp_pool_t odp_buffer_pool(odp_buffer_t buf)
-{
-       return odp_buf_to_hdr(buf)->pool_hdl;
-}
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index a7344f8..cd9ad9e 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -16,7 +16,7 @@
 #include <odp_classification_datamodel.h>
 #include <odp_classification_inlines.h>
 #include <odp_classification_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp/shared_memory.h>
 #include <odp/helper/eth.h>
 #include <string.h>
diff --git a/platform/linux-generic/odp_pool.c 
b/platform/linux-generic/odp_pool.c
new file mode 100644
index 0000000..6bcb777
--- /dev/null
+++ b/platform/linux-generic/odp_pool.c
@@ -0,0 +1,617 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp/std_types.h>
+#include <odp/pool.h>
+#include <odp_buffer_internal.h>
+#include <odp_pool_internal.h>
+#include <odp_buffer_inlines.h>
+#include <odp_packet_internal.h>
+#include <odp_timer_internal.h>
+#include <odp_align_internal.h>
+#include <odp/shared_memory.h>
+#include <odp/align.h>
+#include <odp_internal.h>
+#include <odp/config.h>
+#include <odp/hints.h>
+#include <odp_debug_internal.h>
+#include <odp_atomic_internal.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+
+#if ODP_CONFIG_POOLS > ODP_BUFFER_MAX_POOLS
+#error ODP_CONFIG_POOLS > ODP_BUFFER_MAX_POOLS
+#endif
+
+
+typedef union buffer_type_any_u {
+       odp_buffer_hdr_t  buf;
+       odp_packet_hdr_t  pkt;
+       odp_timeout_hdr_t tmo;
+} odp_anybuf_t;
+
+_ODP_STATIC_ASSERT((sizeof(union buffer_type_any_u) % 8) == 0,
+                  "BUFFER_TYPE_ANY_U__SIZE_ERR");
+
+/* Any buffer type header */
+typedef struct {
+       union buffer_type_any_u any_hdr;    /* any buffer type */
+} odp_any_buffer_hdr_t;
+
+typedef struct odp_any_hdr_stride {
+       uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(odp_any_buffer_hdr_t))];
+} odp_any_hdr_stride;
+
+
+typedef struct pool_table_t {
+       pool_entry_t pool[ODP_CONFIG_POOLS];
+} pool_table_t;
+
+
+/* The pool table */
+static pool_table_t *pool_tbl;
+
+/* Pool entry pointers (for inlining) */
+void *pool_entry_ptr[ODP_CONFIG_POOLS];
+
+/* Local cache for buffer alloc/free acceleration */
+static __thread local_cache_t local_cache[ODP_CONFIG_POOLS];
+
+int odp_buffer_pool_init_global(void)
+{
+       uint32_t i;
+       odp_shm_t shm;
+
+       shm = odp_shm_reserve("odp_buffer_pools",
+                             sizeof(pool_table_t),
+                             sizeof(pool_entry_t), 0);
+
+       pool_tbl = odp_shm_addr(shm);
+
+       if (pool_tbl == NULL)
+               return -1;
+
+       memset(pool_tbl, 0, sizeof(pool_table_t));
+
+       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
+               /* init locks */
+               pool_entry_t *pool = &pool_tbl->pool[i];
+               POOL_LOCK_INIT(&pool->s.lock);
+               pool->s.pool_hdl = pool_index_to_handle(i);
+               pool->s.pool_id = i;
+               pool_entry_ptr[i] = pool;
+       }
+
+       ODP_DBG("\nBuffer pool init global\n");
+       ODP_DBG("  pool_entry_s size     %zu\n", sizeof(struct pool_entry_s));
+       ODP_DBG("  pool_entry_t size     %zu\n", sizeof(pool_entry_t));
+       ODP_DBG("  odp_buffer_hdr_t size %zu\n", sizeof(odp_buffer_hdr_t));
+       ODP_DBG("\n");
+       return 0;
+}
+
+/**
+ * Pool creation
+ */
+
+odp_pool_t odp_pool_create(const char *name,
+                          odp_shm_t shm,
+                          odp_pool_param_t *params)
+{
+       odp_pool_t pool_hdl = ODP_POOL_INVALID;
+       pool_entry_t *pool;
+       uint32_t i, headroom = 0, tailroom = 0;
+
+       /* Default size and align for timeouts */
+       if (params->type == ODP_POOL_TIMEOUT) {
+               params->buf.size  = 0; /* tmo.__res1 */
+               params->buf.align = 0; /* tmo.__res2 */
+       }
+
+       /* Default initialization paramters */
+       static _odp_buffer_pool_init_t default_init_params = {
+               .udata_size = 0,
+               .buf_init = NULL,
+               .buf_init_arg = NULL,
+       };
+
+       _odp_buffer_pool_init_t *init_params = &default_init_params;
+
+       if (params == NULL)
+               return ODP_POOL_INVALID;
+
+       /* Restriction for v1.0: All non-packet buffers are unsegmented */
+       int unseg = 1;
+
+       /* Restriction for v1.0: No zeroization support */
+       const int zeroized = 0;
+
+       /* Restriction for v1.0: No udata support */
+       uint32_t udata_stride = (init_params->udata_size > sizeof(void *)) ?
+               ODP_CACHE_LINE_SIZE_ROUNDUP(init_params->udata_size) :
+               0;
+
+       uint32_t blk_size, buf_stride;
+       uint32_t buf_align;
+
+       if (params->type == ODP_POOL_PACKET)
+               buf_align = 0;
+       else
+               buf_align = params->buf.align;
+
+       /* Validate requested buffer alignment */
+       if (buf_align > ODP_CONFIG_BUFFER_ALIGN_MAX ||
+           buf_align != ODP_ALIGN_ROUNDDOWN_POWER_2(buf_align, buf_align))
+               return ODP_POOL_INVALID;
+
+       /* Set correct alignment based on input request */
+       if (buf_align == 0)
+               buf_align = ODP_CACHE_LINE_SIZE;
+       else if (buf_align < ODP_CONFIG_BUFFER_ALIGN_MIN)
+               buf_align = ODP_CONFIG_BUFFER_ALIGN_MIN;
+
+       /* Calculate space needed for buffer blocks and metadata */
+       switch (params->type) {
+       case ODP_POOL_BUFFER:
+       case ODP_POOL_TIMEOUT:
+               blk_size = params->buf.size;
+
+               /* Optimize small raw buffers */
+               if (blk_size > ODP_MAX_INLINE_BUF || params->buf.align != 0)
+                       blk_size = ODP_ALIGN_ROUNDUP(blk_size, buf_align);
+
+               buf_stride = params->type == ODP_POOL_BUFFER ?
+                       sizeof(odp_buffer_hdr_stride) :
+                       sizeof(odp_timeout_hdr_stride);
+               break;
+
+       case ODP_POOL_PACKET:
+               headroom = ODP_CONFIG_PACKET_HEADROOM;
+               tailroom = ODP_CONFIG_PACKET_TAILROOM;
+               unseg = params->pkt.seg_len > ODP_CONFIG_PACKET_BUF_LEN_MAX;
+
+               if (unseg)
+                       blk_size = ODP_ALIGN_ROUNDUP(
+                               headroom + params->pkt.seg_len + tailroom,
+                               buf_align);
+               else
+                       blk_size = ODP_ALIGN_ROUNDUP(
+                               headroom + params->pkt.seg_len + tailroom,
+                               ODP_CONFIG_PACKET_SEG_LEN_MIN);
+
+               buf_stride = params->type == ODP_POOL_PACKET ?
+                       sizeof(odp_packet_hdr_stride) :
+                       sizeof(odp_any_hdr_stride);
+               break;
+
+       default:
+               return ODP_POOL_INVALID;
+       }
+
+       /* Validate requested number of buffers against addressable limits */
+       if (params->buf.num >
+           (ODP_BUFFER_MAX_BUFFERS / (buf_stride / ODP_CACHE_LINE_SIZE)))
+               return ODP_POOL_INVALID;
+
+       /* Find an unused buffer pool slot and iniitalize it as requested */
+       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
+               pool = get_pool_entry(i);
+
+               POOL_LOCK(&pool->s.lock);
+               if (pool->s.pool_shm != ODP_SHM_INVALID) {
+                       POOL_UNLOCK(&pool->s.lock);
+                       continue;
+               }
+
+               /* found free pool */
+               size_t block_size, pad_size, mdata_size, udata_size;
+
+               pool->s.flags.all = 0;
+
+               if (name == NULL) {
+                       pool->s.name[0] = 0;
+               } else {
+                       strncpy(pool->s.name, name,
+                               ODP_POOL_NAME_LEN - 1);
+                       pool->s.name[ODP_POOL_NAME_LEN - 1] = 0;
+                       pool->s.flags.has_name = 1;
+               }
+
+               pool->s.params = *params;
+               pool->s.init_params = *init_params;
+               pool->s.buf_align = buf_align;
+
+               /* Optimize for short buffers: Data stored in buffer hdr */
+               if (blk_size <= ODP_MAX_INLINE_BUF) {
+                       block_size = 0;
+                       pool->s.buf_align = blk_size == 0 ? 0 : sizeof(void *);
+               } else {
+                       block_size = params->buf.num * blk_size;
+                       pool->s.buf_align = buf_align;
+               }
+
+               pad_size = ODP_CACHE_LINE_SIZE_ROUNDUP(block_size) - block_size;
+               mdata_size = params->buf.num * buf_stride;
+               udata_size = params->buf.num * udata_stride;
+
+               pool->s.pool_size = ODP_PAGE_SIZE_ROUNDUP(block_size +
+                                                         pad_size +
+                                                         mdata_size +
+                                                         udata_size);
+
+               if (shm == ODP_SHM_NULL) {
+                       shm = odp_shm_reserve(pool->s.name,
+                                             pool->s.pool_size,
+                                             ODP_PAGE_SIZE, 0);
+                       if (shm == ODP_SHM_INVALID) {
+                               POOL_UNLOCK(&pool->s.lock);
+                               return ODP_POOL_INVALID;
+                       }
+                       pool->s.pool_base_addr = odp_shm_addr(shm);
+               } else {
+                       odp_shm_info_t info;
+                       if (odp_shm_info(shm, &info) != 0 ||
+                           info.size < pool->s.pool_size) {
+                               POOL_UNLOCK(&pool->s.lock);
+                               return ODP_POOL_INVALID;
+                       }
+                       pool->s.pool_base_addr = odp_shm_addr(shm);
+                       void *page_addr =
+                               ODP_ALIGN_ROUNDUP_PTR(pool->s.pool_base_addr,
+                                                     ODP_PAGE_SIZE);
+                       if (pool->s.pool_base_addr != page_addr) {
+                               if (info.size < pool->s.pool_size +
+                                   ((size_t)page_addr -
+                                    (size_t)pool->s.pool_base_addr)) {
+                                       POOL_UNLOCK(&pool->s.lock);
+                                       return ODP_POOL_INVALID;
+                               }
+                               pool->s.pool_base_addr = page_addr;
+                       }
+                       pool->s.flags.user_supplied_shm = 1;
+               }
+
+               pool->s.pool_shm = shm;
+
+               /* Now safe to unlock since pool entry has been allocated */
+               POOL_UNLOCK(&pool->s.lock);
+
+               pool->s.flags.unsegmented = unseg;
+               pool->s.flags.zeroized = zeroized;
+               pool->s.seg_size = unseg ?
+                       blk_size : ODP_CONFIG_PACKET_SEG_LEN_MIN;
+
+
+               uint8_t *block_base_addr = pool->s.pool_base_addr;
+               uint8_t *mdata_base_addr =
+                       block_base_addr + block_size + pad_size;
+               uint8_t *udata_base_addr = mdata_base_addr + mdata_size;
+
+               /* Pool mdata addr is used for indexing buffer metadata */
+               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);
+
+               /* Initialization will increment these to their target vals */
+               odp_atomic_store_u32(&pool->s.bufcount, 0);
+               odp_atomic_store_u32(&pool->s.blkcount, 0);
+
+               uint8_t *buf = udata_base_addr - buf_stride;
+               uint8_t *udat = udata_stride == 0 ? NULL :
+                       block_base_addr - udata_stride;
+
+               /* Init buffer common header and add to pool buffer freelist */
+               do {
+                       odp_buffer_hdr_t *tmp =
+                               (odp_buffer_hdr_t *)(void *)buf;
+
+                       /* Iniitalize buffer metadata */
+                       tmp->allocator = ODP_FREEBUF;
+                       tmp->flags.all = 0;
+                       tmp->flags.zeroized = zeroized;
+                       tmp->size = 0;
+                       odp_atomic_store_u32(&tmp->ref_count, 0);
+                       tmp->type = params->type;
+                       tmp->pool_hdl = pool->s.pool_hdl;
+                       tmp->udata_addr = (void *)udat;
+                       tmp->udata_size = init_params->udata_size;
+                       tmp->segcount = 0;
+                       tmp->segsize = pool->s.seg_size;
+                       tmp->handle.handle = odp_buffer_encode_handle(tmp);
+
+                       /* Set 1st seg addr for zero-len buffers */
+                       tmp->addr[0] = NULL;
+
+                       /* Special case for short buffer data */
+                       if (blk_size <= ODP_MAX_INLINE_BUF) {
+                               tmp->flags.hdrdata = 1;
+                               if (blk_size > 0) {
+                                       tmp->segcount = 1;
+                                       tmp->addr[0] = &tmp->addr[1];
+                                       tmp->size = blk_size;
+                               }
+                       }
+
+                       /* Push buffer onto pool's freelist */
+                       ret_buf(&pool->s, tmp);
+                       buf  -= buf_stride;
+                       udat -= udata_stride;
+               } while (buf >= mdata_base_addr);
+
+               /* Form block freelist for pool */
+               uint8_t *blk =
+                       block_base_addr + block_size - pool->s.seg_size;
+
+               if (blk_size > ODP_MAX_INLINE_BUF)
+                       do {
+                               ret_blk(&pool->s, blk);
+                               blk -= pool->s.seg_size;
+                       } while (blk >= block_base_addr);
+
+               /* Initialize pool statistics counters */
+               odp_atomic_store_u64(&pool->s.bufallocs, 0);
+               odp_atomic_store_u64(&pool->s.buffrees, 0);
+               odp_atomic_store_u64(&pool->s.blkallocs, 0);
+               odp_atomic_store_u64(&pool->s.blkfrees, 0);
+               odp_atomic_store_u64(&pool->s.bufempty, 0);
+               odp_atomic_store_u64(&pool->s.blkempty, 0);
+               odp_atomic_store_u64(&pool->s.high_wm_count, 0);
+               odp_atomic_store_u64(&pool->s.low_wm_count, 0);
+
+               /* Reset other pool globals to initial state */
+               pool->s.low_wm_assert = 0;
+               pool->s.quiesced = 0;
+               pool->s.low_wm_assert = 0;
+               pool->s.headroom = headroom;
+               pool->s.tailroom = tailroom;
+
+               /* Watermarks are hard-coded for now to control caching */
+               pool->s.high_wm = params->buf.num / 2;
+               pool->s.low_wm = params->buf.num / 4;
+
+               pool_hdl = pool->s.pool_hdl;
+               break;
+       }
+
+       return pool_hdl;
+}
+
+
+odp_pool_t odp_pool_lookup(const char *name)
+{
+       uint32_t i;
+       pool_entry_t *pool;
+
+       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
+               pool = get_pool_entry(i);
+
+               POOL_LOCK(&pool->s.lock);
+               if (strcmp(name, pool->s.name) == 0) {
+                       /* found it */
+                       POOL_UNLOCK(&pool->s.lock);
+                       return pool->s.pool_hdl;
+               }
+               POOL_UNLOCK(&pool->s.lock);
+       }
+
+       return ODP_POOL_INVALID;
+}
+
+int odp_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
+{
+       uint32_t pool_id = pool_handle_to_index(pool_hdl);
+       pool_entry_t *pool = get_pool_entry(pool_id);
+
+       if (pool == NULL || info == NULL)
+               return -1;
+
+       info->name = pool->s.name;
+       info->shm  = pool->s.flags.user_supplied_shm ?
+               pool->s.pool_shm : ODP_SHM_INVALID;
+       info->params.buf.size  = pool->s.params.buf.size;
+       info->params.buf.align = pool->s.params.buf.align;
+       info->params.buf.num   = pool->s.params.buf.num;
+       info->params.type      = pool->s.params.type;
+
+       return 0;
+}
+
+int odp_pool_destroy(odp_pool_t pool_hdl)
+{
+       uint32_t pool_id = pool_handle_to_index(pool_hdl);
+       pool_entry_t *pool = get_pool_entry(pool_id);
+
+       if (pool == NULL)
+               return -1;
+
+       POOL_LOCK(&pool->s.lock);
+
+       /* Call fails if pool is not allocated or predefined*/
+       if (pool->s.pool_shm == ODP_SHM_INVALID ||
+           pool->s.flags.predefined) {
+               POOL_UNLOCK(&pool->s.lock);
+               return -1;
+       }
+
+       /* Make sure local cache is empty */
+       flush_cache(&local_cache[pool_id], &pool->s);
+
+       /* Call fails if pool has allocated buffers */
+       if (odp_atomic_load_u32(&pool->s.bufcount) < pool->s.params.buf.num) {
+               POOL_UNLOCK(&pool->s.lock);
+               return -1;
+       }
+
+       if (!pool->s.flags.user_supplied_shm)
+               odp_shm_free(pool->s.pool_shm);
+
+       pool->s.pool_shm = ODP_SHM_INVALID;
+       POOL_UNLOCK(&pool->s.lock);
+
+       return 0;
+}
+
+odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size)
+{
+       uint32_t pool_id = pool_handle_to_index(pool_hdl);
+       pool_entry_t *pool = get_pool_entry(pool_id);
+       uintmax_t totsize = pool->s.headroom + size + pool->s.tailroom;
+       odp_anybuf_t *buf;
+
+       /* Reject oversized allocation requests */
+       if ((pool->s.flags.unsegmented && totsize > pool->s.seg_size) ||
+           (!pool->s.flags.unsegmented &&
+            totsize > ODP_CONFIG_PACKET_BUF_LEN_MAX))
+               return ODP_BUFFER_INVALID;
+
+       /* Try to satisfy request from the local cache */
+       buf = (odp_anybuf_t *)(void *)get_local_buf(&local_cache[pool_id],
+                                                   &pool->s, totsize);
+
+       /* If cache is empty, satisfy request from the pool */
+       if (odp_unlikely(buf == NULL)) {
+               buf = (odp_anybuf_t *)(void *)get_buf(&pool->s);
+
+               if (odp_unlikely(buf == NULL))
+                       return ODP_BUFFER_INVALID;
+
+               /* Get blocks for this buffer, if pool uses application data */
+               if (buf->buf.size < totsize) {
+                       intmax_t needed = totsize - buf->buf.size;
+                       do {
+                               uint8_t *blk = get_blk(&pool->s);
+                               if (blk == NULL) {
+                                       ret_buf(&pool->s, &buf->buf);
+                                       return ODP_BUFFER_INVALID;
+                               }
+                               buf->buf.addr[buf->buf.segcount++] = blk;
+                               needed -= pool->s.seg_size;
+                       } while (needed > 0);
+                       buf->buf.size = buf->buf.segcount * pool->s.seg_size;
+               }
+       }
+
+       /* By default, buffers inherit their pool's zeroization setting */
+       buf->buf.flags.zeroized = pool->s.flags.zeroized;
+
+       if (buf->buf.type == ODP_EVENT_PACKET) {
+               packet_init(pool, &buf->pkt, size);
+
+               if (pool->s.init_params.buf_init != NULL)
+                       (*pool->s.init_params.buf_init)
+                               (buf->buf.handle.handle,
+                                pool->s.init_params.buf_init_arg);
+       }
+
+       return odp_hdr_to_buf(&buf->buf);
+}
+
+odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl)
+{
+       return buffer_alloc(pool_hdl,
+                           odp_pool_to_entry(pool_hdl)->s.params.buf.size);
+}
+
+void odp_buffer_free(odp_buffer_t buf)
+{
+       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
+       pool_entry_t *pool = odp_buf_to_pool(buf_hdr);
+
+       if (odp_unlikely(pool->s.low_wm_assert))
+               ret_buf(&pool->s, buf_hdr);
+       else
+               ret_local_buf(&local_cache[pool->s.pool_id], buf_hdr);
+}
+
+void _odp_flush_caches(void)
+{
+       int i;
+
+       for (i = 0; i < ODP_CONFIG_POOLS; i++) {
+               pool_entry_t *pool = get_pool_entry(i);
+               flush_cache(&local_cache[i], &pool->s);
+       }
+}
+
+void odp_pool_print(odp_pool_t pool_hdl)
+{
+       pool_entry_t *pool;
+       uint32_t pool_id;
+
+       pool_id = pool_handle_to_index(pool_hdl);
+       pool    = get_pool_entry(pool_id);
+
+       uint32_t bufcount  = odp_atomic_load_u32(&pool->s.bufcount);
+       uint32_t blkcount  = odp_atomic_load_u32(&pool->s.blkcount);
+       uint64_t bufallocs = odp_atomic_load_u64(&pool->s.bufallocs);
+       uint64_t buffrees  = odp_atomic_load_u64(&pool->s.buffrees);
+       uint64_t blkallocs = odp_atomic_load_u64(&pool->s.blkallocs);
+       uint64_t blkfrees  = odp_atomic_load_u64(&pool->s.blkfrees);
+       uint64_t bufempty  = odp_atomic_load_u64(&pool->s.bufempty);
+       uint64_t blkempty  = odp_atomic_load_u64(&pool->s.blkempty);
+       uint64_t hiwmct    = odp_atomic_load_u64(&pool->s.high_wm_count);
+       uint64_t lowmct    = odp_atomic_load_u64(&pool->s.low_wm_count);
+
+       ODP_DBG("Pool info\n");
+       ODP_DBG("---------\n");
+       ODP_DBG(" pool            %" PRIu64 "\n",
+               odp_pool_to_u64(pool->s.pool_hdl));
+       ODP_DBG(" name            %s\n",
+               pool->s.flags.has_name ? pool->s.name : "Unnamed Pool");
+       ODP_DBG(" pool type       %s\n",
+               pool->s.params.type == ODP_POOL_BUFFER ? "buffer" :
+              (pool->s.params.type == ODP_POOL_PACKET ? "packet" :
+              (pool->s.params.type == ODP_POOL_TIMEOUT ? "timeout" :
+               "unknown")));
+       ODP_DBG(" pool storage    %sODP managed\n",
+               pool->s.flags.user_supplied_shm ?
+               "application provided, " : "");
+       ODP_DBG(" pool status     %s\n",
+               pool->s.quiesced ? "quiesced" : "active");
+       ODP_DBG(" pool opts       %s, %s, %s\n",
+               pool->s.flags.unsegmented ? "unsegmented" : "segmented",
+               pool->s.flags.zeroized ? "zeroized" : "non-zeroized",
+               pool->s.flags.predefined  ? "predefined" : "created");
+       ODP_DBG(" pool base       %p\n",  pool->s.pool_base_addr);
+       ODP_DBG(" pool size       %zu (%zu pages)\n",
+               pool->s.pool_size, pool->s.pool_size / ODP_PAGE_SIZE);
+       ODP_DBG(" pool mdata base %p\n",  pool->s.pool_mdata_addr);
+       ODP_DBG(" udata size      %zu\n", pool->s.init_params.udata_size);
+       ODP_DBG(" headroom        %u\n",  pool->s.headroom);
+       ODP_DBG(" buf size        %zu\n", pool->s.params.buf.size);
+       ODP_DBG(" tailroom        %u\n",  pool->s.tailroom);
+       ODP_DBG(" buf align       %u requested, %u used\n",
+               pool->s.params.buf.align, pool->s.buf_align);
+       ODP_DBG(" num bufs        %u\n",  pool->s.params.buf.num);
+       ODP_DBG(" bufs available  %u %s\n", bufcount,
+               pool->s.low_wm_assert ? " **low wm asserted**" : "");
+       ODP_DBG(" bufs in use     %u\n",  pool->s.params.buf.num - bufcount);
+       ODP_DBG(" buf allocs      %lu\n", bufallocs);
+       ODP_DBG(" buf frees       %lu\n", buffrees);
+       ODP_DBG(" buf empty       %lu\n", bufempty);
+       ODP_DBG(" blk size        %zu\n",
+               pool->s.seg_size > ODP_MAX_INLINE_BUF ? pool->s.seg_size : 0);
+       ODP_DBG(" blks available  %u\n",  blkcount);
+       ODP_DBG(" blk allocs      %lu\n", blkallocs);
+       ODP_DBG(" blk frees       %lu\n", blkfrees);
+       ODP_DBG(" blk empty       %lu\n", blkempty);
+       ODP_DBG(" high wm value   %lu\n", pool->s.high_wm);
+       ODP_DBG(" high wm count   %lu\n", hiwmct);
+       ODP_DBG(" low wm value    %lu\n", pool->s.low_wm);
+       ODP_DBG(" low wm count    %lu\n", lowmct);
+}
+
+
+odp_pool_t odp_buffer_pool(odp_buffer_t buf)
+{
+       return odp_buf_to_hdr(buf)->pool_hdl;
+}
diff --git a/platform/linux-generic/odp_queue.c 
b/platform/linux-generic/odp_queue.c
index 76bf4d7..6806a95 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -10,7 +10,7 @@
 #include <odp/align.h>
 #include <odp/buffer.h>
 #include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp_buffer_inlines.h>
 #include <odp_internal.h>
 #include <odp/shared_memory.h>
diff --git a/platform/linux-generic/odp_timer.c 
b/platform/linux-generic/odp_timer.c
index 47af87d..7b5fe15 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -36,7 +36,7 @@
 #include <odp/buffer.h>
 #include <odp_buffer_inlines.h>
 #include <odp/pool.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp/debug.h>
 #include <odp_debug_internal.h>
 #include <odp/event.h>
-- 
2.1.0


_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to