[lng-odp] [API-NEXT PATCH v5 6/7] linux-generic: pktio: dummy multi-queue pktio

2015-11-26 Thread Petri Savolainen
Implemented multi-queue API with dummy single queue support.
Enables testing the API and provides stubbs for actual
multi-queue implementations. Not optimized.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .../include/odp/plat/packet_io_types.h |  14 +-
 .../linux-generic/include/odp_packet_io_internal.h |  46 
 platform/linux-generic/odp_packet_io.c | 280 +
 platform/linux-generic/pktio/loop.c|  10 +-
 platform/linux-generic/pktio/netmap.c  |  10 +-
 platform/linux-generic/pktio/pcap.c|  10 +-
 platform/linux-generic/pktio/socket.c  |  10 +-
 platform/linux-generic/pktio/socket_mmap.c |  10 +-
 8 files changed, 382 insertions(+), 8 deletions(-)

diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h 
b/platform/linux-generic/include/odp/plat/packet_io_types.h
index 1086463..25f7151 100644
--- a/platform/linux-generic/include/odp/plat/packet_io_types.h
+++ b/platform/linux-generic/include/odp/plat/packet_io_types.h
@@ -21,16 +21,24 @@ extern "C" {
 #include 
 #include 
 
-/** @addtogroup odp_packet_io ODP PACKET IO
+/** @addtogroup odp_packet_io
  *  Operations on a packet.
  *  @{
  */
 
 typedef ODP_HANDLE_T(odp_pktio_t);
 
-typedef ODP_HANDLE_T(odp_pktin_queue_t);
+/** @internal */
+typedef struct odp_pktin_queue_t {
+   odp_pktio_t pktio; /**< @internal pktio handle */
+   int index; /**< @internal pktio queue index */
+} odp_pktin_queue_t;
 
-typedef ODP_HANDLE_T(odp_pktout_queue_t);
+/** @internal */
+typedef struct odp_pktout_queue_t {
+   odp_pktio_t pktio; /**< @internal pktio handle */
+   int index; /**< @internal pktio queue index */
+} odp_pktout_queue_t;
 
 #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0)
 
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index a46c6fe..2b6d116 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -32,6 +32,8 @@ extern "C" {
 
 #define PKTIO_NAME_LEN 256
 
+#define PKTIO_MAX_QUEUES 64
+
 /** Determine if a socket read/write error should be reported. Transient errors
  *  that simply require the caller to retry are ignored, the _send/_recv APIs
  *  are non-blocking and it is the caller's responsibility to retry if the
@@ -87,6 +89,17 @@ struct pktio_entry {
char name[PKTIO_NAME_LEN];  /**< name of pktio provided to
   pktio_open() */
odp_pktio_param_t param;
+
+   /* Storage for queue handles
+* Multi-queue support is pktio driver specific */
+   struct {
+   odp_queue_tqueue;
+   odp_pktin_queue_t  pktin;
+   } in_queue[PKTIO_MAX_QUEUES];
+
+   struct {
+   odp_pktout_queue_t pktout;
+   } out_queue[PKTIO_MAX_QUEUES];
 };
 
 typedef union {
@@ -116,6 +129,21 @@ typedef struct pktio_if_ops {
int (*promisc_mode_set)(pktio_entry_t *pktio_entry,  int enable);
int (*promisc_mode_get)(pktio_entry_t *pktio_entry);
int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
+   int (*capability)(pktio_entry_t *pktio_entry,
+ odp_pktio_capability_t *capa);
+   int (*input_queues_config)(pktio_entry_t *pktio_entry,
+  const odp_pktio_input_queue_param_t *param);
+   int (*output_queues_config)(pktio_entry_t *pktio_entry,
+   const odp_pktio_output_queue_param_t *p);
+   int (*in_queues)(pktio_entry_t *entry, odp_queue_t queues[], int num);
+   int (*pktin_queues)(pktio_entry_t *entry, odp_pktin_queue_t queues[],
+   int num);
+   int (*pktout_queues)(pktio_entry_t *entry, odp_pktout_queue_t queues[],
+int num);
+   int (*recv_queue)(pktio_entry_t *entry, int index,
+ odp_packet_t packets[], int num);
+   int (*send_queue)(pktio_entry_t *entry, int index,
+ odp_packet_t packets[], int num);
 } pktio_if_ops_t;
 
 extern void *pktio_entry_ptr[];
@@ -151,6 +179,24 @@ static inline void pktio_cls_enabled_set(pktio_entry_t 
*entry, int ena)
 
 int pktin_poll(pktio_entry_t *entry);
 
+/*
+ * Dummy single queue implementations of multi-queue API
+ */
+int single_capability(odp_pktio_capability_t *capa);
+int single_input_queues_config(pktio_entry_t *entry,
+  const odp_pktio_input_queue_param_t *param);
+int single_output_queues_config(pktio_entry_t *entry,
+   const odp_pktio_output_queue_param_t *param);
+int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num);
+int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[

[lng-odp] [API-NEXT PATCH v5 7/7] test: l2fwd: use multi-queue pktio in direct mode

2015-11-26 Thread Petri Savolainen
Modified the application to support for multiple queues
per interface. Enabled inequal worker thread counts.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 413 ---
 1 file changed, 351 insertions(+), 62 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index d201186..67a23ed 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -45,6 +45,12 @@
  */
 #define MAX_PKT_BURST  32
 
+/** Maximum number of pktio queues per interface */
+#define MAX_QUEUES 32
+
+/** Maximum number of pktio interfaces */
+#define MAX_PKTIOS 8
+
 /**
  * Packet input mode
  */
@@ -64,6 +70,7 @@ typedef enum pkt_in_mode_t {
 typedef struct {
int cpu_count;
int if_count;   /**< Number of interfaces to be used */
+   int num_workers;/**< Number of worker threads */
char **if_names;/**< Array of pointers to interface names */
pkt_in_mode_t mode; /**< Packet input mode */
int time;   /**< Time in seconds to run. */
@@ -95,8 +102,20 @@ typedef union {
 /**
  * Thread specific arguments
  */
-typedef struct {
-   int src_idx;/**< Source interface identifier */
+typedef struct thread_args_t {
+   int num_pktio;
+
+   struct {
+   odp_pktio_t rx_pktio;
+   odp_pktio_t tx_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int rx_idx;
+   int tx_idx;
+   int rx_queue_idx;
+   int tx_queue_idx;
+   } pktio[MAX_PKTIOS];
+
stats_t *stats; /**< Pointer to per thread stats */
 } thread_args_t;
 
@@ -110,14 +129,24 @@ typedef struct {
appl_args_t appl;
/** Thread specific arguments */
thread_args_t thread[MAX_WORKERS];
-   /** Table of pktio handles */
-   odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
-   odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t port_eth_addr[MAX_PKTIOS];
/** Table of dst ethernet addresses */
-   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t dst_eth_addr[MAX_PKTIOS];
/** Table of dst ports */
-   int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
+   int dst_port[MAX_PKTIOS];
+   /** Table of pktio handles */
+   struct {
+   odp_pktio_t pktio;
+   odp_pktin_queue_t pktin[MAX_QUEUES];
+   odp_pktout_queue_t pktout[MAX_QUEUES];
+   int num_rx_thr;
+   int num_tx_thr;
+   int num_rx_queue;
+   int num_tx_queue;
+   int next_rx_queue;
+   int next_tx_queue;
+   } pktios[MAX_PKTIOS];
 } args_t;
 
 /** Global pointer to args */
@@ -190,7 +219,7 @@ static void *pktio_queue_thread(void *arg)
/* packets from the same queue are from the same interface */
dst_idx = lookup_dest_port(pkt_tbl[0]);
fill_eth_addrs(pkt_tbl, pkts, dst_idx);
-   pktio_dst = gbl_args->pktios[dst_idx];
+   pktio_dst = gbl_args->pktios[dst_idx].pktio;
 
sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
@@ -226,8 +255,9 @@ static inline int lookup_dest_port(odp_packet_t pkt)
 
pktio_src = odp_packet_input(pkt);
 
-   for (src_idx = -1, i = 0; gbl_args->pktios[i] != ODP_PKTIO_INVALID; ++i)
-   if (gbl_args->pktios[i] == pktio_src)
+   for (src_idx = -1, i = 0; gbl_args->pktios[i].pktio
+ != ODP_PKTIO_INVALID; ++i)
+   if (gbl_args->pktios[i].pktio == pktio_src)
src_idx = i;
 
if (src_idx == -1)
@@ -264,32 +294,29 @@ static void *pktio_direct_recv_thread(void *arg)
int thr;
int pkts;
odp_packet_t pkt_tbl[MAX_PKT_BURST];
-   int src_idx, dst_idx;
-   odp_pktio_t pktio_src, pktio_dst;
+   int dst_idx, num_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int pktio = 0;
thread_args_t *thr_args = arg;
stats_t *stats = thr_args->stats;
 
thr = odp_thread_id();
 
-   src_idx = thr_args->src_idx;
-   dst_idx = gbl_args->dst_port[src_idx];
-   pktio_src = gbl_args->pktios[src_idx];
-   pktio_dst = gbl_args->pktios[dst_idx];
+   num_pktio = thr_args->num_pktio;
+   dst_idx   = thr_args->pktio[pktio].tx_idx;
+   pktin = thr_args->pktio[pktio].pktin;
+   pktout= thr_args->pktio[pktio].pktout;
 
-   printf("[%02i] srcif:%s dstif:%s spktio:%02" PRIu64
-  " dpktio:%02" PRIu64 " DIRECT RECV mode\n",
-  thr,
-  gbl_args->appl.if_n

[lng-odp] [API-NEXT PATCH 1/3] api: thrmask: correct specification error

2015-11-20 Thread Petri Savolainen
odp_thread_count_max() returns the maximum number of threads,
instead of odp_thrmask_count().

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/thrmask.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/odp/api/thrmask.h b/include/odp/api/thrmask.h
index ebc31f2..8666166 100644
--- a/include/odp/api/thrmask.h
+++ b/include/odp/api/thrmask.h
@@ -67,7 +67,7 @@ void odp_thrmask_set(odp_thrmask_t *mask, int thr);
  * Set all threads in mask
  *
  * Set all possible threads in the mask. All threads from 0 to
- * odp_thrmask_count() minus one are set, regardless of which threads are
+ * odp_thread_count_max() minus one are set, regardless of which threads are
  * actually active.
  *
  * @param mask   Thread mask to set
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 3/3] linux-generic: thread: removed internal max threads define

2015-11-20 Thread Petri Savolainen
Replaced internal define with ODP_THREAD_COUNT_MAX. This
fixes also the current make install issue.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/Makefile.am |  1 -
 .../include/odp/plat/rwlock_recursive_types.h  | 10 
 .../linux-generic/include/odp_buffer_internal.h|  3 +--
 .../linux-generic/include/odp_config_internal.h| 29 --
 platform/linux-generic/include/odp_pool_internal.h |  3 ++-
 platform/linux-generic/odp_pool.c  |  3 ++-
 platform/linux-generic/odp_thread.c| 11 
 platform/linux-generic/odp_thrmask.c   |  1 -
 8 files changed, 15 insertions(+), 46 deletions(-)
 delete mode 100644 platform/linux-generic/include/odp_config_internal.h

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index ca372eb..193ae2a 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -133,7 +133,6 @@ noinst_HEADERS = \
  ${srcdir}/include/odp_classification_datamodel.h \
  ${srcdir}/include/odp_classification_inlines.h \
  ${srcdir}/include/odp_classification_internal.h \
- ${srcdir}/include/odp_config_internal.h \
  ${srcdir}/include/odp_crypto_internal.h \
  ${srcdir}/include/odp_debug_internal.h \
  ${srcdir}/include/odp_forward_typedefs_internal.h \
diff --git a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h 
b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
index d5bfb92..474751c 100644
--- a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
+++ b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
@@ -19,14 +19,14 @@ extern "C" {
 
 #include 
 #include 
-#include 
+#include 
 
 /** @internal */
 struct odp_rwlock_recursive_s {
-   odp_rwlock_t lock;   /**< the lock */
-   int wr_owner;/**< write owner thread */
-   uint32_t wr_cnt; /**< write recursion count */
-   uint8_t  rd_cnt[_ODP_INTERNAL_MAX_THREADS]; /**< read recursion count */
+   odp_rwlock_t lock; /**< the lock */
+   int wr_owner;  /**< write owner thread */
+   uint32_t wr_cnt;   /**< write recursion count */
+   uint8_t  rd_cnt[ODP_THREAD_COUNT_MAX]; /**< read recursion count */
 };
 
 typedef struct odp_rwlock_recursive_s odp_rwlock_recursive_t;
diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
b/platform/linux-generic/include/odp_buffer_internal.h
index 74a0b5c..abdd320 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -30,7 +30,6 @@ extern "C" {
 #include 
 #include 
 #include 
-#include 
 
 #define ODP_BITSIZE(x) \
((x) <= 2 ?  1 : \
@@ -144,7 +143,7 @@ struct odp_buffer_hdr_t {
 
 /** @internal Compile time assert that the
  * allocator field can handle any allocator id*/
-_ODP_STATIC_ASSERT(INT16_MAX >= _ODP_INTERNAL_MAX_THREADS,
+_ODP_STATIC_ASSERT(INT16_MAX >= ODP_THREAD_COUNT_MAX,
   "ODP_BUFFER_HDR_T__ALLOCATOR__SIZE_ERROR");
 
 typedef struct odp_buffer_hdr_stride {
diff --git a/platform/linux-generic/include/odp_config_internal.h 
b/platform/linux-generic/include/odp_config_internal.h
deleted file mode 100644
index 4f20ff8..000
--- a/platform/linux-generic/include/odp_config_internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2015, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/**
- * @file
- *
- * Linux-generic platform internal configuration
- */
-
-#ifndef ODP_CONFIG_INTERNAL_H_
-#define ODP_CONFIG_INTERNAL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Maximum number of threads
- */
-#define _ODP_INTERNAL_MAX_THREADS  128
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/include/odp_pool_internal.h 
b/platform/linux-generic/include/odp_pool_internal.h
index 94bf1fa..b12bca8 100644
--- a/platform/linux-generic/include/odp_pool_internal.h
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -29,6 +29,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /**
@@ -139,7 +140,7 @@ struct pool_entry_s {
uint32_theadroom;
uint32_ttailroom;
 
-   local_cache_t local_cache[_ODP_INTERNAL_MAX_THREADS] ODP_ALIGNED_CACHE;
+   local_cache_t local_cache[ODP_THREAD_COUNT_MAX] ODP_ALIGNED_CACHE;
 };
 
 typedef union pool_entry_u {
diff --git a/platform/linux-generic/odp_pool.c 
b/platform/linux-generic/odp_pool.c
index 9859ff6..84d35bf 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platf

[lng-odp] [API-NEXT PATCH 2/3] api: thread: added THREAD_COUNT_MAX define

2015-11-20 Thread Petri Savolainen
Added maximum thread count define to enable static memory allocation.
The API call returns dynamic maximum. Static and dynamic may be different
application is build for binary compatibility.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/thread.h   |  9 +-
 platform/linux-generic/Makefile.am |  1 +
 .../linux-generic/include/odp/plat/thread_types.h  | 34 ++
 platform/linux-generic/include/odp/thread.h|  8 +
 4 files changed, 44 insertions(+), 8 deletions(-)
 create mode 100644 platform/linux-generic/include/odp/plat/thread_types.h

diff --git a/include/odp/api/thread.h b/include/odp/api/thread.h
index 3029342..3720249 100644
--- a/include/odp/api/thread.h
+++ b/include/odp/api/thread.h
@@ -23,6 +23,13 @@ extern "C" {
  */
 
 /**
+ * @def ODP_THREAD_COUNT_MAX
+ * Maximum number of threads supported in build time. Use
+ * odp_thread_count_max() for maximum number of threads supported in run time,
+ * which depend on system configuration and may be lower than this number.
+ */
+
+/**
  * Thread type
  */
 typedef enum odp_thread_type_e {
@@ -78,7 +85,7 @@ int odp_thread_count(void);
  * Maximum thread count
  *
  * Returns the maximum thread count, which is a constant value and set in
- * ODP initialization phase.
+ * ODP initialization phase. This may be lower than ODP_THREAD_COUNT_MAX.
  *
  * @return Maximum thread count
  */
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index a6b6029..ca372eb 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -74,6 +74,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/spinlock_types.h \
  $(srcdir)/include/odp/plat/spinlock_recursive_types.h \
  $(srcdir)/include/odp/plat/strong_types.h \
+ $(srcdir)/include/odp/plat/thread_types.h \
  $(srcdir)/include/odp/plat/thrmask_types.h \
  $(srcdir)/include/odp/plat/ticketlock_types.h \
  $(srcdir)/include/odp/plat/time_types.h \
diff --git a/platform/linux-generic/include/odp/plat/thread_types.h 
b/platform/linux-generic/include/odp/plat/thread_types.h
new file mode 100644
index 000..33af459
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/thread_types.h
@@ -0,0 +1,34 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP thread
+ */
+
+#ifndef ODP_THREAD_TYPES_H_
+#define ODP_THREAD_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_thread
+ *  @{
+ */
+
+#define ODP_THREAD_COUNT_MAX 128
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/thread.h 
b/platform/linux-generic/include/odp/thread.h
index e521585..522ca25 100644
--- a/platform/linux-generic/include/odp/thread.h
+++ b/platform/linux-generic/include/odp/thread.h
@@ -17,13 +17,7 @@
 extern "C" {
 #endif
 
-/** @ingroup odp_thread ODP THREAD
- *  @{
- */
-
-/**
- * @}
- */
+#include 
 
 #include 
 
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v4 0/7] Multi-queue packet io APIs

2015-11-20 Thread Petri Savolainen
This patch set adds APIs for multi-queue packet IO. It does not remove or modify
existing API calls, so that multi-queue can be verified first with couple of 
apps and implementations. Single queue APIs (e.g. odp_pktio_inq_setdef()) and 
potentially plain _recv() and _send() should be removed once everything is 
ported to use the new API (potentially with num_queues == 1).

Configuration of multiple packet input and output queues fit better into pktio 
API than classification and TM APIs. Multi-queue is more generally needed (and 
provided) than classification or TM. Classification (and potentially TM) API 
spec should be aligned to use the new default input/output queue setup.

v4:
 * added additional cast to avoid build error

v3:
 * added dummy implementations (6/7)
 * modified l2fwd to use multi-queue API in direct mode (7/7)
 * use term single_user instead of single_thr
 * use term hash_enable instead of hash_ena

v2:
 * changed hash proto to bit field to allow selection of multiple protocols
 * added IPv4 and IPv6 protocols
 * defined odp_pktin_queue_t and pktout_queue_t handle types instead 
   of using indexes
 * use term single_thr instead of lock_free
 * added hash_ena to control if hashing (or classification) is used for 
   spreading flows to multiple queues


Petri Savolainen (7):
  api: pktio: added pktio capability struct
  api: pktio: added multiple pktio input queues
  api: pktio: added direct queue receive
  api: pktio: added multiple pktio output queues
  api: pktio: added direct send to pktio output queue
  linux-generic: pktio: dummy multi-queue pktio
  test: l2fwd: use multi-queue pktio in direct mode

 include/odp/api/packet_io.h| 302 ++-
 .../include/odp/plat/packet_io_types.h |  14 +-
 .../linux-generic/include/odp_packet_io_internal.h |  46 +++
 platform/linux-generic/odp_packet_io.c | 280 ++
 platform/linux-generic/pktio/loop.c|  10 +-
 platform/linux-generic/pktio/netmap.c  |  10 +-
 platform/linux-generic/pktio/pcap.c|  10 +-
 platform/linux-generic/pktio/socket.c  |  10 +-
 platform/linux-generic/pktio/socket_mmap.c |  10 +-
 test/performance/odp_l2fwd.c   | 414 ++---
 10 files changed, 1025 insertions(+), 81 deletions(-)

-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v4 1/7] api: pktio: added pktio capability struct

2015-11-20 Thread Petri Savolainen
Added capability structure and a function to query it.
Capability limits are used for advanced pktio configuration,
like configuration of multiple input/output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9409388..264fa75 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -98,6 +98,16 @@ typedef struct odp_pktio_param_t {
 } odp_pktio_param_t;
 
 /**
+ * Packet IO capabilities
+ */
+typedef struct odp_pktio_capability_t {
+   /** Maximum number of input queues */
+   unsigned max_input_queues;
+   /** Maximum number of output queues */
+   unsigned max_output_queues;
+} odp_pktio_capability_t;
+
+/**
  * Open a packet IO interface
  *
  * An ODP program can open a single packet IO interface per device, attempts
@@ -135,6 +145,19 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
   const odp_pktio_param_t *param);
 
 /**
+ * Query packet IO interface capabilities
+ *
+ * Outputs packet IO interface capabilities on success.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] capa   Pointer to capability structure for output
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v4 4/7] api: pktio: added multiple pktio output queues

2015-11-20 Thread Petri Savolainen
Added output queue configuration parameters and functions
for setting up multiple output queues. Added also
a function to query the number of output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 71 ++
 .../include/odp/plat/packet_io_types.h |  2 +
 2 files changed, 73 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index bf9b1f9..9160261 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -48,6 +48,11 @@ extern "C" {
  */
 
 /**
+ * @typedef odp_pktout_queue_t
+ * Direct packet output queue handle
+ */
+
+/**
  * @def ODP_PKTIO_INVALID
  * Invalid packet IO handle
  */
@@ -151,6 +156,24 @@ typedef struct odp_pktio_input_queue_param_t {
 } odp_pktio_input_queue_param_t;
 
 /**
+ * Packet output queue parameters
+ *
+ * These parameters are used only in ODP_PKTOUT_MODE_SEND mode.
+ */
+typedef struct odp_pktio_output_queue_param_t {
+   /** Single thread per queue. Enable performance optimization when each
+ * queue has only single user.
+ * 0: Queue is multi-thread safe
+ * 1: Queue is used by single thread only */
+   odp_bool_t single_user;
+
+   /** Number of output queues to be created. The value must be between
+ * 1 and interface capability */
+   unsigned num_queues;
+
+} odp_pktio_output_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -244,6 +267,25 @@ int odp_pktio_input_queues_config(odp_pktio_t pktio,
  const odp_pktio_input_queue_param_t *param);
 
 /**
+ * Configure packet output queues
+ *
+ * Setup a number of packet output queues and configure those. The maximum
+ * number of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). All requested queues are setup on success, no
+ * queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket output queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_pktout_queues()
+ */
+int odp_pktio_output_queues_config(odp_pktio_t pktio,
+  const odp_pktio_output_queue_param_t *param);
+
+/**
  * Queues for packet input
  *
  * Returns the number of input queues configured for the interface in
@@ -285,6 +327,26 @@ int odp_pktio_pktin_queues(odp_pktio_t pktio, 
odp_pktin_queue_t queues[],
   int num);
 
 /**
+ * Direct packet output queues
+ *
+ * Returns the number of output queues configured for the interface in
+ * ODP_PKTOUT_MODE_SEND mode. Outputs up to 'num' queue handles when the
+ * 'queues' array pointer is not NULL. If return value is larger than 'num',
+ * there are more queues than the function was allowed to output.
+ *
+ * Packets are sent to these queues with odp_pktio_send_queue().
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param  num  Maximum number of queue handles to output
+ *
+ * @return Number of packet output queues
+ * @retval <0 on failure
+ */
+int odp_pktio_pktout_queues(odp_pktio_t pktio, odp_pktout_queue_t queues[],
+   int num);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
@@ -570,6 +632,15 @@ void odp_pktio_param_init(odp_pktio_param_t *param);
 void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param);
 
 /**
+ * Initialize packet output queue parameters
+ *
+ * Initialize an odp_pktio_output_queue_param_t to its default values.
+ *
+ * @param param   Output queue parameter structure to be initialized
+ */
+void odp_pktio_output_queue_param_init(odp_pktio_output_queue_param_t *param);
+
+/**
  * Print pktio info to the console
  *
  * Print implementation-defined pktio debug information to the console.
diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h 
b/platform/linux-generic/include/odp/plat/packet_io_types.h
index 2e229c3..1086463 100644
--- a/platform/linux-generic/include/odp/plat/packet_io_types.h
+++ b/platform/linux-generic/include/odp/plat/packet_io_types.h
@@ -30,6 +30,8 @@ typedef ODP_HANDLE_T(odp_pktio_t);
 
 typedef ODP_HANDLE_T(odp_pktin_queue_t);
 
+typedef ODP_HANDLE_T(odp_pktout_queue_t);
+
 #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0)
 
 #define ODP_PKTIO_ANY _odp_cast_scalar(odp_pktio_t, ~0)
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v4 5/7] api: pktio: added direct send to pktio output queue

2015-11-20 Thread Petri Savolainen
Added odp_pktio_send_queue for direct packet send to
a pktio output queue.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9160261..443841e 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -443,21 +443,44 @@ int odp_pktio_recv_queue(odp_pktin_queue_t queue, 
odp_packet_t packets[],
 int num);
 
 /**
- * Send packets
+ * Send packets directly to an interface
  *
- * Sends out a number of packets. A successful call returns the actual number 
of
- * packets sent. If return value is less than 'len', the remaining packets at
- * the end of pkt_table[] are not consumed, and the caller has to take care of
- * them.
+ * Sends out a number of packets to the interface. The operation is
+ * multi-thread safe. A successful call returns the actual number of
+ * packets sent. If return value is less than 'num', the remaining packets at
+ * the end of packets[] array are not consumed, and the caller has to take
+ * care of them.
  *
  * @param pktioPacket IO handle
- * @param pkt_table[]  Array of packets to send
- * @param len  length of pkt_table[]
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
  *
  * @return Number of packets sent
  * @retval <0 on failure
  */
-int odp_pktio_send(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_send(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Send packets directly to an interface output queue
+ *
+ * Sends out a number of packets to the interface output queue. When
+ * 'single_user' output queue parameter has been set, the operation is 
optimized
+ * for single thread per queue usage model and the same queue must not be
+ * accessed from multiple threads.
+ *
+ * A successful call returns the actual number of packets sent. If return value
+ * is less than 'num', the remaining packets at the end of packets[] array
+ * are not consumed, and the caller has to take care of them.
+ *
+ * @param queuePktio output queue handle for sending packets
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
+ *
+ * @return Number of packets sent
+ * @retval <0 on failure
+ */
+int odp_pktio_send_queue(odp_pktout_queue_t queue, odp_packet_t packets[],
+int num);
 
 /**
  * Set the default input queue to be associated with a pktio handle
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v4 7/7] test: l2fwd: use multi-queue pktio in direct mode

2015-11-20 Thread Petri Savolainen
Modified the application to support for multiple queues
per interface. Enabled inequal worker thread counts.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 414 ---
 1 file changed, 352 insertions(+), 62 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index d201186..fa7 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -45,6 +45,12 @@
  */
 #define MAX_PKT_BURST  32
 
+/** Maximum number of pktio queues per interface */
+#define MAX_QUEUES 32
+
+/** Maximum number of pktio interfaces */
+#define MAX_PKTIOS 8
+
 /**
  * Packet input mode
  */
@@ -64,6 +70,7 @@ typedef enum pkt_in_mode_t {
 typedef struct {
int cpu_count;
int if_count;   /**< Number of interfaces to be used */
+   int num_workers;/**< Number of worker threads */
char **if_names;/**< Array of pointers to interface names */
pkt_in_mode_t mode; /**< Packet input mode */
int time;   /**< Time in seconds to run. */
@@ -95,8 +102,20 @@ typedef union {
 /**
  * Thread specific arguments
  */
-typedef struct {
-   int src_idx;/**< Source interface identifier */
+typedef struct thread_args_t {
+   int num_pktio;
+
+   struct {
+   odp_pktio_t rx_pktio;
+   odp_pktio_t tx_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int rx_idx;
+   int tx_idx;
+   int rx_queue_idx;
+   int tx_queue_idx;
+   } pktio[MAX_PKTIOS];
+
stats_t *stats; /**< Pointer to per thread stats */
 } thread_args_t;
 
@@ -110,14 +129,24 @@ typedef struct {
appl_args_t appl;
/** Thread specific arguments */
thread_args_t thread[MAX_WORKERS];
-   /** Table of pktio handles */
-   odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
-   odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t port_eth_addr[MAX_PKTIOS];
/** Table of dst ethernet addresses */
-   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t dst_eth_addr[MAX_PKTIOS];
/** Table of dst ports */
-   int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
+   int dst_port[MAX_PKTIOS];
+   /** Table of pktio handles */
+   struct {
+   odp_pktio_t pktio;
+   odp_pktin_queue_t pktin[MAX_QUEUES];
+   odp_pktout_queue_t pktout[MAX_QUEUES];
+   int num_rx_thr;
+   int num_tx_thr;
+   int num_rx_queue;
+   int num_tx_queue;
+   int next_rx_queue;
+   int next_tx_queue;
+   } pktios[MAX_PKTIOS];
 } args_t;
 
 /** Global pointer to args */
@@ -190,7 +219,7 @@ static void *pktio_queue_thread(void *arg)
/* packets from the same queue are from the same interface */
dst_idx = lookup_dest_port(pkt_tbl[0]);
fill_eth_addrs(pkt_tbl, pkts, dst_idx);
-   pktio_dst = gbl_args->pktios[dst_idx];
+   pktio_dst = gbl_args->pktios[dst_idx].pktio;
 
sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
@@ -226,8 +255,9 @@ static inline int lookup_dest_port(odp_packet_t pkt)
 
pktio_src = odp_packet_input(pkt);
 
-   for (src_idx = -1, i = 0; gbl_args->pktios[i] != ODP_PKTIO_INVALID; ++i)
-   if (gbl_args->pktios[i] == pktio_src)
+   for (src_idx = -1, i = 0; gbl_args->pktios[i].pktio
+ != ODP_PKTIO_INVALID; ++i)
+   if (gbl_args->pktios[i].pktio == pktio_src)
src_idx = i;
 
if (src_idx == -1)
@@ -264,32 +294,29 @@ static void *pktio_direct_recv_thread(void *arg)
int thr;
int pkts;
odp_packet_t pkt_tbl[MAX_PKT_BURST];
-   int src_idx, dst_idx;
-   odp_pktio_t pktio_src, pktio_dst;
+   int dst_idx, num_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int pktio = 0;
thread_args_t *thr_args = arg;
stats_t *stats = thr_args->stats;
 
thr = odp_thread_id();
 
-   src_idx = thr_args->src_idx;
-   dst_idx = gbl_args->dst_port[src_idx];
-   pktio_src = gbl_args->pktios[src_idx];
-   pktio_dst = gbl_args->pktios[dst_idx];
+   num_pktio = thr_args->num_pktio;
+   dst_idx   = thr_args->pktio[pktio].tx_idx;
+   pktin = thr_args->pktio[pktio].pktin;
+   pktout= thr_args->pktio[pktio].pktout;
 
-   printf("[%02i] srcif:%s dstif:%s spktio:%02" PRIu64
-  " dpktio:%02" PRIu64 " DIRECT RECV mode\n",
-  thr,
-  gbl_args->appl.if_n

[lng-odp] [API-NEXT PATCH v4 2/7] api: pktio: added multiple pktio input queues

2015-11-20 Thread Petri Savolainen
Added input queue configuration parameters and functions
to setup multiple input queue and hashing. Added also
functions to query the number of queues and queue handles.
Direct receive does use new odp_pktin_queue_t handle type.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 136 +
 .../include/odp/plat/packet_io_types.h |   2 +
 2 files changed, 138 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 264fa75..26c9be5 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -19,6 +19,7 @@ extern "C" {
 #endif
 
 #include 
+#include 
 
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
@@ -42,6 +43,11 @@ extern "C" {
  */
 
 /**
+ * @typedef odp_pktin_queue_t
+ * Direct packet input queue handle
+ */
+
+/**
  * @def ODP_PKTIO_INVALID
  * Invalid packet IO handle
  */
@@ -85,6 +91,66 @@ typedef enum odp_pktio_output_mode_t {
 } odp_pktio_output_mode_t;
 
 /**
+ * Packet input hash protocols
+ *
+ * The list of protocol header field combinations, which are included into
+ * packet input hash calculation.
+ */
+typedef union odp_pktin_hash_proto_t {
+   /** Protocol header fields for hashing */
+   struct {
+   /** IPv4 addresses and UDP port numbers */
+   uint32_t ipv4_udp : 1;
+   /** IPv4 addresses and TCP port numbers */
+   uint32_t ipv4_tcp : 1;
+   /** IPv4 addresses */
+   uint32_t ipv4 : 1;
+   /** IPv6 addresses and UDP port numbers */
+   uint32_t ipv6_udp : 1;
+   /** IPv6 addresses and TCP port numbers */
+   uint32_t ipv6_tcp : 1;
+   /** IPv6 addresses */
+   uint32_t ipv6 : 1;
+   } proto;
+
+   /** All bits of the bit field structure */
+   uint32_t all_bits;
+} odp_pktin_hash_proto_t;
+
+/**
+ * Packet input queue parameters
+ */
+typedef struct odp_pktio_input_queue_param_t {
+   /** Single thread per queue. Enable performance optimization when each
+ * queue has only single user.
+ * 0: Queue is multi-thread safe
+ * 1: Queue is used by single thread only */
+   odp_bool_t single_user;
+
+   /** Enable flow hashing
+ * 0: Do not hash flows
+ * 1: Hash flows to input queues */
+   odp_bool_t hash_enable;
+
+   /** Protocol field selection for hashing. Multiple protocols can be
+ * selected. */
+   odp_pktin_hash_proto_t hash_proto;
+
+   /** Number of input queues to be created. More than one input queue
+ * require input hashing or classifier setup. Hash_proto is ignored
+ * when hash_enable is zero or num_queues is one. This value must be
+ * between 1 and interface capability. Queue type is defined by the
+ * input mode. */
+   unsigned num_queues;
+
+   /** Queue parameters for creating input queues in ODP_PKTIN_MODE_POLL
+ * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered
+ * only in ODP_PKTIN_MODE_SCHED mode. */
+   odp_queue_param_t queue_param;
+
+} odp_pktio_input_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -158,6 +224,67 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
 
 /**
+ * Configure packet input queues
+ *
+ * Setup a number of packet input queues and configure those. The maximum 
number
+ * of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). Queue handles for input queues can be requested with
+ * odp_pktio_in_queues() or odp_pktio_pktin_queues() after this call. All
+ * requested queues are setup on success, no queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket input queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_in_queues(), odp_pktio_pktin_queues()
+ */
+int odp_pktio_input_queues_config(odp_pktio_t pktio,
+ const odp_pktio_input_queue_param_t *param);
+
+/**
+ * Queues for packet input
+ *
+ * Returns the number of input queues configured for the interface in
+ * ODP_PKTIN_MODE_POLL and ODP_PKTIN_MODE_SCHED modes. Outputs up to 'num' 
queue
+ * handles when the 'queues' array pointer is not NULL. If return value is
+ * larger than 'num', there are more queues than the function was allowed to
+ * output.
+ *
+ * Packets (and other events) from these queues are received with
+ * odp_queue_deq(), odp_schedule(), etc calls.
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param

[lng-odp] [API-NEXT PATCH v3 7/7] test: l2fwd: use multi-queue pktio in direct mode

2015-11-19 Thread Petri Savolainen
Modified the application to support for multiple queues
per interface. Enabled inequal worker thread counts.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 414 ---
 1 file changed, 352 insertions(+), 62 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index d201186..fa7 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -45,6 +45,12 @@
  */
 #define MAX_PKT_BURST  32
 
+/** Maximum number of pktio queues per interface */
+#define MAX_QUEUES 32
+
+/** Maximum number of pktio interfaces */
+#define MAX_PKTIOS 8
+
 /**
  * Packet input mode
  */
@@ -64,6 +70,7 @@ typedef enum pkt_in_mode_t {
 typedef struct {
int cpu_count;
int if_count;   /**< Number of interfaces to be used */
+   int num_workers;/**< Number of worker threads */
char **if_names;/**< Array of pointers to interface names */
pkt_in_mode_t mode; /**< Packet input mode */
int time;   /**< Time in seconds to run. */
@@ -95,8 +102,20 @@ typedef union {
 /**
  * Thread specific arguments
  */
-typedef struct {
-   int src_idx;/**< Source interface identifier */
+typedef struct thread_args_t {
+   int num_pktio;
+
+   struct {
+   odp_pktio_t rx_pktio;
+   odp_pktio_t tx_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int rx_idx;
+   int tx_idx;
+   int rx_queue_idx;
+   int tx_queue_idx;
+   } pktio[MAX_PKTIOS];
+
stats_t *stats; /**< Pointer to per thread stats */
 } thread_args_t;
 
@@ -110,14 +129,24 @@ typedef struct {
appl_args_t appl;
/** Thread specific arguments */
thread_args_t thread[MAX_WORKERS];
-   /** Table of pktio handles */
-   odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of port ethernet addresses */
-   odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t port_eth_addr[MAX_PKTIOS];
/** Table of dst ethernet addresses */
-   odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+   odph_ethaddr_t dst_eth_addr[MAX_PKTIOS];
/** Table of dst ports */
-   int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
+   int dst_port[MAX_PKTIOS];
+   /** Table of pktio handles */
+   struct {
+   odp_pktio_t pktio;
+   odp_pktin_queue_t pktin[MAX_QUEUES];
+   odp_pktout_queue_t pktout[MAX_QUEUES];
+   int num_rx_thr;
+   int num_tx_thr;
+   int num_rx_queue;
+   int num_tx_queue;
+   int next_rx_queue;
+   int next_tx_queue;
+   } pktios[MAX_PKTIOS];
 } args_t;
 
 /** Global pointer to args */
@@ -190,7 +219,7 @@ static void *pktio_queue_thread(void *arg)
/* packets from the same queue are from the same interface */
dst_idx = lookup_dest_port(pkt_tbl[0]);
fill_eth_addrs(pkt_tbl, pkts, dst_idx);
-   pktio_dst = gbl_args->pktios[dst_idx];
+   pktio_dst = gbl_args->pktios[dst_idx].pktio;
 
sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
@@ -226,8 +255,9 @@ static inline int lookup_dest_port(odp_packet_t pkt)
 
pktio_src = odp_packet_input(pkt);
 
-   for (src_idx = -1, i = 0; gbl_args->pktios[i] != ODP_PKTIO_INVALID; ++i)
-   if (gbl_args->pktios[i] == pktio_src)
+   for (src_idx = -1, i = 0; gbl_args->pktios[i].pktio
+ != ODP_PKTIO_INVALID; ++i)
+   if (gbl_args->pktios[i].pktio == pktio_src)
src_idx = i;
 
if (src_idx == -1)
@@ -264,32 +294,29 @@ static void *pktio_direct_recv_thread(void *arg)
int thr;
int pkts;
odp_packet_t pkt_tbl[MAX_PKT_BURST];
-   int src_idx, dst_idx;
-   odp_pktio_t pktio_src, pktio_dst;
+   int dst_idx, num_pktio;
+   odp_pktin_queue_t pktin;
+   odp_pktout_queue_t pktout;
+   int pktio = 0;
thread_args_t *thr_args = arg;
stats_t *stats = thr_args->stats;
 
thr = odp_thread_id();
 
-   src_idx = thr_args->src_idx;
-   dst_idx = gbl_args->dst_port[src_idx];
-   pktio_src = gbl_args->pktios[src_idx];
-   pktio_dst = gbl_args->pktios[dst_idx];
+   num_pktio = thr_args->num_pktio;
+   dst_idx   = thr_args->pktio[pktio].tx_idx;
+   pktin = thr_args->pktio[pktio].pktin;
+   pktout= thr_args->pktio[pktio].pktout;
 
-   printf("[%02i] srcif:%s dstif:%s spktio:%02" PRIu64
-  " dpktio:%02" PRIu64 " DIRECT RECV mode\n",
-  thr,
-  gbl_args->appl.if_n

[lng-odp] [API-NEXT PATCH v3 6/7] linux-generic: pktio: dummy multi-queue pktio

2015-11-19 Thread Petri Savolainen
Implemented multi-queue API with dummy single queue support.
Enables testing the API and provides stubbs for actual
multi-queue implementations. Not optimized.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .../include/odp/plat/packet_io_types.h |  14 +-
 .../linux-generic/include/odp_packet_io_internal.h |  46 
 platform/linux-generic/odp_packet_io.c | 280 +
 platform/linux-generic/pktio/loop.c|  10 +-
 platform/linux-generic/pktio/netmap.c  |  10 +-
 platform/linux-generic/pktio/pcap.c|  10 +-
 platform/linux-generic/pktio/socket.c  |  10 +-
 platform/linux-generic/pktio/socket_mmap.c |  10 +-
 8 files changed, 382 insertions(+), 8 deletions(-)

diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h 
b/platform/linux-generic/include/odp/plat/packet_io_types.h
index 1086463..25f7151 100644
--- a/platform/linux-generic/include/odp/plat/packet_io_types.h
+++ b/platform/linux-generic/include/odp/plat/packet_io_types.h
@@ -21,16 +21,24 @@ extern "C" {
 #include 
 #include 
 
-/** @addtogroup odp_packet_io ODP PACKET IO
+/** @addtogroup odp_packet_io
  *  Operations on a packet.
  *  @{
  */
 
 typedef ODP_HANDLE_T(odp_pktio_t);
 
-typedef ODP_HANDLE_T(odp_pktin_queue_t);
+/** @internal */
+typedef struct odp_pktin_queue_t {
+   odp_pktio_t pktio; /**< @internal pktio handle */
+   int index; /**< @internal pktio queue index */
+} odp_pktin_queue_t;
 
-typedef ODP_HANDLE_T(odp_pktout_queue_t);
+/** @internal */
+typedef struct odp_pktout_queue_t {
+   odp_pktio_t pktio; /**< @internal pktio handle */
+   int index; /**< @internal pktio queue index */
+} odp_pktout_queue_t;
 
 #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0)
 
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index a46c6fe..2b6d116 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -32,6 +32,8 @@ extern "C" {
 
 #define PKTIO_NAME_LEN 256
 
+#define PKTIO_MAX_QUEUES 64
+
 /** Determine if a socket read/write error should be reported. Transient errors
  *  that simply require the caller to retry are ignored, the _send/_recv APIs
  *  are non-blocking and it is the caller's responsibility to retry if the
@@ -87,6 +89,17 @@ struct pktio_entry {
char name[PKTIO_NAME_LEN];  /**< name of pktio provided to
   pktio_open() */
odp_pktio_param_t param;
+
+   /* Storage for queue handles
+* Multi-queue support is pktio driver specific */
+   struct {
+   odp_queue_tqueue;
+   odp_pktin_queue_t  pktin;
+   } in_queue[PKTIO_MAX_QUEUES];
+
+   struct {
+   odp_pktout_queue_t pktout;
+   } out_queue[PKTIO_MAX_QUEUES];
 };
 
 typedef union {
@@ -116,6 +129,21 @@ typedef struct pktio_if_ops {
int (*promisc_mode_set)(pktio_entry_t *pktio_entry,  int enable);
int (*promisc_mode_get)(pktio_entry_t *pktio_entry);
int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
+   int (*capability)(pktio_entry_t *pktio_entry,
+ odp_pktio_capability_t *capa);
+   int (*input_queues_config)(pktio_entry_t *pktio_entry,
+  const odp_pktio_input_queue_param_t *param);
+   int (*output_queues_config)(pktio_entry_t *pktio_entry,
+   const odp_pktio_output_queue_param_t *p);
+   int (*in_queues)(pktio_entry_t *entry, odp_queue_t queues[], int num);
+   int (*pktin_queues)(pktio_entry_t *entry, odp_pktin_queue_t queues[],
+   int num);
+   int (*pktout_queues)(pktio_entry_t *entry, odp_pktout_queue_t queues[],
+int num);
+   int (*recv_queue)(pktio_entry_t *entry, int index,
+ odp_packet_t packets[], int num);
+   int (*send_queue)(pktio_entry_t *entry, int index,
+ odp_packet_t packets[], int num);
 } pktio_if_ops_t;
 
 extern void *pktio_entry_ptr[];
@@ -151,6 +179,24 @@ static inline void pktio_cls_enabled_set(pktio_entry_t 
*entry, int ena)
 
 int pktin_poll(pktio_entry_t *entry);
 
+/*
+ * Dummy single queue implementations of multi-queue API
+ */
+int single_capability(odp_pktio_capability_t *capa);
+int single_input_queues_config(pktio_entry_t *entry,
+  const odp_pktio_input_queue_param_t *param);
+int single_output_queues_config(pktio_entry_t *entry,
+   const odp_pktio_output_queue_param_t *param);
+int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num);
+int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[

[lng-odp] [API-NEXT PATCH v3 3/7] api: pktio: added direct queue receive

2015-11-19 Thread Petri Savolainen
Added odp_pktio_recv_queue for direct packet receive from pktio
input queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 26c9be5..bf9b1f9 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -346,16 +346,39 @@ int odp_pktio_close(odp_pktio_t pktio);
 odp_pktio_t odp_pktio_lookup(const char *dev);
 
 /**
- * Receive packets
+ * Receive packets directly from an interface
  *
- * @param pktio   Packet IO handle
- * @param pkt_table[] Storage for received packets (filled by function)
- * @param len Length of pkt_table[], i.e. max number of pkts to receive
+ * Receives up to 'num' packets from the interface. The operation is
+ * multi-thread safe.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
+ *
+ * @return Number of packets received
+ * @retval <0 on failure
+ */
+int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Receive packets directly from an interface input queue
+ *
+ * Receives up to 'num' packets from the pktio interface input queue. When
+ * 'single_user' input queue parameter has been set, the operation is optimized
+ * for single thread per queue usage model and the same queue must not be
+ * accessed from multiple threads.
+ *
+ * @param  queue  Pktio input queue handle for receiving packets
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
  *
  * @return Number of packets received
  * @retval <0 on failure
+ *
+ * @see odp_pktio_pktin_queues()
  */
-int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_recv_queue(odp_pktin_queue_t queue, odp_packet_t packets[],
+int num);
 
 /**
  * Send packets
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 5/7] api: pktio: added direct send to pktio output queue

2015-11-19 Thread Petri Savolainen
Added odp_pktio_send_queue for direct packet send to
a pktio output queue.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9160261..443841e 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -443,21 +443,44 @@ int odp_pktio_recv_queue(odp_pktin_queue_t queue, 
odp_packet_t packets[],
 int num);
 
 /**
- * Send packets
+ * Send packets directly to an interface
  *
- * Sends out a number of packets. A successful call returns the actual number 
of
- * packets sent. If return value is less than 'len', the remaining packets at
- * the end of pkt_table[] are not consumed, and the caller has to take care of
- * them.
+ * Sends out a number of packets to the interface. The operation is
+ * multi-thread safe. A successful call returns the actual number of
+ * packets sent. If return value is less than 'num', the remaining packets at
+ * the end of packets[] array are not consumed, and the caller has to take
+ * care of them.
  *
  * @param pktioPacket IO handle
- * @param pkt_table[]  Array of packets to send
- * @param len  length of pkt_table[]
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
  *
  * @return Number of packets sent
  * @retval <0 on failure
  */
-int odp_pktio_send(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_send(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Send packets directly to an interface output queue
+ *
+ * Sends out a number of packets to the interface output queue. When
+ * 'single_user' output queue parameter has been set, the operation is 
optimized
+ * for single thread per queue usage model and the same queue must not be
+ * accessed from multiple threads.
+ *
+ * A successful call returns the actual number of packets sent. If return value
+ * is less than 'num', the remaining packets at the end of packets[] array
+ * are not consumed, and the caller has to take care of them.
+ *
+ * @param queuePktio output queue handle for sending packets
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
+ *
+ * @return Number of packets sent
+ * @retval <0 on failure
+ */
+int odp_pktio_send_queue(odp_pktout_queue_t queue, odp_packet_t packets[],
+int num);
 
 /**
  * Set the default input queue to be associated with a pktio handle
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 0/7] Multi-queue packet io APIs

2015-11-19 Thread Petri Savolainen
This patch set adds APIs for multi-queue packet IO. It does not remove or modify
existing API calls, so that multi-queue can be verified first with couple of 
apps and implementations. Single queue APIs (e.g. odp_pktio_inq_setdef()) and 
potentially plain _recv() and _send() should be removed once everything is 
ported to use the new API (potentially with num_queues == 1).

Configuration of multiple packet input and output queues fit better into pktio 
API than classification and TM APIs. Multi-queue is more generally needed (and 
provided) than classification or TM. Classification (and potentially TM) API 
spec should be aligned to use the new default input/output queue setup.

v3:
 * added dummy implementations (6/7)
 * modified l2fwd to use multi-queue API in direct mode (7/7)
 * use term single_user instead of single_thr
 * use term hash_enable instead of hash_ena

v2:
 * changed hash proto to bit field to allow selection of multiple protocols
 * added IPv4 and IPv6 protocols
 * defined odp_pktin_queue_t and pktout_queue_t handle types instead 
   of using indexes
 * use term single_thr instead of lock_free
 * added hash_ena to control if hashing (or classification) is used for 
   spreading flows to multiple queues


Petri Savolainen (7):
  api: pktio: added pktio capability struct
  api: pktio: added multiple pktio input queues
  api: pktio: added direct queue receive
  api: pktio: added multiple pktio output queues
  api: pktio: added direct send to pktio output queue
  linux-generic: pktio: dummy multi-queue pktio
  test: l2fwd: use multi-queue pktio in direct mode

 include/odp/api/packet_io.h| 302 ++-
 .../include/odp/plat/packet_io_types.h |  14 +-
 .../linux-generic/include/odp_packet_io_internal.h |  46 +++
 platform/linux-generic/odp_packet_io.c | 280 ++
 platform/linux-generic/pktio/loop.c|  10 +-
 platform/linux-generic/pktio/netmap.c  |  10 +-
 platform/linux-generic/pktio/pcap.c|  10 +-
 platform/linux-generic/pktio/socket.c  |  10 +-
 platform/linux-generic/pktio/socket_mmap.c |  10 +-
 test/performance/odp_l2fwd.c   | 414 ++---
 10 files changed, 1025 insertions(+), 81 deletions(-)

-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 2/7] api: pktio: added multiple pktio input queues

2015-11-19 Thread Petri Savolainen
Added input queue configuration parameters and functions
to setup multiple input queue and hashing. Added also
functions to query the number of queues and queue handles.
Direct receive does use new odp_pktin_queue_t handle type.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 136 +
 .../include/odp/plat/packet_io_types.h |   2 +
 2 files changed, 138 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 264fa75..26c9be5 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -19,6 +19,7 @@ extern "C" {
 #endif
 
 #include 
+#include 
 
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
@@ -42,6 +43,11 @@ extern "C" {
  */
 
 /**
+ * @typedef odp_pktin_queue_t
+ * Direct packet input queue handle
+ */
+
+/**
  * @def ODP_PKTIO_INVALID
  * Invalid packet IO handle
  */
@@ -85,6 +91,66 @@ typedef enum odp_pktio_output_mode_t {
 } odp_pktio_output_mode_t;
 
 /**
+ * Packet input hash protocols
+ *
+ * The list of protocol header field combinations, which are included into
+ * packet input hash calculation.
+ */
+typedef union odp_pktin_hash_proto_t {
+   /** Protocol header fields for hashing */
+   struct {
+   /** IPv4 addresses and UDP port numbers */
+   uint32_t ipv4_udp : 1;
+   /** IPv4 addresses and TCP port numbers */
+   uint32_t ipv4_tcp : 1;
+   /** IPv4 addresses */
+   uint32_t ipv4 : 1;
+   /** IPv6 addresses and UDP port numbers */
+   uint32_t ipv6_udp : 1;
+   /** IPv6 addresses and TCP port numbers */
+   uint32_t ipv6_tcp : 1;
+   /** IPv6 addresses */
+   uint32_t ipv6 : 1;
+   } proto;
+
+   /** All bits of the bit field structure */
+   uint32_t all_bits;
+} odp_pktin_hash_proto_t;
+
+/**
+ * Packet input queue parameters
+ */
+typedef struct odp_pktio_input_queue_param_t {
+   /** Single thread per queue. Enable performance optimization when each
+ * queue has only single user.
+ * 0: Queue is multi-thread safe
+ * 1: Queue is used by single thread only */
+   odp_bool_t single_user;
+
+   /** Enable flow hashing
+ * 0: Do not hash flows
+ * 1: Hash flows to input queues */
+   odp_bool_t hash_enable;
+
+   /** Protocol field selection for hashing. Multiple protocols can be
+ * selected. */
+   odp_pktin_hash_proto_t hash_proto;
+
+   /** Number of input queues to be created. More than one input queue
+ * require input hashing or classifier setup. Hash_proto is ignored
+ * when hash_enable is zero or num_queues is one. This value must be
+ * between 1 and interface capability. Queue type is defined by the
+ * input mode. */
+   unsigned num_queues;
+
+   /** Queue parameters for creating input queues in ODP_PKTIN_MODE_POLL
+ * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered
+ * only in ODP_PKTIN_MODE_SCHED mode. */
+   odp_queue_param_t queue_param;
+
+} odp_pktio_input_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -158,6 +224,67 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
 
 /**
+ * Configure packet input queues
+ *
+ * Setup a number of packet input queues and configure those. The maximum 
number
+ * of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). Queue handles for input queues can be requested with
+ * odp_pktio_in_queues() or odp_pktio_pktin_queues() after this call. All
+ * requested queues are setup on success, no queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket input queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_in_queues(), odp_pktio_pktin_queues()
+ */
+int odp_pktio_input_queues_config(odp_pktio_t pktio,
+ const odp_pktio_input_queue_param_t *param);
+
+/**
+ * Queues for packet input
+ *
+ * Returns the number of input queues configured for the interface in
+ * ODP_PKTIN_MODE_POLL and ODP_PKTIN_MODE_SCHED modes. Outputs up to 'num' 
queue
+ * handles when the 'queues' array pointer is not NULL. If return value is
+ * larger than 'num', there are more queues than the function was allowed to
+ * output.
+ *
+ * Packets (and other events) from these queues are received with
+ * odp_queue_deq(), odp_schedule(), etc calls.
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param

[lng-odp] [API-NEXT PATCH v3 1/7] api: pktio: added pktio capability struct

2015-11-19 Thread Petri Savolainen
Added capability structure and a function to query it.
Capability limits are used for advanced pktio configuration,
like configuration of multiple input/output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9409388..264fa75 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -98,6 +98,16 @@ typedef struct odp_pktio_param_t {
 } odp_pktio_param_t;
 
 /**
+ * Packet IO capabilities
+ */
+typedef struct odp_pktio_capability_t {
+   /** Maximum number of input queues */
+   unsigned max_input_queues;
+   /** Maximum number of output queues */
+   unsigned max_output_queues;
+} odp_pktio_capability_t;
+
+/**
  * Open a packet IO interface
  *
  * An ODP program can open a single packet IO interface per device, attempts
@@ -135,6 +145,19 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
   const odp_pktio_param_t *param);
 
 /**
+ * Query packet IO interface capabilities
+ *
+ * Outputs packet IO interface capabilities on success.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] capa   Pointer to capability structure for output
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 4/7] api: pktio: added multiple pktio output queues

2015-11-19 Thread Petri Savolainen
Added output queue configuration parameters and functions
for setting up multiple output queues. Added also
a function to query the number of output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 71 ++
 .../include/odp/plat/packet_io_types.h |  2 +
 2 files changed, 73 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index bf9b1f9..9160261 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -48,6 +48,11 @@ extern "C" {
  */
 
 /**
+ * @typedef odp_pktout_queue_t
+ * Direct packet output queue handle
+ */
+
+/**
  * @def ODP_PKTIO_INVALID
  * Invalid packet IO handle
  */
@@ -151,6 +156,24 @@ typedef struct odp_pktio_input_queue_param_t {
 } odp_pktio_input_queue_param_t;
 
 /**
+ * Packet output queue parameters
+ *
+ * These parameters are used only in ODP_PKTOUT_MODE_SEND mode.
+ */
+typedef struct odp_pktio_output_queue_param_t {
+   /** Single thread per queue. Enable performance optimization when each
+ * queue has only single user.
+ * 0: Queue is multi-thread safe
+ * 1: Queue is used by single thread only */
+   odp_bool_t single_user;
+
+   /** Number of output queues to be created. The value must be between
+ * 1 and interface capability */
+   unsigned num_queues;
+
+} odp_pktio_output_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -244,6 +267,25 @@ int odp_pktio_input_queues_config(odp_pktio_t pktio,
  const odp_pktio_input_queue_param_t *param);
 
 /**
+ * Configure packet output queues
+ *
+ * Setup a number of packet output queues and configure those. The maximum
+ * number of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). All requested queues are setup on success, no
+ * queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket output queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_pktout_queues()
+ */
+int odp_pktio_output_queues_config(odp_pktio_t pktio,
+  const odp_pktio_output_queue_param_t *param);
+
+/**
  * Queues for packet input
  *
  * Returns the number of input queues configured for the interface in
@@ -285,6 +327,26 @@ int odp_pktio_pktin_queues(odp_pktio_t pktio, 
odp_pktin_queue_t queues[],
   int num);
 
 /**
+ * Direct packet output queues
+ *
+ * Returns the number of output queues configured for the interface in
+ * ODP_PKTOUT_MODE_SEND mode. Outputs up to 'num' queue handles when the
+ * 'queues' array pointer is not NULL. If return value is larger than 'num',
+ * there are more queues than the function was allowed to output.
+ *
+ * Packets are sent to these queues with odp_pktio_send_queue().
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param  num  Maximum number of queue handles to output
+ *
+ * @return Number of packet output queues
+ * @retval <0 on failure
+ */
+int odp_pktio_pktout_queues(odp_pktio_t pktio, odp_pktout_queue_t queues[],
+   int num);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
@@ -570,6 +632,15 @@ void odp_pktio_param_init(odp_pktio_param_t *param);
 void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param);
 
 /**
+ * Initialize packet output queue parameters
+ *
+ * Initialize an odp_pktio_output_queue_param_t to its default values.
+ *
+ * @param param   Output queue parameter structure to be initialized
+ */
+void odp_pktio_output_queue_param_init(odp_pktio_output_queue_param_t *param);
+
+/**
  * Print pktio info to the console
  *
  * Print implementation-defined pktio debug information to the console.
diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h 
b/platform/linux-generic/include/odp/plat/packet_io_types.h
index 2e229c3..1086463 100644
--- a/platform/linux-generic/include/odp/plat/packet_io_types.h
+++ b/platform/linux-generic/include/odp/plat/packet_io_types.h
@@ -30,6 +30,8 @@ typedef ODP_HANDLE_T(odp_pktio_t);
 
 typedef ODP_HANDLE_T(odp_pktin_queue_t);
 
+typedef ODP_HANDLE_T(odp_pktout_queue_t);
+
 #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0)
 
 #define ODP_PKTIO_ANY _odp_cast_scalar(odp_pktio_t, ~0)
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3] api: atomic: added atomic_lock_free_u64

2015-11-12 Thread Petri Savolainen
Platforms may support some uint64 operations lock-free and
others not. For example, inc_64 can be natively supported but
cas_64 (or max_64/min_64) not. User may be able to switch to
32 bit variables when a 64 bit operation uses locks. The same
atomic operation struture could be used for platform init to guide
lock vs. lock-free implementation (e.g. if cas_64 is never
called, inc_64 can be lock-free).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 48 +
 platform/linux-generic/Makefile.am  |  1 +
 platform/linux-generic/odp_atomic.c | 24 +++
 3 files changed, 73 insertions(+)
 create mode 100644 platform/linux-generic/odp_atomic.c

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 316f13a..5e897c1 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -388,6 +388,54 @@ void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
+ * Atomic operations
+ *
+ * Atomic operations listed in a bit field structure.
+ */
+typedef union odp_atomic_op_t {
+   /** Operation flags */
+   struct {
+   uint32_t init  : 1;  /**< Init atomic variable */
+   uint32_t load  : 1;  /**< Atomic load */
+   uint32_t store : 1;  /**< Atomic store */
+   uint32_t fetch_add : 1;  /**< Atomic fetch and add */
+   uint32_t add   : 1;  /**< Atomic add */
+   uint32_t fetch_sub : 1;  /**< Atomic fetch and substract */
+   uint32_t sub   : 1;  /**< Atomic substract */
+   uint32_t fetch_inc : 1;  /**< Atomic fetch and increment */
+   uint32_t inc   : 1;  /**< Atomic increment */
+   uint32_t fetch_dec : 1;  /**< Atomic fetch and decrement */
+   uint32_t dec   : 1;  /**< Atomic decrement */
+   uint32_t min   : 1;  /**< Atomic minimum */
+   uint32_t max   : 1;  /**< Atomic maximum */
+   uint32_t cas   : 1;  /**< Atomic compare and swap */
+   } op;
+
+   /** All bits of the bit field structure.
+ * Operation flag mapping is architecture specific. This field can be
+ * used to set/clear all flags, or bitwise operations over the entire
+ * structure. */
+   uint32_t all_bits;
+} odp_atomic_op_t;
+
+/**
+ * Query which atomic uint64 operations are lock-free
+ *
+ * Lock-free implementations have higher performance and scale better than
+ * implementations using locks. User can decide to use e.g. uint32 atomic
+ * variables instead of uint64 to optimize performance on platforms that
+ * implement a performance critical operation using locks.
+ *
+ * @param atomic_op  Pointer to atomic operation structure for storing
+ *   operation flags. All bits are initialized to zero during
+ *   the operation. The parameter is ignored when NULL.
+ * @retval 0 None of the operations are lock-free
+ * @retval 1 Some of the operations are lock-free
+ * @retval 2 All operations are lock-free
+ */
+int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index a6b6029..0b7234e 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -151,6 +151,7 @@ noinst_HEADERS = \
  ${srcdir}/Makefile.inc
 
 __LIB__libodp_la_SOURCES = \
+  odp_atomic.c \
   odp_barrier.c \
   odp_buffer.c \
   odp_classification.c \
diff --git a/platform/linux-generic/odp_atomic.c 
b/platform/linux-generic/odp_atomic.c
new file mode 100644
index 000..996d09a
--- /dev/null
+++ b/platform/linux-generic/odp_atomic.c
@@ -0,0 +1,24 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include 
+
+int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   /* All operations have locks */
+   if (atomic_op)
+   atomic_op->all_bits = 0;
+
+   return 0;
+#else
+   /* All operations are lock-free */
+   if (atomic_op)
+   atomic_op->all_bits = ~((uint32_t)0);
+
+   return 2;
+#endif
+}
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 0/5] Multi-queue packet io APIs

2015-11-12 Thread Petri Savolainen
This patch set adds APIs for multi-queue packet IO. It does not remove or modify
existing API calls, so that multi-queue can be verified first with couple of 
apps and implementations. Single queue APIs (e.g. odp_pktio_inq_setdef()) and 
potentially plain _recv() and _send() should be removed once everything is 
ported to use the new API (potentially with num_queues == 1).

Configuration of multiple packet input and output queues fit better into pktio 
API than classification and TM APIs. Multi-queue is more generally needed (and 
provided) than classification or TM. Classification (and potentially TM) API 
spec should be aligned to use the new default input/output queue setup.

v2:
 * changed hash proto to bit field to allow selection of multiple protocols
 * added IPv4 and IPv6 protocols
 * defined odp_pktin_queue_t and pktout_queue_t handle types instead 
   of using indexes
 * use term single_thr instead of lock_free
 * added hash_ena to control if hashing (or classification) is used for 
   spreading flows to multiple queues


Petri Savolainen (5):
  api: pktio: added pktio capability struct
  api: pktio: added multiple pktio input queues
  api: pktio: added direct queue receive
  api: pktio: added multiple pktio output queues
  api: pktio: added direct send to pktio output queue

 include/odp/api/packet_io.h| 297 -
 .../include/odp/plat/packet_io_types.h |   4 +
 2 files changed, 288 insertions(+), 13 deletions(-)

-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 3/5] api: pktio: added direct queue receive

2015-11-12 Thread Petri Savolainen
Added odp_pktio_recv_queue for direct packet receive from pktio
input queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index a27d88a..07aaa7d 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -343,16 +343,39 @@ int odp_pktio_close(odp_pktio_t pktio);
 odp_pktio_t odp_pktio_lookup(const char *dev);
 
 /**
- * Receive packets
+ * Receive packets directly from an interface
  *
- * @param pktio   Packet IO handle
- * @param pkt_table[] Storage for received packets (filled by function)
- * @param len Length of pkt_table[], i.e. max number of pkts to receive
+ * Receives up to 'num' packets from the interface. The operation is
+ * multi-thread safe.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
+ *
+ * @return Number of packets received
+ * @retval <0 on failure
+ */
+int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Receive packets directly from an interface input queue
+ *
+ * Receives up to 'num' packets from the pktio interface input queue. When
+ * 'single_thr' input queue parameter has been set, the operation is optimized
+ * for single thread usage and the same queue must not be accessed from 
multiple
+ * threads.
+ *
+ * @param  queue  Pktio input queue handle for receiving packets
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
  *
  * @return Number of packets received
  * @retval <0 on failure
+ *
+ * @see odp_pktio_pktin_queues()
  */
-int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_recv_queue(odp_pktin_queue_t queue, odp_packet_t packets[],
+int num);
 
 /**
  * Send packets
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 2/5] api: pktio: added multiple pktio input queues

2015-11-12 Thread Petri Savolainen
Added input queue configuration parameters and functions
to setup multiple input queue and hashing. Added also
functions to query the number of queues and queue handles.
Direct receive does use new odp_pktin_queue_t handle type.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 133 +
 .../include/odp/plat/packet_io_types.h |   2 +
 2 files changed, 135 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 264fa75..a27d88a 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -19,6 +19,7 @@ extern "C" {
 #endif
 
 #include 
+#include 
 
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
@@ -42,6 +43,11 @@ extern "C" {
  */
 
 /**
+ * @typedef odp_pktin_queue_t
+ * Direct packet input queue handle
+ */
+
+/**
  * @def ODP_PKTIO_INVALID
  * Invalid packet IO handle
  */
@@ -85,6 +91,63 @@ typedef enum odp_pktio_output_mode_t {
 } odp_pktio_output_mode_t;
 
 /**
+ * Packet input hash protocols
+ *
+ * The list of protocol header field combinations, which are included into
+ * packet input hash calculation.
+ */
+typedef union odp_pktin_hash_proto_t {
+   /** Protocol header fields for hashing */
+   struct {
+   /** IPv4 addresses and UDP port numbers */
+   uint32_t ipv4_udp : 1;
+   /** IPv4 addresses and TCP port numbers */
+   uint32_t ipv4_tcp : 1;
+   /** IPv4 addresses */
+   uint32_t ipv4 : 1;
+   /** IPv6 addresses and UDP port numbers */
+   uint32_t ipv6_udp : 1;
+   /** IPv6 addresses and TCP port numbers */
+   uint32_t ipv6_tcp : 1;
+   /** IPv6 addresses */
+   uint32_t ipv6 : 1;
+   } proto;
+
+   /** All bits of the bit field structure */
+   uint32_t all_bits;
+} odp_pktin_hash_proto_t;
+
+/**
+ * Packet input queue parameters
+ */
+typedef struct odp_pktio_input_queue_param_t {
+   /** Enable performance optimization for single thread per queue
+ * 0: Queue is multi-thread safe, 1: Queue is for single thread */
+   odp_bool_t single_thr;
+
+   /** Enable flow hashing
+ * 0: Do not hash, 1: Hash flows to input queues */
+   odp_bool_t hash_ena;
+
+   /** Protocol field selection for hashing. Multiple protocols can be
+ * selected. */
+   odp_pktin_hash_proto_t hash_proto;
+
+   /** Number of input queues to be created. More than one input queue
+ * require input hashing or classifier setup. Hash_proto is ignored
+ * when hash_ena is zero or num_queues is one. This value must be
+ * between 1 and interface capability. Queue type is defined by the
+ * input mode. */
+   unsigned num_queues;
+
+   /** Queue parameters for creating input queues in ODP_PKTIN_MODE_POLL
+ * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered
+ * only in ODP_PKTIN_MODE_SCHED mode. */
+   odp_queue_param_t queue_param;
+
+} odp_pktio_input_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -158,6 +221,67 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
 
 /**
+ * Configure packet input queues
+ *
+ * Setup a number of packet input queues and configure those. The maximum 
number
+ * of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). Queue handles for input queues can be requested with
+ * odp_pktio_in_queues() or odp_pktio_pktin_queues() after this call. All
+ * requested queues are setup on success, no queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket input queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_in_queues(), odp_pktio_pktin_queues()
+ */
+int odp_pktio_input_queues_config(odp_pktio_t pktio,
+ const odp_pktio_input_queue_param_t *param);
+
+/**
+ * Queues for packet input
+ *
+ * Returns the number of input queues configured for the interface in
+ * ODP_PKTIN_MODE_POLL and ODP_PKTIN_MODE_SCHED modes. Outputs up to 'num' 
queue
+ * handles when the 'queues' array pointer is not NULL. If return value is
+ * larger than 'num', there are more queues than the function was allowed to
+ * output.
+ *
+ * Packets (and other events) from these queues are received with
+ * odp_queue_deq(), odp_schedule(), etc calls.
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param  num  Maximum number of queue handles to output
+ *
+ * @return Number of packe

[lng-odp] [API-NEXT PATCH v2 1/5] api: pktio: added pktio capability struct

2015-11-12 Thread Petri Savolainen
Added capability structure and a function to query it.
Capability limits are used for advanced pktio configuration,
like configuration of multiple input/output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9409388..264fa75 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -98,6 +98,16 @@ typedef struct odp_pktio_param_t {
 } odp_pktio_param_t;
 
 /**
+ * Packet IO capabilities
+ */
+typedef struct odp_pktio_capability_t {
+   /** Maximum number of input queues */
+   unsigned max_input_queues;
+   /** Maximum number of output queues */
+   unsigned max_output_queues;
+} odp_pktio_capability_t;
+
+/**
  * Open a packet IO interface
  *
  * An ODP program can open a single packet IO interface per device, attempts
@@ -135,6 +145,19 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
   const odp_pktio_param_t *param);
 
 /**
+ * Query packet IO interface capabilities
+ *
+ * Outputs packet IO interface capabilities on success.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] capa   Pointer to capability structure for output
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 5/5] api: pktio: added direct send to pktio output queue

2015-11-12 Thread Petri Savolainen
Added odp_pktio_send_queue for direct packet send to
a pktio output queue.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 8c17718..f6dede9 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -438,21 +438,44 @@ int odp_pktio_recv_queue(odp_pktin_queue_t queue, 
odp_packet_t packets[],
 int num);
 
 /**
- * Send packets
+ * Send packets directly to an interface
  *
- * Sends out a number of packets. A successful call returns the actual number 
of
- * packets sent. If return value is less than 'len', the remaining packets at
- * the end of pkt_table[] are not consumed, and the caller has to take care of
- * them.
+ * Sends out a number of packets to the interface. The operation is
+ * multi-thread safe. A successful call returns the actual number of
+ * packets sent. If return value is less than 'num', the remaining packets at
+ * the end of packets[] array are not consumed, and the caller has to take
+ * care of them.
  *
  * @param pktioPacket IO handle
- * @param pkt_table[]  Array of packets to send
- * @param len  length of pkt_table[]
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
  *
  * @return Number of packets sent
  * @retval <0 on failure
  */
-int odp_pktio_send(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_send(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Send packets directly to an interface output queue
+ *
+ * Sends out a number of packets to the interface output queue. When
+ * 'single_thr' output queue parameter has been set, the operation is optimized
+ * for single thread usage and the same queue must not be accessed from 
multiple
+ * threads.
+ *
+ * A successful call returns the actual number of packets sent. If return value
+ * is less than 'num', the remaining packets at the end of packets[] array
+ * are not consumed, and the caller has to take care of them.
+ *
+ * @param queuePktio output queue handle for sending packets
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
+ *
+ * @return Number of packets sent
+ * @retval <0 on failure
+ */
+int odp_pktio_send_queue(odp_pktout_queue_t queue, odp_packet_t packets[],
+int num);
 
 /**
  * Set the default input queue to be associated with a pktio handle
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2] api: atomic: added atomic_lock_free_u64

2015-11-11 Thread Petri Savolainen
Platforms may support some uint64 operations lock-free and
others not. For example, inc_64 can be natively supported but
cas_64 (or max_64/min_64) not. User may be able to switch to
32 bit variables when a 64 bit operation uses locks. The same
atomic operation struture could be used for platform init to guide
lock vs. lock-free implementation (e.g. if cas_64 is never
called, inc_64 can be lock-free).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 51 +
 platform/linux-generic/Makefile.am  |  1 +
 platform/linux-generic/odp_atomic.c | 26 +++
 3 files changed, 78 insertions(+)
 create mode 100644 platform/linux-generic/odp_atomic.c

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 316f13a..17a38fb 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -388,6 +388,57 @@ void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
+ * Atomic operations
+ *
+ * Atomic operations listed in a bit field structure.
+ */
+typedef union odp_atomic_op_t {
+   /** Operation flags */
+   struct {
+   uint32_t init  : 1;  /**< Atomic init */
+   uint32_t load  : 1;  /**< Atomic load */
+   uint32_t store : 1;  /**< Atomic store */
+   uint32_t fetch_add : 1;  /**< Atomic fetch and add */
+   uint32_t add   : 1;  /**< Atomic add */
+   uint32_t fetch_sub : 1;  /**< Atomic fetch and substract */
+   uint32_t sub   : 1;  /**< Atomic substract */
+   uint32_t fetch_inc : 1;  /**< Atomic fetch and increment */
+   uint32_t inc   : 1;  /**< Atomic increment */
+   uint32_t fetch_dec : 1;  /**< Atomic fetch and decrement */
+   uint32_t dec   : 1;  /**< Atomic decrement */
+   uint32_t min   : 1;  /**< Atomic minimum */
+   uint32_t max   : 1;  /**< Atomic maximum */
+   uint32_t cas   : 1;  /**< Atomic compare and swap */
+   uint32_t _reserved : 18; /**< Reserved - do not use */
+   } op;
+
+   /** All flags */
+   union {
+   uint32_t ops   : 14; /**< All operations*/
+   uint32_t _reserved : 18; /**< Reserved - do not use */
+
+   uint32_t bits;   /**< All bits */
+   } all;
+} odp_atomic_op_t;
+
+/**
+ * Query which atomic uint64 operations are lock-free
+ *
+ * Lock-free implementations have higher performance and scale better than
+ * implementations using locks. User can decide to use e.g. uint32 atomic
+ * variables instead of uint64 to optimize performance on platforms that
+ * implement a performance critical operation using locks.
+ *
+ * @param atomic_op  Pointer to atomic operation structure for storing
+ *   operation flags. All bits are initialized to zero during
+ *   the operation. The parameter is ignored when NULL.
+ * @retval 0 None of the operations are lock-free
+ * @retval 1 Some of the operations are lock-free
+ * @retval 2 All operations are lock-free
+ */
+int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index a6b6029..0b7234e 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -151,6 +151,7 @@ noinst_HEADERS = \
  ${srcdir}/Makefile.inc
 
 __LIB__libodp_la_SOURCES = \
+  odp_atomic.c \
   odp_barrier.c \
   odp_buffer.c \
   odp_classification.c \
diff --git a/platform/linux-generic/odp_atomic.c 
b/platform/linux-generic/odp_atomic.c
new file mode 100644
index 000..8955b41
--- /dev/null
+++ b/platform/linux-generic/odp_atomic.c
@@ -0,0 +1,26 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include 
+
+int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   /* All operations have locks */
+   if (atomic_op)
+   atomic_op->all.bits = 0;
+
+   return 0;
+#else
+   /* All operations are lock-free */
+   if (atomic_op) {
+   atomic_op->all.bits = 0;
+   atomic_op->all.ops  = 0x3fff;
+   }
+
+   return 2;
+#endif
+}
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 4/5] api: pktio: added multiple pktio output queues

2015-11-06 Thread Petri Savolainen
Added output queue configuration parameters and functions
for setting up multiple output queues. Added also
odp_pktio_output_queues to query the number of queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 57 +
 1 file changed, 57 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 1723d61..aa218f2 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -123,6 +123,22 @@ typedef struct odp_pktio_input_queue_param_t {
 } odp_pktio_input_queue_param_t;
 
 /**
+ * Packet output queue parameters
+ *
+ * These parameters are used only in ODP_PKTOUT_MODE_SEND mode.
+ */
+typedef struct odp_pktio_output_queue_param_t {
+   /** Enable lock-free send operation per queue
+ * 0: Send is multi-thread safe, 1: Send is lock-free */
+   odp_bool_t lock_free;
+
+   /** Number of output queues to be created. The value must be between
+ * 1 and interface capability */
+   unsigned num_queues;
+
+} odp_pktio_output_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -216,6 +232,25 @@ int odp_pktio_input_queues_config(odp_pktio_t pktio,
  const odp_pktio_input_queue_param_t *param);
 
 /**
+ * Configure packet output queues
+ *
+ * Setup a number of packet output queues and configure those. The maximum
+ * number of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). All requested queues are setup on success, no
+ * queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket output queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_output_queues()
+ */
+int odp_pktio_output_queues_config(odp_pktio_t pktio,
+  const odp_pktio_output_queue_param_t *param);
+
+/**
  * Packet input queues
  *
  * Returns the number of input queues configured for the interface. Outputs 
also
@@ -237,6 +272,19 @@ int odp_pktio_input_queues_config(odp_pktio_t pktio,
 int odp_pktio_input_queues(odp_pktio_t pktio, odp_queue_t queues[], int num);
 
 /**
+ * Packet output queues
+ *
+ * Returns the number of output queues configured for the interface. These
+ * output queues are used only in ODP_PKTOUT_MODE_SEND mode.
+ *
+ * @param  pktioPacket IO handle
+ *
+ * @return Number of packet output queues
+ * @retval <0 on failure
+ */
+int odp_pktio_output_queues(odp_pktio_t pktio);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
@@ -525,6 +573,15 @@ void odp_pktio_param_init(odp_pktio_param_t *param);
 void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param);
 
 /**
+ * Initialize packet output queue parameters
+ *
+ * Initialize an odp_pktio_output_queue_param_t to its default values.
+ *
+ * @param param   Output queue parameter structure to be initialized
+ */
+void odp_pktio_output_queue_param_init(odp_pktio_output_queue_param_t *param);
+
+/**
  * Print pktio info to the console
  *
  * Print implementation-defined pktio debug information to the console.
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 5/5] api: pktio: added direct send to pktio output queue

2015-11-06 Thread Petri Savolainen
Added odp_pktio_send_queue for direct packet send to
a pktio output queue.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 42 ++
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index aa218f2..6b72482 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -384,21 +384,47 @@ int odp_pktio_recv_queue(odp_pktio_t pktio, unsigned 
queue_id,
 odp_packet_t packets[], int num);
 
 /**
- * Send packets
+ * Send packets directly to an interface
  *
- * Sends out a number of packets. A successful call returns the actual number 
of
- * packets sent. If return value is less than 'len', the remaining packets at
- * the end of pkt_table[] are not consumed, and the caller has to take care of
- * them.
+ * Sends out a number of packets to the interface. The operation is
+ * multi-thread safe. A successful call returns the actual number of
+ * packets sent. If return value is less than 'num', the remaining packets at
+ * the end of packets[] array are not consumed, and the caller has to take
+ * care of them.
  *
  * @param pktioPacket IO handle
- * @param pkt_table[]  Array of packets to send
- * @param len  length of pkt_table[]
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
  *
  * @return Number of packets sent
  * @retval <0 on failure
  */
-int odp_pktio_send(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_send(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Send packets directly to an interface output queue
+ *
+ * Sends out a number of packets to the interface output queue defined by the
+ * queue index. The operation is lock-free if 'lock_free' output queue 
parameter
+ * has been set. Application must not share a lock-free output queue between
+ * multiple threads.
+ *
+ * A successful call returns the actual number of packets sent. If return value
+ * is less than 'num', the remaining packets at the end of packets[] array
+ * are not consumed, and the caller has to take care of them.
+ *
+ * @param pktioPacket IO handle
+ * @param queue_id The output queue index to send packets.
+ * The index must be between 0 and number of output queues
+ * minus one.
+ * @param packets[]Array of packets to send
+ * @param num  Number of packets to send
+ *
+ * @return Number of packets sent
+ * @retval <0 on failure
+ */
+int odp_pktio_send_queue(odp_pktio_t pktio, unsigned queue_id,
+odp_packet_t packets[], int num);
 
 /**
  * Set the default input queue to be associated with a pktio handle
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 2/5] api: pktio: added multiple pktio input queues

2015-11-06 Thread Petri Savolainen
Added input queue configuration parameters and functions
to setup multiple input queue and hashing. Added also
odp_pktio_input_queues to query the number of queues
and queue handles. Direct receive does not use queue
handles, but indexes.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 88 +
 1 file changed, 88 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 264fa75..bb0e67c 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -19,6 +19,7 @@ extern "C" {
 #endif
 
 #include 
+#include 
 
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
@@ -85,6 +86,43 @@ typedef enum odp_pktio_output_mode_t {
 } odp_pktio_output_mode_t;
 
 /**
+ * Packet input hash protocols
+ *
+ * The list of protocol header field combinations, which are included into
+ * packet input hash calculation.
+ */
+typedef enum odp_pktin_hash_proto_t {
+   /** IPv4 addresses and UDP port numbers, non-fragmented packets */
+   ODP_PKTIN_HASH_IPV4_UDP = 0,
+   /** IPv4 addresses and TCP port numbers, non-fragmented packets */
+   ODP_PKTIN_HASH_IPV4_TCP
+} odp_pktin_hash_proto_t;
+
+/**
+ * Packet input queue parameters
+ */
+typedef struct odp_pktio_input_queue_param_t {
+   /** Enable lock-free receive operation per queue
+ * 0: Receive is multi-thread safe, 1: Receive is lock-free */
+   odp_bool_t lock_free;
+
+   /** Select protocol fields used for hashing */
+   odp_pktin_hash_proto_t hash_proto;
+
+   /** Number of input queues to be created. More than one input queue
+ * require input hashing. Hash_proto is ignore when num_queues is one.
+ * The value must be between 1 and interface capability. Queue type is
+ * defined by the input mode. */
+   unsigned num_queues;
+
+   /** Queue parameters for creating input queues in ODP_PKTIN_MODE_POLL
+ * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are considered
+ * only in ODP_PKTIN_MODE_SCHED mode. */
+   odp_queue_param_t queue_param;
+
+} odp_pktio_input_queue_param_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -158,6 +196,47 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
 
 /**
+ * Configure packet input queues
+ *
+ * Setup a number of packet input queues and configure those. The maximum 
number
+ * of queues is platform dependent and can be queried with
+ * odp_pktio_capability(). Queue handles for input queues can be requested with
+ * odp_pktio_input_queues() after this call. All requested queues are setup on
+ * success, no queues are setup on failure.
+ *
+ * @param pktioPacket IO handle
+ * @param paramPacket input queue configuration parameters
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_pktio_capability(), odp_pktio_input_queues()
+ */
+int odp_pktio_input_queues_config(odp_pktio_t pktio,
+ const odp_pktio_input_queue_param_t *param);
+
+/**
+ * Packet input queues
+ *
+ * Returns the number of input queues configured for the interface. Outputs 
also
+ * up to 'num' queue handles created for ODP_PKTIN_MODE_POLL and
+ * ODP_PKTIN_MODE_SCHED modes. If return value is larger than 'num', there are
+ * more queues than the function was allowed to output handles.
+ *
+ * Depending on the input mode, packets (or events) from these queues are
+ * received using odp_pktio_recv_queue(), odp_queue_deq(), odp_schedule(), etc
+ * calls.
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param  num  Maximum number of queue handles to output
+ *
+ * @return Number of packet input queues
+ * @retval <0 on failure
+ */
+int odp_pktio_input_queues(odp_pktio_t pktio, odp_queue_t queues[], int num);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
@@ -411,6 +490,15 @@ uint64_t odp_pktio_to_u64(odp_pktio_t pktio);
 void odp_pktio_param_init(odp_pktio_param_t *param);
 
 /**
+ * Initialize packet input queue parameters
+ *
+ * Initialize an odp_pktio_input_queue_param_t to its default values.
+ *
+ * @param param   Input queue parameter structure to be initialized
+ */
+void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param);
+
+/**
  * Print pktio info to the console
  *
  * Print implementation-defined pktio debug information to the console.
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 3/5] api: pktio: added direct queue receive

2015-11-06 Thread Petri Savolainen
Added odp_pktio_recv_queue for direct packet receive from pktio input
hash queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 36 +++-
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index bb0e67c..1723d61 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -298,16 +298,42 @@ int odp_pktio_close(odp_pktio_t pktio);
 odp_pktio_t odp_pktio_lookup(const char *dev);
 
 /**
- * Receive packets
+ * Receive packets directly from an interface
  *
- * @param pktio   Packet IO handle
- * @param pkt_table[] Storage for received packets (filled by function)
- * @param len Length of pkt_table[], i.e. max number of pkts to receive
+ * Receives up to 'num' packets from the interface. The operation is
+ * multi-thread safe.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
+ *
+ * @return Number of packets received
+ * @retval <0 on failure
+ */
+int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Receive packets directly from an interface input queue
+ *
+ * Receives up to 'num' packets from the interface input queue defined by the
+ * queue index. The operation is lock-free if 'lock_free' input queue parameter
+ * has been set. Application must not share a lock-free input queue between
+ * multiple threads.
+ *
+ * @param  pktio  Packet IO handle
+ * @param  queue_id   The input queue index from which to receive packets.
+ *The index must be between 0 and number of input 
queues
+ *minus one.
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param  numMaximum number of packets to receive
  *
  * @return Number of packets received
  * @retval <0 on failure
+ *
+ * @see odp_pktio_input_queues()
  */
-int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_recv_queue(odp_pktio_t pktio, unsigned queue_id,
+odp_packet_t packets[], int num);
 
 /**
  * Send packets
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 1/5] api: pktio: added pktio capability struct

2015-11-06 Thread Petri Savolainen
Added capability structure and a function to query it.
Capability limits are used for advanced pktio configuration,
like configuration of multiple input/output queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9409388..264fa75 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -98,6 +98,16 @@ typedef struct odp_pktio_param_t {
 } odp_pktio_param_t;
 
 /**
+ * Packet IO capabilities
+ */
+typedef struct odp_pktio_capability_t {
+   /** Maximum number of input queues */
+   unsigned max_input_queues;
+   /** Maximum number of output queues */
+   unsigned max_output_queues;
+} odp_pktio_capability_t;
+
+/**
  * Open a packet IO interface
  *
  * An ODP program can open a single packet IO interface per device, attempts
@@ -135,6 +145,19 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
   const odp_pktio_param_t *param);
 
 /**
+ * Query packet IO interface capabilities
+ *
+ * Outputs packet IO interface capabilities on success.
+ *
+ * @param  pktio  Packet IO handle
+ * @param[out] capa   Pointer to capability structure for output
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa);
+
+/**
  * Start packet receive and transmit
  *
  * Activate packet receive and transmit on a previously opened or stopped
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 0/5] *** Multi-queue packet io APIs ***

2015-11-06 Thread Petri Savolainen
This patch set adds APIs for multi-queue packet IO. It does not remove or modify
existing API calls, so that multi-queue can be verified first with couple of 
apps and implementations. Single queue APIs (e.g. odp_pktio_inq_setdef()) 
should be removed once everything is ported to use the new API (potentially with
num_queues == 1).

Configuration of multiple packet input and output queues fit better pktio API 
than e.g. classification API. Classification API should be aligned the new 
setup.


Petri Savolainen (5):
  api: pktio: added pktio capability struct
  api: pktio: added multiple pktio input queues
  api: pktio: added direct queue receive
  api: pktio: added multiple pktio output queues
  api: pktio: added direct send to pktio output queue

 include/odp/api/packet_io.h | 246 +---
 1 file changed, 233 insertions(+), 13 deletions(-)

-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT RFC 1/2] api: pktio: added input hash parameters

2015-11-03 Thread Petri Savolainen
Added parameters for setting up input hashing during pktio_open
and odp_pktio_input_hash_queues to query queue handles.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 60 +
 1 file changed, 60 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 9409388..7706049 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -19,6 +19,7 @@ extern "C" {
 #endif
 
 #include 
+#include 
 
 /** @defgroup odp_packet_io ODP PACKET IO
  *  Operations on a packet Input/Output interface.
@@ -85,6 +86,40 @@ typedef enum odp_pktio_output_mode_t {
 } odp_pktio_output_mode_t;
 
 /**
+ * Packet input hash protocols
+ *
+ * This is the list of protocol header field combinations included into
+ * hash calculation.
+ */
+typedef enum odp_pktin_hash_proto_t {
+   /** IPv4 addresses and UDP port numbers, non-fragmented packets */
+   ODP_PKTIN_HASH_IPV4_UDP = 0,
+   /** IPv4 addresses and TCP port numbers, non-fragmented packets */
+   ODP_PKTIN_HASH_IPV4_TCP
+} odp_pktin_hash_proto_t;
+
+/**
+ * Packet input hashing
+ */
+typedef struct odp_pktio_input_hash_t {
+   /** Enable input hashing
+ * 0: hashing disabled, 1: hashing enabled */
+   odp_bool_t enable;
+
+   /** Select protocol fields used for hashing */
+   odp_pktin_hash_proto_t proto;
+
+   /** Number of input queues for hashing. Queue type is
+ * defined by the input mode. Use 0 for default. */
+   unsigned num_queues;
+
+   /** Queue parameters. Scheduler parameters are read only in
+ * ODP_PKTIN_MODE_SCHED mode. */
+   odp_queue_param_t queue_param;
+
+} odp_pktio_input_hash_t;
+
+/**
  * Packet IO parameters
  *
  * In minimum, user must select input and output modes. Use 0 for defaults.
@@ -95,6 +130,8 @@ typedef struct odp_pktio_param_t {
odp_pktio_input_mode_t in_mode;
/** Packet output mode */
odp_pktio_output_mode_t out_mode;
+   /** Packet input hashing */
+   odp_pktio_input_hash_t in_hash;
 } odp_pktio_param_t;
 
 /**
@@ -265,6 +302,29 @@ int odp_pktio_inq_remdef(odp_pktio_t pktio);
 odp_queue_t odp_pktio_outq_getdef(odp_pktio_t pktio);
 
 /**
+ * Queues used for input hashing
+ *
+ * When input hashing is enabled, query handles for queues that are used for
+ * packet input hashing. Depending on input mode packets (or events) from these
+ * queues are received using odp_pktio_recv() (ODP_PKTIN_MODE_RECV),
+ * odp_schedule() (ODP_PKTIN_MODE_SCHED) or odp_queue_deq()
+ * (ODP_PKTIN_MODE_POLL).
+ *
+ * Outputs up to 'num' queue handles and returns the number of input hash
+ * queues created for the pktio interface. If return value is larger than 
'num',
+ * there are more queues than the function was allowed to output.
+ *
+ * @param  pktioPacket IO handle
+ * @param[out] queues   Points to an array of queue handles for output
+ * @param  num  Maximum number of queue handles
+ *
+ * @return Number of input hash queues
+ * @retval <0 on failure
+ */
+int odp_pktio_input_hash_queues(odp_pktio_t pktio, odp_queue_t queues[],
+   int num);
+
+/**
  * Return the currently configured MTU value of a packet IO interface.
  *
  * @param[in] pktio  Packet IO handle.
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT RFC 2/2] api: pktio: added direct queue receive

2015-11-03 Thread Petri Savolainen
Added odp_pktio_recv_queue for direct packet receive from pktio input
hash queues.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 7706049..3f5a065 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -233,16 +233,31 @@ int odp_pktio_close(odp_pktio_t pktio);
 odp_pktio_t odp_pktio_lookup(const char *dev);
 
 /**
- * Receive packets
+ * Receive packets directly from interface
  *
- * @param pktio   Packet IO handle
- * @param pkt_table[] Storage for received packets (filled by function)
- * @param len Length of pkt_table[], i.e. max number of pkts to receive
+ * @param  pktio  Packet IO handle
+ * @param[out] packets[]  Array of packet handles for received packets
+ * @param  numMaximum number of packets to receive
  *
  * @return Number of packets received
  * @retval <0 on failure
  */
-int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t pkt_table[], int len);
+int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t packets[], int num);
+
+/**
+ * Receive packets directly from a queue of an interface
+ *
+ * @param  pktio  Packet IO handle
+ * @param  queue  The input hash queue from which to receive packets.
+ *The queue must belong to the pktio interface.
+ * @param[out] packets[]  Array of packet handles for received packets
+ * @param  numMaximum number of packets to receive
+ *
+ * @return Number of packets received
+ * @retval <0 on failure
+ */
+int odp_pktio_recv_queue(odp_pktio_t pktio, odp_queue_t queue,
+odp_packet_t packets[], int num);
 
 /**
  * Send packets
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 1/2] api: version: added implementation name str

2015-11-02 Thread Petri Savolainen
Refined version API documentation and added implementation
name string that can be used to identify the underlying
implementation at run time.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/version.h | 47 ++-
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/include/odp/api/version.h b/include/odp/api/version.h
index c976f16..d7bce74 100644
--- a/include/odp/api/version.h
+++ b/include/odp/api/version.h
@@ -18,8 +18,15 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_version ODP VERSION
- *  @{
+/**
+ * @defgroup odp_version ODP VERSION
+ * @details
+ *  ODP API and implementation versions 
+ *
+ * ODP API version is identified by ODP_VERSION_API_XXX pre-processor macros.
+ * In addition to these macros, API calls can be used to identify 
implementation
+ * and API version information at run time.
+ * @{
  */
 
 /**
@@ -49,20 +56,42 @@ extern "C" {
 #define ODP_VERSION_API_MINOR 0
 
 /**
- * Returns ODP API version string
+ * ODP API version string
+ *
+ * The API version string defines ODP API version in this format:
+ * @verbatim .. @endverbatim
+ *
+ * The string is null terminated.
+ *
+ * @return Pointer to API version string
  */
 const char *odp_version_api_str(void);
 
+/**
+ * Implementation name string
+ *
+ * This is a free format string which identifies the implementation with a
+ * unique name. The string should be compact and remain constant over multiple
+ * API and implementation versions. Application can use this to identify the
+ * underlying implementation at run time. The string is null terminated.
+ *
+ * @return Pointer to implementation name string
+  */
+const char *odp_version_impl_name(void);
 
 /**
- * Returns ODP implementation version string
+ * Implementation version string
  *
- * Every implementation of ODP may receive bug fixes independent of the version
- * of the API changing, this function returns that indication string.
- * @note This string is implementation specific.
- * @sa odp_version_api_str()
+ * This is a free format string which identifies the implementation with
+ * detailed version information. The string may include information about
+ * implementation version, bug fix level, version control tags, build number,
+ * etc details which exactly identify the implementation code base.
+ * User may include this information e.g. to bug reports. The string is null
+ * terminated.
  *
- * @return null terminated implementation specific version identifier string
+ * @see odp_version_api_str(), odp_version_impl_name()
+ *
+ * @return Pointer to implementation specific version identifier string
   */
 const char *odp_version_impl_str(void);
 /**
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 2/2] linux-generic: version: implemented impl name str

2015-11-02 Thread Petri Savolainen
Implemented implementation name string and call it from
validation test common.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/odp_version.c  | 6 ++
 test/validation/common/odp_cunit_common.c | 1 +
 2 files changed, 7 insertions(+)

diff --git a/platform/linux-generic/odp_version.c 
b/platform/linux-generic/odp_version.c
index b5219d4..6ca8c51 100644
--- a/platform/linux-generic/odp_version.c
+++ b/platform/linux-generic/odp_version.c
@@ -10,3 +10,9 @@ const char *odp_version_api_str(void)
 {
return ODP_VERSION_API_STR;
 }
+
+const char *odp_version_impl_name(void)
+{
+   const char *str = ODP_VERSION_TO_STR(PLATFORM);
+   return str;
+}
diff --git a/test/validation/common/odp_cunit_common.c 
b/test/validation/common/odp_cunit_common.c
index a98042d..db9b107 100644
--- a/test/validation/common/odp_cunit_common.c
+++ b/test/validation/common/odp_cunit_common.c
@@ -280,6 +280,7 @@ int odp_cunit_run(void)
int ret;
 
printf("\tODP API version: %s\n", odp_version_api_str());
+   printf("\tODP implementation: %s\n", odp_version_impl_name());
printf("\tODP implementation version: %s\n", odp_version_impl_str());
 
CU_basic_set_mode(CU_BRM_VERBOSE);
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2 5/6] test: l2fwd: increase burst size

2015-10-30 Thread Petri Savolainen
Increased burst size to 32. This improves packet rate about
15% with netmap, since system call rate is halved.
No harm to any implementation, since implementation decides
how many packets are returned. This is comparable to DPDK l2fwd
burst size.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index d73c38b..5913496 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -43,7 +43,7 @@
 /** @def MAX_PKT_BURST
  * @brief Maximum number of packet in a burst
  */
-#define MAX_PKT_BURST  16
+#define MAX_PKT_BURST  32
 
 /**
  * Packet input mode
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2 6/6] test: l2fwd: separate rx and tx drop counters

2015-10-30 Thread Petri Savolainen
Separated receive and transmit drop counters to
help debugging the cause of dropped packets.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 5913496..f415ba3 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -81,8 +81,12 @@ static int exit_threads; /**< Break workers loop if set 
to 1 */
  */
 typedef union {
struct {
-   uint64_t packets;  /**< Number of forwarded packets. */
-   uint64_t drops;/**< Number of dropped packets. */
+   /** Number of forwarded packets */
+   uint64_t packets;
+   /** Packets dropped due to receive error */
+   uint64_t rx_drops;
+   /** Packets dropped due to transmit error */
+   uint64_t tx_drops;
} s;
 
uint8_t padding[ODP_CACHE_LINE_SIZE];
@@ -159,7 +163,6 @@ static void *pktio_queue_thread(void *arg)
while (!exit_threads) {
int sent, i;
unsigned tx_drops;
-   int rx_drops = 0;
 
pkts = odp_schedule_multi(NULL, wait, ev_tbl, MAX_PKT_BURST);
 
@@ -170,14 +173,16 @@ static void *pktio_queue_thread(void *arg)
pkt_tbl[i] = odp_packet_from_event(ev_tbl[i]);
 
if (gbl_args->appl.error_check) {
+   int rx_drops;
+
/* Drop packets with errors */
rx_drops = drop_err_pkts(pkt_tbl, pkts);
 
if (odp_unlikely(rx_drops)) {
-   if (pkts == rx_drops) {
-   stats->s.drops += rx_drops;
+   stats->s.rx_drops += rx_drops;
+   if (pkts == rx_drops)
continue;
-   }
+
pkts -= rx_drops;
}
}
@@ -193,12 +198,13 @@ static void *pktio_queue_thread(void *arg)
tx_drops = pkts - sent;
 
if (odp_unlikely(tx_drops)) {
+   stats->s.tx_drops += tx_drops;
+
/* Drop rejected packets */
for (i = sent; i < pkts; i++)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->s.drops   += rx_drops + tx_drops;
stats->s.packets += pkts;
}
 
@@ -282,21 +288,22 @@ static void *pktio_direct_recv_thread(void *arg)
while (!exit_threads) {
int sent, i;
unsigned tx_drops;
-   int rx_drops = 0;
 
pkts = odp_pktio_recv(pktio_src, pkt_tbl, MAX_PKT_BURST);
if (odp_unlikely(pkts <= 0))
continue;
 
if (gbl_args->appl.error_check) {
+   int rx_drops;
+
/* Drop packets with errors */
rx_drops = drop_err_pkts(pkt_tbl, pkts);
 
if (odp_unlikely(rx_drops)) {
-   if (pkts == rx_drops) {
-   stats->s.drops += rx_drops;
+   stats->s.rx_drops += rx_drops;
+   if (pkts == rx_drops)
continue;
-   }
+
pkts -= rx_drops;
}
}
@@ -309,12 +316,13 @@ static void *pktio_direct_recv_thread(void *arg)
tx_drops = pkts - sent;
 
if (odp_unlikely(tx_drops)) {
+   stats->s.tx_drops += tx_drops;
+
/* Drop rejected packets */
for (i = sent; i < pkts; i++)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->s.drops   += rx_drops + tx_drops;
stats->s.packets += pkts;
}
 
@@ -408,7 +416,7 @@ static int print_speed_stats(int num_workers, stats_t 
*thr_stats,
uint64_t pkts = 0;
uint64_t pkts_prev = 0;
uint64_t pps;
-   uint64_t drops;
+   uint64_t rx_drops, tx_drops;
uint64_t maximum_pps = 0;
int i;
int elapsed = 0;
@@ -424,13 +432,15 @@ static int print_speed_stats(int num_workers, stats_t 
*thr_stats,
 
do {
pkts = 0;
-   drops = 0;
+   rx_drops = 0;
+   tx_drops = 0;
 
sleep(timeout);
 
for (i = 0; i < num_workers; i++) {
pkts += thr_stats[i].s.packets;
-   

[lng-odp] [PATCH v2 0/6] l2fwd optimizations

2015-10-30 Thread Petri Savolainen
v2:
  * corrected funtionality bug in v1. Queue mode used per
thread (fixed) destination pktio.
  * moved pktio start after worker thread create


Petri Savolainen (6):
  test: l2fwd: added option to disable error check
  test: l2fwd: start pktios after worker thread create
  test: l2fwd: optimize queue mode
  test: l2fwd: optimize statistics usage
  test: l2fwd: increase burst size
  test: l2fwd: separate rx and tx drop counters

 test/performance/odp_l2fwd.c | 233 ++-
 1 file changed, 142 insertions(+), 91 deletions(-)

-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2 2/6] test: l2fwd: start pktios after worker thread create

2015-10-30 Thread Petri Savolainen
More controlled startup sequence:
* Create and configure pktios
* Create and start workers
* Enable packet rx and tx

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 69b67a0..5830a02 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -541,15 +541,8 @@ int main(int argc, char *argv[])
 
/* Save interface destination port */
gbl_args->dst_port[i] = find_dest_port(i);
-
-   ret = odp_pktio_start(pktio);
-   if (ret) {
-   LOG_ERR("Error: unable to start %s\n",
-   gbl_args->appl.if_names[i]);
-   exit(EXIT_FAILURE);
-   }
-
}
+
gbl_args->pktios[i] = ODP_PKTIO_INVALID;
 
memset(thread_tbl, 0, sizeof(thread_tbl));
@@ -580,6 +573,17 @@ int main(int argc, char *argv[])
cpu = odp_cpumask_next(, cpu);
}
 
+   /* Start packet receive and transmit */
+   for (i = 0; i < gbl_args->appl.if_count; ++i) {
+   pktio = gbl_args->pktios[i];
+   ret   = odp_pktio_start(pktio);
+   if (ret) {
+   LOG_ERR("Error: unable to start %s\n",
+   gbl_args->appl.if_names[i]);
+   exit(EXIT_FAILURE);
+   }
+   }
+
ret = print_speed_stats(num_workers, stats, gbl_args->appl.time,
gbl_args->appl.accuracy);
free(stats);
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2 3/6] test: l2fwd: optimize queue mode

2015-10-30 Thread Petri Savolainen
Queue mode works the same way as direct mode, but uses
odp_schedule_multi for packet input. This improves packet
rate about 40% (with netmap). Only scheduler overhead is now
added which makes it easy to compare direct vs. scheduler inputs
options.

Output through queues or TM can be added as a third mode later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 64 ++--
 1 file changed, 38 insertions(+), 26 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 5830a02..69dd96b 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -106,8 +106,6 @@ typedef struct {
odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ethernet addresses */
odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
-   /** Table of port default output queues */
-   odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ports */
int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
@@ -134,12 +132,14 @@ static void usage(char *progname);
  */
 static void *pktio_queue_thread(void *arg)
 {
-   int thr, dst_port;
-   odp_queue_t outq_def;
-   odp_packet_t pkt;
-   odp_event_t ev;
+   odp_event_t  ev_tbl[MAX_PKT_BURST];
+   odp_packet_t pkt_tbl[MAX_PKT_BURST];
+   int pkts;
+   int thr;
thread_args_t *thr_args = arg;
uint64_t wait;
+   int dst_idx;
+   odp_pktio_t pktio_dst;
 
stats_t *stats = calloc(1, sizeof(stats_t));
*thr_args->stats = stats;
@@ -153,33 +153,49 @@ static void *pktio_queue_thread(void *arg)
 
/* Loop packets */
while (!exit_threads) {
-   /* Use schedule to get buf from any input queue */
-   ev  = odp_schedule(NULL, wait);
-   if (ev == ODP_EVENT_INVALID)
+   int sent, i;
+   unsigned tx_drops;
+   int rx_drops = 0;
+
+   pkts = odp_schedule_multi(NULL, wait, ev_tbl, MAX_PKT_BURST);
+
+   if (pkts <= 0)
continue;
-   pkt = odp_packet_from_event(ev);
+
+   for (i = 0; i < pkts; i++)
+   pkt_tbl[i] = odp_packet_from_event(ev_tbl[i]);
 
if (gbl_args->appl.error_check) {
/* Drop packets with errors */
-   if (odp_unlikely(drop_err_pkts(, 1))) {
-   stats->drops += 1;
-   continue;
+   rx_drops = drop_err_pkts(pkt_tbl, pkts);
+
+   if (odp_unlikely(rx_drops)) {
+   if (pkts == rx_drops) {
+   stats->drops += rx_drops;
+   continue;
+   }
+   pkts -= rx_drops;
}
}
 
-   dst_port = lookup_dest_port(pkt);
+   /* packets from the same queue are from the same interface */
+   dst_idx = lookup_dest_port(pkt_tbl[0]);
+   fill_eth_addrs(pkt_tbl, pkts, dst_idx);
+   pktio_dst = gbl_args->pktios[dst_idx];
 
-   fill_eth_addrs(, 1, dst_port);
+   sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
-   /* Enqueue the packet for output */
-   outq_def = gbl_args->outq_def[dst_port];
-   if (odp_queue_enq(outq_def, ev)) {
-   printf("  [%i] Queue enqueue failed.\n", thr);
-   odp_packet_free(pkt);
-   continue;
+   sent = odp_unlikely(sent < 0) ? 0 : sent;
+   tx_drops = pkts - sent;
+
+   if (odp_unlikely(tx_drops)) {
+   /* Drop rejected packets */
+   for (i = sent; i < pkts; i++)
+   odp_packet_free(pkt_tbl[i]);
}
 
-   stats->packets += 1;
+   stats->drops   += rx_drops + tx_drops;
+   stats->packets += pkts;
}
 
free(stats);
@@ -526,10 +542,6 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
 
-   /* Save interface default output queue */
-   if (gbl_args->appl.mode != DIRECT_RECV)
-   gbl_args->outq_def[i] = odp_pktio_outq_getdef(pktio);
-
/* Save destination eth address */
if (gbl_args->appl.dst_change) {
/* 02:00:00:00:00:XX */
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH 3/5] test: l2fwd: optimize statistics usage

2015-10-29 Thread Petri Savolainen
Allocate cacheline aligned shared memory for per thread
statistics and simplify stats pointer references.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 63 
 1 file changed, 34 insertions(+), 29 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index a7f1ff6..e4def80 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -79,23 +79,29 @@ static int exit_threads;/**< Break workers loop if set 
to 1 */
 /**
  * Statistics
  */
-typedef struct {
-   uint64_t packets;   /**< Number of forwarded packets. */
-   uint64_t drops; /**< Number of dropped packets. */
-} stats_t;
+typedef union {
+   struct {
+   uint64_t packets;  /**< Number of forwarded packets. */
+   uint64_t drops;/**< Number of dropped packets. */
+   } s;
+
+   uint8_t padding[ODP_CACHE_LINE_SIZE];
+} stats_t ODP_ALIGNED_CACHE;
 
 /**
  * Thread specific arguments
  */
 typedef struct {
-   int src_idx;/**< Source interface identifier */
-   stats_t **stats;/**< Per thread packet stats */
+   int src_idx;/**< Source interface identifier */
+   stats_t *stats; /**< Pointer to per thread stats */
 } thread_args_t;
 
 /**
  * Grouping of all global data
  */
 typedef struct {
+   /** Per thread packet stats */
+   stats_t stats[MAX_WORKERS];
/** Application (parsed) arguments */
appl_args_t appl;
/** Thread specific arguments */
@@ -136,20 +142,18 @@ static void *pktio_queue_thread(void *arg)
odp_packet_t pkt_tbl[MAX_PKT_BURST];
int pkts;
int thr;
-   thread_args_t *thr_args = arg;
uint64_t wait;
int src_idx, dst_idx;
odp_pktio_t pktio_dst;
+   thread_args_t *thr_args = arg;
+   stats_t *stats = thr_args->stats;
 
-   stats_t *stats = calloc(1, sizeof(stats_t));
-   *thr_args->stats = stats;
+   thr = odp_thread_id();
 
src_idx = thr_args->src_idx;
dst_idx = gbl_args->dst_port[src_idx];
pktio_dst = gbl_args->pktios[dst_idx];
 
-   thr = odp_thread_id();
-
printf("[%02i] QUEUE mode\n", thr);
odp_barrier_wait();
 
@@ -175,7 +179,7 @@ static void *pktio_queue_thread(void *arg)
 
if (odp_unlikely(rx_drops)) {
if (pkts == rx_drops) {
-   stats->drops += rx_drops;
+   stats->s.drops += rx_drops;
continue;
}
pkts -= rx_drops;
@@ -195,11 +199,13 @@ static void *pktio_queue_thread(void *arg)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->drops   += rx_drops + tx_drops;
-   stats->packets += pkts;
+   stats->s.drops   += rx_drops + tx_drops;
+   stats->s.packets += pkts;
}
 
-   free(stats);
+   /* Make sure that the last stats write is visible to readers */
+   odp_sync_stores();
+
return NULL;
 }
 
@@ -251,17 +257,14 @@ static inline int find_dest_port(int port)
 static void *pktio_direct_recv_thread(void *arg)
 {
int thr;
-   thread_args_t *thr_args;
int pkts;
odp_packet_t pkt_tbl[MAX_PKT_BURST];
int src_idx, dst_idx;
odp_pktio_t pktio_src, pktio_dst;
+   thread_args_t *thr_args = arg;
+   stats_t *stats = thr_args->stats;
 
thr = odp_thread_id();
-   thr_args = arg;
-
-   stats_t *stats = calloc(1, sizeof(stats_t));
-   *thr_args->stats = stats;
 
src_idx = thr_args->src_idx;
dst_idx = gbl_args->dst_port[src_idx];
@@ -292,7 +295,7 @@ static void *pktio_direct_recv_thread(void *arg)
 
if (odp_unlikely(rx_drops)) {
if (pkts == rx_drops) {
-   stats->drops += rx_drops;
+   stats->s.drops += rx_drops;
continue;
}
pkts -= rx_drops;
@@ -312,11 +315,13 @@ static void *pktio_direct_recv_thread(void *arg)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->drops   += rx_drops + tx_drops;
-   stats->packets += pkts;
+   stats->s.drops   += rx_drops + tx_drops;
+   stats->s.packets += pkts;
}
 
-   free(stats);
+   /* Make sure that the last stats write is visible to readers */
+   odp_sync_stores();
+
return NULL;
 }
 
@@ -398,7 +403,7 @@ static odp_pktio_t create_pktio(const ch

[lng-odp] [PATCH 2/5] test: l2fwd: optimize queue mode

2015-10-29 Thread Petri Savolainen
Queue mode works the same way as direct mode, but uses
odp_schedule_multi for packet input. This improves packet
rate about 40% (with netmap). Only scheduler overhead is now
added which makes it easy to compare direct vs. scheduler inputs
options.

Output through queues or TM can be added as a third mode later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 65 ++--
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 69b67a0..a7f1ff6 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -106,8 +106,6 @@ typedef struct {
odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ethernet addresses */
odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
-   /** Table of port default output queues */
-   odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
/** Table of dst ports */
int dst_port[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
@@ -134,16 +132,22 @@ static void usage(char *progname);
  */
 static void *pktio_queue_thread(void *arg)
 {
-   int thr, dst_port;
-   odp_queue_t outq_def;
-   odp_packet_t pkt;
-   odp_event_t ev;
+   odp_event_t  ev_tbl[MAX_PKT_BURST];
+   odp_packet_t pkt_tbl[MAX_PKT_BURST];
+   int pkts;
+   int thr;
thread_args_t *thr_args = arg;
uint64_t wait;
+   int src_idx, dst_idx;
+   odp_pktio_t pktio_dst;
 
stats_t *stats = calloc(1, sizeof(stats_t));
*thr_args->stats = stats;
 
+   src_idx = thr_args->src_idx;
+   dst_idx = gbl_args->dst_port[src_idx];
+   pktio_dst = gbl_args->pktios[dst_idx];
+
thr = odp_thread_id();
 
printf("[%02i] QUEUE mode\n", thr);
@@ -153,33 +157,46 @@ static void *pktio_queue_thread(void *arg)
 
/* Loop packets */
while (!exit_threads) {
-   /* Use schedule to get buf from any input queue */
-   ev  = odp_schedule(NULL, wait);
-   if (ev == ODP_EVENT_INVALID)
+   int sent, i;
+   unsigned tx_drops;
+   int rx_drops = 0;
+
+   pkts = odp_schedule_multi(NULL, wait, ev_tbl, MAX_PKT_BURST);
+
+   if (pkts <= 0)
continue;
-   pkt = odp_packet_from_event(ev);
+
+   for (i = 0; i < pkts; i++)
+   pkt_tbl[i] = odp_packet_from_event(ev_tbl[i]);
 
if (gbl_args->appl.error_check) {
/* Drop packets with errors */
-   if (odp_unlikely(drop_err_pkts(, 1))) {
-   stats->drops += 1;
-   continue;
+   rx_drops = drop_err_pkts(pkt_tbl, pkts);
+
+   if (odp_unlikely(rx_drops)) {
+   if (pkts == rx_drops) {
+   stats->drops += rx_drops;
+   continue;
+   }
+   pkts -= rx_drops;
}
}
 
-   dst_port = lookup_dest_port(pkt);
+   fill_eth_addrs(pkt_tbl, pkts, dst_idx);
 
-   fill_eth_addrs(, 1, dst_port);
+   sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
-   /* Enqueue the packet for output */
-   outq_def = gbl_args->outq_def[dst_port];
-   if (odp_queue_enq(outq_def, ev)) {
-   printf("  [%i] Queue enqueue failed.\n", thr);
-   odp_packet_free(pkt);
-   continue;
+   sent = odp_unlikely(sent < 0) ? 0 : sent;
+   tx_drops = pkts - sent;
+
+   if (odp_unlikely(tx_drops)) {
+   /* Drop rejected packets */
+   for (i = sent; i < pkts; i++)
+   odp_packet_free(pkt_tbl[i]);
}
 
-   stats->packets += 1;
+   stats->drops   += rx_drops + tx_drops;
+   stats->packets += pkts;
}
 
free(stats);
@@ -526,10 +543,6 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
 
-   /* Save interface default output queue */
-   if (gbl_args->appl.mode != DIRECT_RECV)
-   gbl_args->outq_def[i] = odp_pktio_outq_getdef(pktio);
-
/* Save destination eth address */
if (gbl_args->appl.dst_change) {
/* 02:00:00:00:00:XX */
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH 4/5] test: l2fwd: increase burst size

2015-10-29 Thread Petri Savolainen
Increased burst size to 32. This improves packet rate about
15% with netmap, since system call rate is halved.
No harm to any implementation, since implementation decides
how many packets are returned. This is comparable to DPDK l2fwd
burst size.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index e4def80..f733440 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -43,7 +43,7 @@
 /** @def MAX_PKT_BURST
  * @brief Maximum number of packet in a burst
  */
-#define MAX_PKT_BURST  16
+#define MAX_PKT_BURST  32
 
 /**
  * Packet input mode
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH 1/5] test: l2fwd: added option to disable error check

2015-10-29 Thread Petri Savolainen
Added command line option to disable packet error check. Error
check requires full packet parse. Max packet rate measurements
should be done with minimal feature set.

This change gives +10% packet rate increase in direct recv mode
with netmap.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 89 +++-
 1 file changed, 54 insertions(+), 35 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 0844f00..69b67a0 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -69,8 +69,9 @@ typedef struct {
int time;   /**< Time in seconds to run. */
int accuracy;   /**< Number of seconds to get and print 
statistics */
char *if_str;   /**< Storage for interface names */
-   int dst_change; /**< Change destination eth addresses > */
-   int src_change; /**< Change source eth addresses > */
+   int dst_change; /**< Change destination eth addresses */
+   int src_change; /**< Change source eth addresses */
+   int error_check;/**< Check packet errors */
 } appl_args_t;
 
 static int exit_threads;   /**< Break workers loop if set to 1 */
@@ -119,7 +120,7 @@ static odp_barrier_t barrier;
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
 static inline int find_dest_port(int port);
-static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
+static inline int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned num);
 static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
   int dst_port);
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
@@ -158,10 +159,12 @@ static void *pktio_queue_thread(void *arg)
continue;
pkt = odp_packet_from_event(ev);
 
-   /* Drop packets with errors */
-   if (odp_unlikely(drop_err_pkts(, 1) == 0)) {
-   stats->drops += 1;
-   continue;
+   if (gbl_args->appl.error_check) {
+   /* Drop packets with errors */
+   if (odp_unlikely(drop_err_pkts(, 1))) {
+   stats->drops += 1;
+   continue;
+   }
}
 
dst_port = lookup_dest_port(pkt);
@@ -232,7 +235,7 @@ static void *pktio_direct_recv_thread(void *arg)
 {
int thr;
thread_args_t *thr_args;
-   int pkts, pkts_ok;
+   int pkts;
odp_packet_t pkt_tbl[MAX_PKT_BURST];
int src_idx, dst_idx;
odp_pktio_t pktio_src, pktio_dst;
@@ -258,33 +261,42 @@ static void *pktio_direct_recv_thread(void *arg)
 
/* Loop packets */
while (!exit_threads) {
+   int sent, i;
+   unsigned tx_drops;
+   int rx_drops = 0;
+
pkts = odp_pktio_recv(pktio_src, pkt_tbl, MAX_PKT_BURST);
-   if (pkts <= 0)
+   if (odp_unlikely(pkts <= 0))
continue;
 
-   /* Drop packets with errors */
-   pkts_ok = drop_err_pkts(pkt_tbl, pkts);
-   if (pkts_ok > 0) {
-   fill_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
+   if (gbl_args->appl.error_check) {
+   /* Drop packets with errors */
+   rx_drops = drop_err_pkts(pkt_tbl, pkts);
 
-   int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok);
-
-   sent = sent > 0 ? sent : 0;
-   if (odp_unlikely(sent < pkts_ok)) {
-   stats->drops += pkts_ok - sent;
-   do
-   odp_packet_free(pkt_tbl[sent]);
-   while (++sent < pkts_ok);
+   if (odp_unlikely(rx_drops)) {
+   if (pkts == rx_drops) {
+   stats->drops += rx_drops;
+   continue;
+   }
+   pkts -= rx_drops;
}
}
 
-   if (odp_unlikely(pkts_ok != pkts))
-   stats->drops += pkts - pkts_ok;
+   fill_eth_addrs(pkt_tbl, pkts, dst_idx);
 
-   if (pkts_ok == 0)
-   continue;
+   sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts);
 
-   stats->packets += pkts_ok;
+   sent = odp_unlikely(sent < 0) ? 0 : sent;
+   tx_drops = pkts - sent;
+
+   if (odp_unlikely(tx_drops)) {
+   /* Drop rejected packets */
+   f

[lng-odp] [PATCH 5/5] test: l2fwd: separate rx and tx drop counters

2015-10-29 Thread Petri Savolainen
Separated receive and transmit drop counters to
help debugging the cause of dropped packets.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 test/performance/odp_l2fwd.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index f733440..617e1b2 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -81,8 +81,12 @@ static int exit_threads; /**< Break workers loop if set 
to 1 */
  */
 typedef union {
struct {
-   uint64_t packets;  /**< Number of forwarded packets. */
-   uint64_t drops;/**< Number of dropped packets. */
+   /** Number of forwarded packets */
+   uint64_t packets;
+   /** Packets dropped due to receive error */
+   uint64_t rx_drops;
+   /** Packets dropped due to transmit error */
+   uint64_t tx_drops;
} s;
 
uint8_t padding[ODP_CACHE_LINE_SIZE];
@@ -163,7 +167,6 @@ static void *pktio_queue_thread(void *arg)
while (!exit_threads) {
int sent, i;
unsigned tx_drops;
-   int rx_drops = 0;
 
pkts = odp_schedule_multi(NULL, wait, ev_tbl, MAX_PKT_BURST);
 
@@ -174,14 +177,16 @@ static void *pktio_queue_thread(void *arg)
pkt_tbl[i] = odp_packet_from_event(ev_tbl[i]);
 
if (gbl_args->appl.error_check) {
+   int rx_drops;
+
/* Drop packets with errors */
rx_drops = drop_err_pkts(pkt_tbl, pkts);
 
if (odp_unlikely(rx_drops)) {
-   if (pkts == rx_drops) {
-   stats->s.drops += rx_drops;
+   stats->s.rx_drops += rx_drops;
+   if (pkts == rx_drops)
continue;
-   }
+
pkts -= rx_drops;
}
}
@@ -194,12 +199,13 @@ static void *pktio_queue_thread(void *arg)
tx_drops = pkts - sent;
 
if (odp_unlikely(tx_drops)) {
+   stats->s.tx_drops += tx_drops;
+
/* Drop rejected packets */
for (i = sent; i < pkts; i++)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->s.drops   += rx_drops + tx_drops;
stats->s.packets += pkts;
}
 
@@ -283,21 +289,22 @@ static void *pktio_direct_recv_thread(void *arg)
while (!exit_threads) {
int sent, i;
unsigned tx_drops;
-   int rx_drops = 0;
 
pkts = odp_pktio_recv(pktio_src, pkt_tbl, MAX_PKT_BURST);
if (odp_unlikely(pkts <= 0))
continue;
 
if (gbl_args->appl.error_check) {
+   int rx_drops;
+
/* Drop packets with errors */
rx_drops = drop_err_pkts(pkt_tbl, pkts);
 
if (odp_unlikely(rx_drops)) {
-   if (pkts == rx_drops) {
-   stats->s.drops += rx_drops;
+   stats->s.rx_drops += rx_drops;
+   if (pkts == rx_drops)
continue;
-   }
+
pkts -= rx_drops;
}
}
@@ -310,12 +317,13 @@ static void *pktio_direct_recv_thread(void *arg)
tx_drops = pkts - sent;
 
if (odp_unlikely(tx_drops)) {
+   stats->s.tx_drops += tx_drops;
+
/* Drop rejected packets */
for (i = sent; i < pkts; i++)
odp_packet_free(pkt_tbl[i]);
}
 
-   stats->s.drops   += rx_drops + tx_drops;
stats->s.packets += pkts;
}
 
@@ -409,7 +417,7 @@ static int print_speed_stats(int num_workers, stats_t 
*thr_stats,
uint64_t pkts = 0;
uint64_t pkts_prev = 0;
uint64_t pps;
-   uint64_t drops;
+   uint64_t rx_drops, tx_drops;
uint64_t maximum_pps = 0;
int i;
int elapsed = 0;
@@ -425,13 +433,15 @@ static int print_speed_stats(int num_workers, stats_t 
*thr_stats,
 
do {
pkts = 0;
-   drops = 0;
+   rx_drops = 0;
+   tx_drops = 0;
 
sleep(timeout);
 
for (i = 0; i < num_workers; i++) {
pkts += thr_stats[i].s.packets;
-   

[lng-odp] [API-NEXT PATCH] validation: std_clib: added validation tests

2015-10-29 Thread Petri Savolainen
Added validation tests for ODP std C library API.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 configure.ac |  1 +
 platform/linux-generic/test/Makefile.am  |  1 +
 test/validation/Makefile.am  |  1 +
 test/validation/std_clib/.gitignore  |  1 +
 test/validation/std_clib/Makefile.am | 10 +
 test/validation/std_clib/std_clib.c  | 66 
 test/validation/std_clib/std_clib.h  | 21 ++
 test/validation/std_clib/std_clib_main.c | 12 ++
 8 files changed, 113 insertions(+)
 create mode 100644 test/validation/std_clib/.gitignore
 create mode 100644 test/validation/std_clib/Makefile.am
 create mode 100644 test/validation/std_clib/std_clib.c
 create mode 100644 test/validation/std_clib/std_clib.h
 create mode 100644 test/validation/std_clib/std_clib_main.c

diff --git a/configure.ac b/configure.ac
index 8e94d82..9887589 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,6 +326,7 @@ AC_CONFIG_FILES([Makefile
 test/validation/queue/Makefile
 test/validation/random/Makefile
 test/validation/scheduler/Makefile
+test/validation/std_clib/Makefile
 test/validation/synchronizers/Makefile
 test/validation/thread/Makefile
 test/validation/time/Makefile
diff --git a/platform/linux-generic/test/Makefile.am 
b/platform/linux-generic/test/Makefile.am
index a657de9..24285c1 100644
--- a/platform/linux-generic/test/Makefile.am
+++ b/platform/linux-generic/test/Makefile.am
@@ -19,6 +19,7 @@ TESTS = pktio/pktio_run \
${top_builddir}/test/validation/queue/queue_main$(EXEEXT) \
${top_builddir}/test/validation/random/random_main$(EXEEXT) \
${top_builddir}/test/validation/scheduler/scheduler_main$(EXEEXT) \
+   ${top_builddir}/test/validation/std_clib/std_clib_main$(EXEEXT) \

${top_builddir}/test/validation/synchronizers/synchronizers_main$(EXEEXT) \
${top_builddir}/test/validation/thread/thread_main$(EXEEXT) \
${top_builddir}/test/validation/time/time_main$(EXEEXT) \
diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am
index 4f926ce..1711b93 100644
--- a/test/validation/Makefile.am
+++ b/test/validation/Makefile.am
@@ -12,6 +12,7 @@ ODP_MODULES = buffer \
  pool \
  random \
  scheduler \
+ std_clib \
  synchronizers \
  thread \
  time \
diff --git a/test/validation/std_clib/.gitignore 
b/test/validation/std_clib/.gitignore
new file mode 100644
index 000..3782833
--- /dev/null
+++ b/test/validation/std_clib/.gitignore
@@ -0,0 +1 @@
+std_clib_main
diff --git a/test/validation/std_clib/Makefile.am 
b/test/validation/std_clib/Makefile.am
new file mode 100644
index 000..aa02be6
--- /dev/null
+++ b/test/validation/std_clib/Makefile.am
@@ -0,0 +1,10 @@
+include ../Makefile.inc
+
+noinst_LTLIBRARIES = libteststd_clib.la
+libteststd_clib_la_SOURCES = std_clib.c
+
+bin_PROGRAMS = std_clib_main$(EXEEXT)
+dist_std_clib_main_SOURCES = std_clib_main.c
+std_clib_main_LDADD = libteststd_clib.la $(LIBCUNIT_COMMON) $(LIBODP)
+
+EXTRA_DIST = std_clib.h
diff --git a/test/validation/std_clib/std_clib.c 
b/test/validation/std_clib/std_clib.c
new file mode 100644
index 000..e53ad39
--- /dev/null
+++ b/test/validation/std_clib/std_clib.c
@@ -0,0 +1,66 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include 
+#include 
+#include "std_clib.h"
+
+#include 
+
+#define PATTERN 0x5e
+
+static void std_clib_test_memcpy(void)
+{
+   uint8_t src[] = {0, 1,  2,  3,  4,  5,  6,  7,
+8, 9, 10, 11, 12, 13, 14, 15};
+   uint8_t dst[16];
+   int ret;
+
+   memset(dst, 0, sizeof(dst));
+
+   odp_memcpy(dst, src, sizeof(dst));
+
+   ret = memcmp(dst, src, sizeof(dst));
+
+   CU_ASSERT(ret == 0);
+}
+
+static void std_clib_test_memset(void)
+{
+   uint8_t data[] = {0, 1,  2,  3,  4,  5,  6,  7,
+ 8, 9, 10, 11, 12, 13, 14, 15};
+   uint8_t ref[16];
+   int ret;
+
+   odp_memset(data, PATTERN, sizeof(data));
+
+   memset(ref, PATTERN, sizeof(ref));
+
+   ret = memcmp(data, ref, sizeof(data));
+
+   CU_ASSERT(ret == 0);
+}
+
+odp_testinfo_t std_clib_suite[] = {
+   ODP_TEST_INFO(std_clib_test_memcpy),
+   ODP_TEST_INFO(std_clib_test_memset),
+   ODP_TEST_INFO_NULL,
+};
+
+odp_suiteinfo_t std_clib_suites[] = {
+   {"Std C library", NULL, NULL, std_clib_suite},
+   ODP_SUITE_INFO_NULL
+};
+
+int std_clib_main(void)
+{
+   int ret = odp_cunit_register(std_clib_suites);
+
+   if (ret == 0)
+   ret = odp_cunit_run();
+
+   return ret;
+}
diff --git a/test/validation/std_clib/std_clib.h 
b/test/validation/std_clib/std_clib.h
new file

[lng-odp] [API-NEXT PATCH] api: atomic: added atomic_is_lock_free

2015-10-27 Thread Petri Savolainen
Platforms may support some uint64 operations lock-free and
others not. For example, inc_64 can be natively supported but
cas_64 (or max_64/min_64) not. User may be able to switch to
32 bit variables when a 64 bit operation uses locks. The same
atomic operation enum could be used for platform init to guide
lock vs. lock-free implementation (e.g. if cas_64 is never
called, inc_64 can be lock-free).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 51 +
 platform/linux-generic/include/odp/atomic.h | 28 
 2 files changed, 79 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 316f13a..1613405 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -388,6 +388,57 @@ void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
+ * @enum odp_atomic_operation_t
+ * Atomic operations
+ *
+ * @var ODP_ATOMIC_OP_ALL
+ * All atomic operations
+ * @var ODP_ATOMIC_OP_INIT
+ * Atomic init
+ * @var ODP_ATOMIC_OP_LOAD
+ * Atomic load
+ * @var ODP_ATOMIC_OP_STORE
+ * Atomic store
+ * @var ODP_ATOMIC_OP_FETCH_ADD
+ * Atomic fetch add
+ * @var ODP_ATOMIC_OP_ADD
+ * Atomic add
+ * @var ODP_ATOMIC_OP_FETCH_SUB
+ * Atomic fetch sub
+ * @var ODP_ATOMIC_OP_SUB
+ * Atomic sub
+ * @var ODP_ATOMIC_OP_FETCH_INC
+ * Atomic fetch inc
+ * @var ODP_ATOMIC_OP_INC
+ * Atomic inc
+ * @var ODP_ATOMIC_OP_FETCH_DEC
+ * Atomic fetch dec
+ * @var ODP_ATOMIC_OP_DEC
+ * Atomic dec
+ * @var ODP_ATOMIC_OP_MIN
+ * Atomic min
+ * @var ODP_ATOMIC_OP_MAX
+ * Atomic max
+ * @var ODP_ATOMIC_OP_CAS
+ * Atomic compare and swap
+ */
+
+/**
+ * Determine if an atomic uint64 operation is lock-free
+ *
+ * Lock-free implementations have higher performance and scale better than
+ * implementations using locks. User can decide to use e.g. uint32 atomic
+ * variables instead of uint64 to optimize performance on platforms that
+ * implement a performance critical operation using locks.
+ *
+ * @param op  Atomic operation
+ *
+ * @retval 0  Operation is implemented with locks
+ * @retval 1  Operation is lock-free
+ */
+int odp_atomic_is_lock_free_u64(odp_atomic_operation_t op);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 005a0cd..481d13a 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -25,6 +25,34 @@ extern "C" {
  *  @{
  */
 
+typedef enum odp_atomic_operation_t {
+   ODP_ATOMIC_OP_ALL = 0,
+   ODP_ATOMIC_OP_INIT,
+   ODP_ATOMIC_OP_LOAD,
+   ODP_ATOMIC_OP_STORE,
+   ODP_ATOMIC_OP_FETCH_ADD,
+   ODP_ATOMIC_OP_ADD,
+   ODP_ATOMIC_OP_FETCH_SUB,
+   ODP_ATOMIC_OP_SUB,
+   ODP_ATOMIC_OP_FETCH_INC,
+   ODP_ATOMIC_OP_INC,
+   ODP_ATOMIC_OP_FETCH_DEC,
+   ODP_ATOMIC_OP_DEC,
+   ODP_ATOMIC_OP_MIN,
+   ODP_ATOMIC_OP_MAX,
+   ODP_ATOMIC_OP_CAS
+} odp_atomic_operation_t;
+
+static inline int odp_atomic_is_lock_free_u64(odp_atomic_operation_t op)
+{
+   (void)op;
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   return 0;
+#else
+   return 1;
+#endif
+}
+
 static inline void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
 {
__atomic_store_n(>v, val, __ATOMIC_RELAXED);
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 6/7] api: atomic: added atomic min and max

2015-10-23 Thread Petri Savolainen
Added atomic min and max operations. These can be used e.g.
to maintain high and low water marks of an another atomic counter.
These use relaxed memory order.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 44 ++
 platform/linux-generic/include/odp/atomic.h | 48 +
 2 files changed, 92 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 957d304..b79a50a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,28 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Update maximum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max);
+
+/**
+ * Update minimum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min);
+
+/**
  * Compare and swap atomic uint32 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
@@ -248,6 +270,28 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Update maximum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max);
+
+/**
+ * Update minimum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min);
+
+/**
  * Compare and swap atomic uint64 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 5b13e02..b2bc5c4 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -94,6 +94,30 @@ static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, 
uint32_t *old_val,
   __ATOMIC_RELAXED);
 }
 
+static inline void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_min))
+   break;
+   }
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -210,6 +234,30 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t 
*atom, uint64_t *old_val,
 #endif
 }
 
+static inline void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_min))
+   break;
+   }
+}
+
 /**
  * @}
  */
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 7/7] api: atomic: added 32 bit acquire and release

2015-10-23 Thread Petri Savolainen
Added 32 bit acquire load/cas and release store/add/sub calls.
These are the minimum set of non-relaxed calls that are needed
for building lock-free algorithms. 64 bit versions can be added
later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 80 -
 platform/linux-generic/include/odp/atomic.h | 32 
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index b79a50a..316f13a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -21,7 +21,7 @@ extern "C" {
 /**
  * @defgroup odp_atomic ODP ATOMIC
  * @details
- *  Atomic integers 
+ *  Atomic integers using relaxed memory ordering 
  *
  * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
  * implement e.g. shared counters. If not otherwise documented, operations in
@@ -31,6 +31,18 @@ extern "C" {
  * before or after the operation), only atomicity of the operation itself is
  * guaranteed.
  *
+ *  Operations with other than relaxed memory ordering 
+ *
+ *  An operation with RELEASE  memory ordering 
(odp_atomic_xxx_rls_xxx())
+ * ensures that other threads loading the same atomic variable with ACQUIRE
+ * memory ordering see all stores (from the calling thread) that happened 
before
+ * this releasing store.
+ *
+ *  An operation with ACQUIRE  memory ordering 
(odp_atomic_xxx_acq_xxx())
+ * ensures that the calling thread sees all stores (done by the releasing
+ * thread) that happened before a RELEASE memory ordered store to the same
+ * atomic variable.
+ *
  * @{
  */
 
@@ -309,6 +321,72 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t 
new_min);
 int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
   uint64_t new_val);
 
+/*
+ * Operations with other than relaxed memory ordering
+ * --
+ */
+
+/**
+ * Load value of atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ *
+ * @return Value of the variable
+ */
+uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
+
+/**
+ * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
+ * Store value to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
+ */
+void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Add to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
+ */
+void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Subtract from atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
+ */
+void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index b2bc5c4..005a0cd 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -258,6 +258,38 @@ static inline void odp_atomic_min_u64(odp_atomic_u64_t 
*atom, uint64_t new_min)
}
 }
 
+static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
+{
+   return __atomic_load_n(>v, __ATOMIC_ACQUIRE);
+}
+
+static inline int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom,
+uint32_t *old_val, uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_ACQUIRE,
+  __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom,
+   

[lng-odp] [API-NEXT PATCH v3 4/7] api: atomic: clean atomic API documentation

2015-10-23 Thread Petri Savolainen
Refined and centralized comment about relaxed memory ordering.
Removed in/out doxygen tags since 'atom' pointer to an object
that application must not directly access (only through the API).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h | 112 ---
 1 file changed, 48 insertions(+), 64 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 8aacc9d..97e8639 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,10 +18,20 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_atomic ODP ATOMIC
- *  Atomic types and relaxed operations. These operations cannot be used for
- *  synchronization.
- *  @{
+/**
+ * @defgroup odp_atomic ODP ATOMIC
+ * @details
+ *  Atomic integers 
+ *
+ * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
+ * implement e.g. shared counters. If not otherwise documented, operations in
+ * this API are implemented using  RELAXED memory ordering  (see memory
+ * order descriptions in the C11 specification). Relaxed operations do not
+ * provide synchronization or ordering for other memory accesses (initiated
+ * before or after the operation), only atomicity of the operation itself is
+ * guaranteed.
+ *
+ * @{
  */
 
 /**
@@ -34,19 +44,16 @@ extern "C" {
 
 /**
  * Initialize atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to initialize the variable with
+ * @param atomPointer to atomic variable
+ * @param val Value to initialize the variable with
  */
 void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val);
 
-
 /**
  * Load value of atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable
  */
@@ -54,19 +61,17 @@ uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom);
 
 /**
  * Store value to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to store in the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
  */
 void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  *
  * @return Value of the variable before the addition
  */
@@ -74,19 +79,17 @@ uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  */
 void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be subracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subracted from the variable
  *
  * @return Value of the variable before the subtraction
  */
@@ -94,37 +97,32 @@ uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be subtracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
  */
 void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable before the increment
  */
-
 uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  */
 void odp_atomic_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Fetch and decrement atomic uint32 variabl

[lng-odp] [API-NEXT PATCH v3 1/7] api: doc: remove broken doxygen reference

2015-10-23 Thread Petri Savolainen
Reference caused warning when creating doxygen documentation.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 2 +-
 platform/linux-generic/include/odp/debug.h | 8 
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..c17f8fa 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -30,7 +30,7 @@ extern "C" {
  * odp_pktio_send().
  * Diagnostic messages can be enhanced by using odp_pktio_to_u64 which
  * will generate a printable reference for a pktio handle for use with
- * the logging @ref odp_ver_abt_log_dbg.
+ * the logging.
  *  @{
  */
 
diff --git a/platform/linux-generic/include/odp/debug.h 
b/platform/linux-generic/include/odp/debug.h
index 987ced2..a2e59bf 100644
--- a/platform/linux-generic/include/odp/debug.h
+++ b/platform/linux-generic/include/odp/debug.h
@@ -17,14 +17,6 @@
 extern "C" {
 #endif
 
-/** @ingroup odp_ver_abt_log_dbg
- *  @{
- */
-
-/**
- * @}
- */
-
 #include 
 
 #ifdef __cplusplus
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 3/7] api: doc: re-organize doxygen doc for synchronizer

2015-10-23 Thread Petri Savolainen
Removed module synchronizer from doxygen documentation and
introduced new modules for locks, atomics and barriers. Removed
unnecessary group tagging from internal headers, which are not
visible to doxygen anyway.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h  |  2 +-
 include/odp/api/barrier.h |  4 ++--
 include/odp/api/rwlock.h  | 19 +++
 include/odp/api/rwlock_recursive.h| 17 ++---
 include/odp/api/spinlock.h| 11 ---
 include/odp/api/spinlock_recursive.h  | 15 +--
 include/odp/api/sync.h|  2 +-
 include/odp/api/ticketlock.h  | 16 ++--
 platform/linux-generic/include/odp/atomic.h   |  2 +-
 platform/linux-generic/include/odp/barrier.h  |  8 
 .../linux-generic/include/odp/plat/atomic_types.h |  8 
 .../linux-generic/include/odp/plat/barrier_types.h|  8 
 .../include/odp/plat/rwlock_recursive_types.h | 13 +
 .../linux-generic/include/odp/plat/rwlock_types.h | 13 +
 .../include/odp/plat/spinlock_recursive_types.h   | 13 +
 .../linux-generic/include/odp/plat/spinlock_types.h   | 14 +-
 .../linux-generic/include/odp/plat/ticketlock_types.h | 13 +
 platform/linux-generic/include/odp/rwlock.h   |  8 
 platform/linux-generic/include/odp/spinlock.h |  8 
 platform/linux-generic/include/odp/sync.h |  8 
 platform/linux-generic/include/odp/ticketlock.h   |  9 -
 platform/linux-generic/include/odp_atomic_internal.h  |  9 -
 22 files changed, 58 insertions(+), 162 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index ba5c354..8aacc9d 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
+/** @defgroup odp_atomic ODP ATOMIC
  *  Atomic types and relaxed operations. These operations cannot be used for
  *  synchronization.
  *  @{
diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h
index 28310ba..8ca2647 100644
--- a/include/odp/api/barrier.h
+++ b/include/odp/api/barrier.h
@@ -18,8 +18,8 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Synchronize threads.
+/** @defgroup odp_barrier ODP BARRIER
+ *  Thread excution and memory ordering barriers.
  *  @{
  */
 
diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h
index d730a70..54f426f 100644
--- a/include/odp/api/rwlock.h
+++ b/include/odp/api/rwlock.h
@@ -17,18 +17,21 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_synchronizers ODP SYNCRONIZERS
- *  Operations on reader/writer locks.
- *  A reader/writer lock allows multiple simultaneous readers but only one
- *  writer at a time.
- *  A thread that wants write access will have to wait until there are no
- *  threads that want read access. This casues a risk for starvation.
- *  @{
+/**
+ * @defgroup odp_locks ODP LOCKS
+ * @details
+ *  Reader / writer lock (odp_rwlock_t) 
+ *
+ * A reader/writer lock allows multiple simultaneous readers but only one
+ * writer at a time. A thread that wants write access will have to wait until
+ * there are no threads that want read access. This casues a risk for
+ * starvation.
+ * @{
  */
 
 /**
  * @typedef odp_rwlock_t
- * ODP rwlock
+ * ODP reader/writer lock
  */
 
 
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
index 4c7556a..10b2f79 100644
--- a/include/odp/api/rwlock_recursive.h
+++ b/include/odp/api/rwlock_recursive.h
@@ -17,15 +17,12 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on recursive rwlocks.
- *  @{
- */
-
 /**
- * @typedef odp_rwlock_recursive_t
- * Recursive rwlock
+ * @addtogroup odp_locks
+ * @details
+ *  Recursive reader/writer lock (odp_rwlock_recursive_t) 
  *
+ * This is recursive version of the reader/writer lock.
  * A thread can read- or write-acquire a recursive read-write lock multiple
  * times without a deadlock. To release the lock, the thread must unlock it
  * the same number of times. Recursion is supported only for a pure series of
@@ -38,6 +35,12 @@ extern "C" {
  *
  * ... but this is not supported.
  *   * read_lock(); write_lock(); write_unlock(); read_unlock();
+ * @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
  */
 
 /**
diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h
index 9a5a929..154d025 100644
--- a/include/odp/api/spinlock.h
+++ b/include/odp/api/spinlock.h
@@ -18,9 +18,14 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on spin locks.
- *  @{
+/**
+ *

[lng-odp] [API-NEXT PATCH v3 2/7] doc: add doxygen layout file to control group page output

2015-10-23 Thread Petri Savolainen
Group level documentation can be used for API level general
description. Layout file is needed to place detailed group
description on the top of a page. By default doxygen shows
only the brief description on top (the first sentence).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 doc/doxygen.cfg   |   1 +
 doc/doxygenlayout.xml | 193 ++
 2 files changed, 194 insertions(+)
 create mode 100644 doc/doxygenlayout.xml

diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg
index f28ec24..909f0ce 100644
--- a/doc/doxygen.cfg
+++ b/doc/doxygen.cfg
@@ -33,6 +33,7 @@ EXAMPLE_PATTERNS = *.c
 EXAMPLE_RECURSIVE = YES
 IMAGE_PATH = $(SRCDIR)/doc/images
 HTML_EXTRA_STYLESHEET = $(SRCDIR)/doc/odpdoxygen.css
+LAYOUT_FILE = $(SRCDIR)/doc/doxygenlayout.xml
 ENABLE_PREPROCESSING = YES
 MACRO_EXPANSION = YES
 EXPAND_ONLY_PREDEF = YES
diff --git a/doc/doxygenlayout.xml b/doc/doxygenlayout.xml
new file mode 100644
index 000..90e189a
--- /dev/null
+++ b/doc/doxygenlayout.xml
@@ -0,0 +1,193 @@
+
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 5/7] api: atomic: added cas operations

2015-10-23 Thread Petri Savolainen
Added cas operations for 32 and 64 bit atomic variables. These
use relaxed memory order (as all other operations).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h   | 37 ++
 platform/linux-generic/include/odp/atomic.h| 24 ++
 .../linux-generic/include/odp/plat/atomic_types.h  | 21 ++--
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 97e8639..957d304 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,25 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Compare and swap atomic uint32 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ *
+ */
+int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
  * Initialize atomic uint64 variable
  *
  * @param atomPointer to atomic variable
@@ -229,6 +248,24 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Compare and swap atomic uint64 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+  uint64_t new_val);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index deb4039..5b13e02 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -85,6 +85,15 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
(void)__atomic_fetch_sub(>v, 1, __ATOMIC_RELAXED);
 }
 
+static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -186,6 +195,21 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t 
*atom)
 #endif
 }
 
+static inline int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   int ret;
+   *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(, *old_val, new_val));
+   return ret;
+#else
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+#endif
+}
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/plat/atomic_types.h 
b/platform/linux-generic/include/odp/plat/atomic_types.h
index 0f6c353..ea8fc2a 100644
--- a/platform/linux-generic/include/odp/plat/atomic_types.h
+++ b/platform/linux-generic/include/odp/plat/atomic_types.h
@@ -42,6 +42,21 @@ struct odp_atomic_u32_s {
 } ODP_ALIGNED(sizeof(uint32_t)); /* Enforce alignement! */;
 
 #if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+
+/**
+ * @internal
+ * CAS operation expression for the ATOMIC_OP macro
+ */
+#define ATOMIC_CAS_OP(ret_ptr, old_val, new_val) \
+({ \
+   if (atom->v == (old_val)) { \
+   atom->v = (new_val); \
+   *(ret_ptr) = 1; \
+   } else { \
+   *(ret_ptr) = 0; \
+   } \
+})
+
 /**
  * @internal
  * Helper macro for lock-based atomic operations on 64-bit integers
@@ -51,14 +66

[lng-odp] [API-NEXT PATCH v2] api: pktio: improve pktio_start and stop documentation

2015-10-22 Thread Petri Savolainen
Improved documentation of open, start, stop and close calls.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---

v2
  * fix typo
  * modify wordings
  * add spec for pktio_close

 include/odp/api/packet_io.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..915276b 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -103,6 +103,11 @@ typedef struct odp_pktio_param_t {
  * errno set. Use odp_pktio_lookup() to obtain a handle to an already open
  * device. Packet IO parameters provide interface level configuration options.
  *
+ * This call does not activate packet receive and transmit on the interface.
+ * The interface is activated with a call to odp_pktio_start(). If not
+ * specified otherwise, any interface level configuration must not be changed
+ * when the interface is active (between start and stop calls).
+ *
  * @param devPacket IO device name
  * @param pool   Default pool from which to allocate storage for packets
  *   received over this interface, must be of type ODP_POOL_PACKET
@@ -121,6 +126,8 @@ typedef struct odp_pktio_param_t {
  *  assigned the packet to a specific CoS. The default pool specified
  *  here is applicable only for those packets that are not assigned to a
  *  more specific CoS.
+ *
+ * @see odp_pktio_start(), odp_pktio_stop(), odp_pktio_close()
  */
 odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool,
   const odp_pktio_param_t *param);
@@ -128,30 +135,51 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t 
pool,
 /**
  * Start packet receive and transmit
  *
+ * Activate packet receive and transmit on a previously opened or stopped
+ * interface. The interface can be stopped with a call to odp_pktio_stop().
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_open(), odp_pktio_stop()
  */
 int odp_pktio_start(odp_pktio_t pktio);
 
 /**
  * Stop packet receive and transmit
  *
+ * Stop packet receive and transmit on a previously started interface. New
+ * packets are not received from or transmitted to the network. Packets already
+ * received from the network may be still available from interface and
+ * application can receive those normally. New packets may not be accepted for
+ * transmit. Packets already stored for transmit are not freed. A following
+ * odp_packet_start() call restarts packet receive and transmit.
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_start(), odp_pktio_close()
  */
 int odp_pktio_stop(odp_pktio_t pktio);
 
 /**
  * Close a packet IO interface
  *
+ * Close a stopped packet IO interface. This call frees all remaining packets
+ * stored in pktio receive and transmit side buffers. The pktio is destroyed
+ * and the handle must not be used for other calls. After a successful call,
+ * the same pktio device can be opened again with a odp_packet_open() call.
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
  * @retval <0 on failure
+ *
+ * @see odp_pktio_stop(), odp_pktio_open()
  */
 int odp_pktio_close(odp_pktio_t pktio);
 
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 4/7] api: atomic: clean atomic API documentation

2015-10-22 Thread Petri Savolainen
Refined and centralized comment about relaxed memory ordering.
Removed in/out doxygen tags since 'atom' pointer to an object
that application must not directly access (only through the API).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h | 112 ---
 1 file changed, 48 insertions(+), 64 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 8aacc9d..97e8639 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,10 +18,20 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_atomic ODP ATOMIC
- *  Atomic types and relaxed operations. These operations cannot be used for
- *  synchronization.
- *  @{
+/**
+ * @defgroup odp_atomic ODP ATOMIC
+ * @details
+ *  Atomic integers 
+ *
+ * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
+ * implement e.g. shared counters. If not otherwise documented, operations in
+ * this API are implemented using  RELAXED memory ordering  (see memory
+ * order descriptions in the C11 specification). Relaxed operations do not
+ * provide synchronization or ordering for other memory accesses (initiated
+ * before or after the operation), only atomicity of the operation itself is
+ * guaranteed.
+ *
+ * @{
  */
 
 /**
@@ -34,19 +44,16 @@ extern "C" {
 
 /**
  * Initialize atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to initialize the variable with
+ * @param atomPointer to atomic variable
+ * @param val Value to initialize the variable with
  */
 void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val);
 
-
 /**
  * Load value of atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable
  */
@@ -54,19 +61,17 @@ uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom);
 
 /**
  * Store value to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to store in the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
  */
 void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  *
  * @return Value of the variable before the addition
  */
@@ -74,19 +79,17 @@ uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  */
 void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be subracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subracted from the variable
  *
  * @return Value of the variable before the subtraction
  */
@@ -94,37 +97,32 @@ uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be subtracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
  */
 void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable before the increment
  */
-
 uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  */
 void odp_atomic_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Fetch and decrement atomic uint32 variabl

[lng-odp] [API-NEXT PATCH v2 3/7] api: doc: re-organize doxygen doc for synchronizer

2015-10-22 Thread Petri Savolainen
Removed module synchronizer from doxygen documentation and
introduced new modules for locks, atomics and barriers. Removed
unnecessary group tagging from internal headers, which are not
visible to doxygen anyway.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h  |  2 +-
 include/odp/api/barrier.h |  4 ++--
 include/odp/api/rwlock.h  | 19 +++
 include/odp/api/rwlock_recursive.h| 17 ++---
 include/odp/api/spinlock.h| 11 ---
 include/odp/api/spinlock_recursive.h  | 15 +--
 include/odp/api/sync.h|  2 +-
 include/odp/api/ticketlock.h  | 16 ++--
 platform/linux-generic/include/odp/atomic.h   |  2 +-
 platform/linux-generic/include/odp/barrier.h  |  8 
 .../linux-generic/include/odp/plat/atomic_types.h |  8 
 .../linux-generic/include/odp/plat/barrier_types.h|  8 
 .../include/odp/plat/rwlock_recursive_types.h | 13 +
 .../linux-generic/include/odp/plat/rwlock_types.h | 13 +
 .../include/odp/plat/spinlock_recursive_types.h   | 13 +
 .../linux-generic/include/odp/plat/spinlock_types.h   | 14 +-
 .../linux-generic/include/odp/plat/ticketlock_types.h | 13 +
 platform/linux-generic/include/odp/rwlock.h   |  8 
 platform/linux-generic/include/odp/spinlock.h |  8 
 platform/linux-generic/include/odp/sync.h |  8 
 platform/linux-generic/include/odp/ticketlock.h   |  9 -
 platform/linux-generic/include/odp_atomic_internal.h  |  9 -
 22 files changed, 58 insertions(+), 162 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index ba5c354..8aacc9d 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
+/** @defgroup odp_atomic ODP ATOMIC
  *  Atomic types and relaxed operations. These operations cannot be used for
  *  synchronization.
  *  @{
diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h
index 28310ba..8ca2647 100644
--- a/include/odp/api/barrier.h
+++ b/include/odp/api/barrier.h
@@ -18,8 +18,8 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Synchronize threads.
+/** @defgroup odp_barrier ODP BARRIER
+ *  Thread excution and memory ordering barriers.
  *  @{
  */
 
diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h
index d730a70..54f426f 100644
--- a/include/odp/api/rwlock.h
+++ b/include/odp/api/rwlock.h
@@ -17,18 +17,21 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_synchronizers ODP SYNCRONIZERS
- *  Operations on reader/writer locks.
- *  A reader/writer lock allows multiple simultaneous readers but only one
- *  writer at a time.
- *  A thread that wants write access will have to wait until there are no
- *  threads that want read access. This casues a risk for starvation.
- *  @{
+/**
+ * @defgroup odp_locks ODP LOCKS
+ * @details
+ *  Reader / writer lock (odp_rwlock_t) 
+ *
+ * A reader/writer lock allows multiple simultaneous readers but only one
+ * writer at a time. A thread that wants write access will have to wait until
+ * there are no threads that want read access. This casues a risk for
+ * starvation.
+ * @{
  */
 
 /**
  * @typedef odp_rwlock_t
- * ODP rwlock
+ * ODP reader/writer lock
  */
 
 
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
index 4c7556a..10b2f79 100644
--- a/include/odp/api/rwlock_recursive.h
+++ b/include/odp/api/rwlock_recursive.h
@@ -17,15 +17,12 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on recursive rwlocks.
- *  @{
- */
-
 /**
- * @typedef odp_rwlock_recursive_t
- * Recursive rwlock
+ * @addtogroup odp_locks
+ * @details
+ *  Recursive reader/writer lock (odp_rwlock_recursive_t) 
  *
+ * This is recursive version of the reader/writer lock.
  * A thread can read- or write-acquire a recursive read-write lock multiple
  * times without a deadlock. To release the lock, the thread must unlock it
  * the same number of times. Recursion is supported only for a pure series of
@@ -38,6 +35,12 @@ extern "C" {
  *
  * ... but this is not supported.
  *   * read_lock(); write_lock(); write_unlock(); read_unlock();
+ * @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
  */
 
 /**
diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h
index 9a5a929..154d025 100644
--- a/include/odp/api/spinlock.h
+++ b/include/odp/api/spinlock.h
@@ -18,9 +18,14 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on spin locks.
- *  @{
+/**
+ *

[lng-odp] [API-NEXT PATCH v2 7/7] api: atomic: added 32 bit acquire and release

2015-10-22 Thread Petri Savolainen
Added 32 bit acquire load/cas and release store/add/sub calls.
These are the minimum set of non-relaxed calls that are needed
for building lock-free algorithms. 64 bit versions can be added
later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 80 -
 platform/linux-generic/include/odp/atomic.h | 32 
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index b79a50a..316f13a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -21,7 +21,7 @@ extern "C" {
 /**
  * @defgroup odp_atomic ODP ATOMIC
  * @details
- *  Atomic integers 
+ *  Atomic integers using relaxed memory ordering 
  *
  * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
  * implement e.g. shared counters. If not otherwise documented, operations in
@@ -31,6 +31,18 @@ extern "C" {
  * before or after the operation), only atomicity of the operation itself is
  * guaranteed.
  *
+ *  Operations with other than relaxed memory ordering 
+ *
+ *  An operation with RELEASE  memory ordering 
(odp_atomic_xxx_rls_xxx())
+ * ensures that other threads loading the same atomic variable with ACQUIRE
+ * memory ordering see all stores (from the calling thread) that happened 
before
+ * this releasing store.
+ *
+ *  An operation with ACQUIRE  memory ordering 
(odp_atomic_xxx_acq_xxx())
+ * ensures that the calling thread sees all stores (done by the releasing
+ * thread) that happened before a RELEASE memory ordered store to the same
+ * atomic variable.
+ *
  * @{
  */
 
@@ -309,6 +321,72 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t 
new_min);
 int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
   uint64_t new_val);
 
+/*
+ * Operations with other than relaxed memory ordering
+ * --
+ */
+
+/**
+ * Load value of atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ *
+ * @return Value of the variable
+ */
+uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
+
+/**
+ * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
+ * Store value to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
+ */
+void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Add to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
+ */
+void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Subtract from atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
+ */
+void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index b2bc5c4..005a0cd 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -258,6 +258,38 @@ static inline void odp_atomic_min_u64(odp_atomic_u64_t 
*atom, uint64_t new_min)
}
 }
 
+static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
+{
+   return __atomic_load_n(>v, __ATOMIC_ACQUIRE);
+}
+
+static inline int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom,
+uint32_t *old_val, uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_ACQUIRE,
+  __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom,
+   

[lng-odp] [API-NEXT PATCH v2 1/7] api: doc: remove broken doxygen reference

2015-10-22 Thread Petri Savolainen
Reference caused warning when creating doxygen documentation.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 2 +-
 platform/linux-generic/include/odp/debug.h | 8 
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..c17f8fa 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -30,7 +30,7 @@ extern "C" {
  * odp_pktio_send().
  * Diagnostic messages can be enhanced by using odp_pktio_to_u64 which
  * will generate a printable reference for a pktio handle for use with
- * the logging @ref odp_ver_abt_log_dbg.
+ * the logging.
  *  @{
  */
 
diff --git a/platform/linux-generic/include/odp/debug.h 
b/platform/linux-generic/include/odp/debug.h
index 987ced2..a2e59bf 100644
--- a/platform/linux-generic/include/odp/debug.h
+++ b/platform/linux-generic/include/odp/debug.h
@@ -17,14 +17,6 @@
 extern "C" {
 #endif
 
-/** @ingroup odp_ver_abt_log_dbg
- *  @{
- */
-
-/**
- * @}
- */
-
 #include 
 
 #ifdef __cplusplus
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 6/7] api: atomic: added atomic min and max

2015-10-22 Thread Petri Savolainen
Added atomic min and max operations. These can be used e.g.
to maintain high and low water marks of an another atomic counter.
These use relaxed memory order.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 44 ++
 platform/linux-generic/include/odp/atomic.h | 48 +
 2 files changed, 92 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 957d304..b79a50a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,28 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Update maximum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max);
+
+/**
+ * Update minimum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min);
+
+/**
  * Compare and swap atomic uint32 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
@@ -248,6 +270,28 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Update maximum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max);
+
+/**
+ * Update minimum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atomPointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min);
+
+/**
  * Compare and swap atomic uint64 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 5b13e02..b2bc5c4 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -94,6 +94,30 @@ static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, 
uint32_t *old_val,
   __ATOMIC_RELAXED);
 }
 
+static inline void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
+{
+   uint32_t old_val;
+
+   old_val = odp_atomic_load_u32(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u32(atom, _val, new_min))
+   break;
+   }
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -210,6 +234,30 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t 
*atom, uint64_t *old_val,
 #endif
 }
 
+static inline void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_max > old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_max))
+   break;
+   }
+}
+
+static inline void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
+{
+   uint64_t old_val;
+
+   old_val = odp_atomic_load_u64(atom);
+
+   while (new_min < old_val) {
+   if (odp_atomic_cas_u64(atom, _val, new_min))
+   break;
+   }
+}
+
 /**
  * @}
  */
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 5/7] api: atomic: added cas operations

2015-10-22 Thread Petri Savolainen
Added cas operations for 32 and 64 bit atomic variables. These
use relaxed memory order (as all other operations).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h   | 37 ++
 platform/linux-generic/include/odp/atomic.h| 24 ++
 .../linux-generic/include/odp/plat/atomic_types.h  | 21 ++--
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 97e8639..957d304 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,25 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Compare and swap atomic uint32 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ *
+ */
+int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
  * Initialize atomic uint64 variable
  *
  * @param atomPointer to atomic variable
@@ -229,6 +248,24 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Compare and swap atomic uint64 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+  uint64_t new_val);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index deb4039..5b13e02 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -85,6 +85,15 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
(void)__atomic_fetch_sub(>v, 1, __ATOMIC_RELAXED);
 }
 
+static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -186,6 +195,21 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t 
*atom)
 #endif
 }
 
+static inline int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+   int ret;
+   *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(, *old_val, new_val));
+   return ret;
+#else
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+#endif
+}
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/plat/atomic_types.h 
b/platform/linux-generic/include/odp/plat/atomic_types.h
index 0f6c353..ea8fc2a 100644
--- a/platform/linux-generic/include/odp/plat/atomic_types.h
+++ b/platform/linux-generic/include/odp/plat/atomic_types.h
@@ -42,6 +42,21 @@ struct odp_atomic_u32_s {
 } ODP_ALIGNED(sizeof(uint32_t)); /* Enforce alignement! */;
 
 #if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+
+/**
+ * @internal
+ * CAS operation expression for the ATOMIC_OP macro
+ */
+#define ATOMIC_CAS_OP(ret_ptr, old_val, new_val) \
+({ \
+   if (atom->v == (old_val)) { \
+   atom->v = (new_val); \
+   *(ret_ptr) = 1; \
+   } else { \
+   *(ret_ptr) = 0; \
+   } \
+})
+
 /**
  * @internal
  * Helper macro for lock-based atomic operations on 64-bit integers
@@ -51,14 +66

[lng-odp] [API-NEXT PATCH v2 2/7] doc: add doxygen layout file to control group page output

2015-10-22 Thread Petri Savolainen
Group level documentation can be used for API level general
description. Layout file is needed to place detailed group
description on the top of a page. By default doxygen shows
only the brief description on top (the first sentence).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 doc/doxygen.cfg   |   1 +
 doc/doxygenlayout.xml | 195 ++
 2 files changed, 196 insertions(+)
 create mode 100644 doc/doxygenlayout.xml

diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg
index f28ec24..909f0ce 100644
--- a/doc/doxygen.cfg
+++ b/doc/doxygen.cfg
@@ -33,6 +33,7 @@ EXAMPLE_PATTERNS = *.c
 EXAMPLE_RECURSIVE = YES
 IMAGE_PATH = $(SRCDIR)/doc/images
 HTML_EXTRA_STYLESHEET = $(SRCDIR)/doc/odpdoxygen.css
+LAYOUT_FILE = $(SRCDIR)/doc/doxygenlayout.xml
 ENABLE_PREPROCESSING = YES
 MACRO_EXPANSION = YES
 EXPAND_ONLY_PREDEF = YES
diff --git a/doc/doxygenlayout.xml b/doc/doxygenlayout.xml
new file mode 100644
index 000..54467c8
--- /dev/null
+++ b/doc/doxygenlayout.xml
@@ -0,0 +1,195 @@
+
+  
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
-- 
2.6.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2] linux-generic: pktio: fill in L2 parse results by default

2015-10-21 Thread Petri Savolainen
Optimize and simplify packet parsing. Fill in L2 metadata
allways in packet input. Perform full packet parsing only
if other than L2 metadata is requested. Perform parsing only
for packets received from the network (disable parsing of
user created packets).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---

v2:
  * rebased
  * fixed typo
  * moved packet_parse_l2 to run always after data copy into packet

 .../linux-generic/include/odp_packet_internal.h|  61 ++-
 platform/linux-generic/odp_classification.c|   4 +-
 platform/linux-generic/odp_packet.c| 188 ++---
 platform/linux-generic/odp_packet_flags.c  |  24 ++-
 platform/linux-generic/odp_pool.c  |   3 -
 platform/linux-generic/pktio/loop.c|   5 +-
 platform/linux-generic/pktio/netmap.c  |   7 +-
 platform/linux-generic/pktio/pcap.c|   8 +-
 platform/linux-generic/pktio/socket.c  |   9 +-
 platform/linux-generic/pktio/socket_mmap.c |  10 +-
 10 files changed, 187 insertions(+), 132 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_internal.h 
b/platform/linux-generic/include/odp_packet_internal.h
index 8c41491..6f7d739 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -36,7 +36,8 @@ typedef union {
uint32_t all;
 
struct {
-   uint32_t unparsed:1;  /**< Set to inticate parse needed */
+   uint32_t parsed_l2:1; /**< L2 parsed */
+   uint32_t parsed_all:1;/**< Parsing complete */
 
uint32_t l2:1;/**< known L2 protocol present */
uint32_t l3:1;/**< known L3 protocol present */
@@ -152,43 +153,6 @@ static inline odp_packet_hdr_t 
*odp_packet_hdr(odp_packet_t pkt)
return (odp_packet_hdr_t *)odp_buf_to_hdr((odp_buffer_t)pkt);
 }
 
-/**
- * Initialize packet buffer
- */
-static inline void packet_init(pool_entry_t *pool,
-  odp_packet_hdr_t *pkt_hdr,
-  size_t size)
-{
-   /*
-   * Reset parser metadata.  Note that we clear via memset to make
-   * this routine indepenent of any additional adds to packet metadata.
-   */
-   const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
-   uint8_t *start;
-   size_t len;
-
-   start = (uint8_t *)pkt_hdr + start_offset;
-   len = sizeof(odp_packet_hdr_t) - start_offset;
-   memset(start, 0, len);
-
-   /* Set metadata items that initialize to non-zero values */
-   pkt_hdr->l2_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->payload_offset = ODP_PACKET_OFFSET_INVALID;
-
-   /*
-   * Packet headroom is set from the pool's headroom
-   * Packet tailroom is rounded up to fill the last
-   * segment occupied by the allocated length.
-   */
-   pkt_hdr->frame_len = size;
-   pkt_hdr->headroom  = pool->s.headroom;
-   pkt_hdr->tailroom  =
-   (pool->s.seg_size * pkt_hdr->buf_hdr.segcount) -
-   (pool->s.headroom + size);
-}
-
 static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
   odp_packet_hdr_t *dst_hdr)
 {
@@ -250,12 +214,14 @@ static inline void packet_set_len(odp_packet_t pkt, 
uint32_t len)
odp_packet_hdr(pkt)->frame_len = len;
 }
 
-#define ODP_PACKET_UNPARSED ~0
+static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
+{
+   return !pkt_hdr->input_flags.parsed_l2;
+}
 
-static inline void _odp_packet_reset_parse(odp_packet_t pkt)
+static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
 {
-   odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
-   pkt_hdr->input_flags.all = ODP_PACKET_UNPARSED;
+   return !pkt_hdr->input_flags.parsed_all;
 }
 
 /* Forward declarations */
@@ -265,9 +231,16 @@ int _odp_packet_copy_to_packet(odp_packet_t srcpkt, 
uint32_t srcoffset,
 
 void _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt);
 
-odp_packet_t _odp_packet_alloc(odp_pool_t pool_hdl);
+odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len, int parse);
 
-int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr);
+/* Fill in parser metadata for L2 */
+void packet_parse_l2(odp_packet_hdr_t *pkt_hdr);
+
+/* Perform full packet parse */
+int packet_parse_full(odp_packet_hdr_t *pkt_hdr);
+
+/* Reset parser metadata for a new parse */
+void packet_parse_reset(odp_packet_t pkt);
 
 /* Convert a packet handle to a buffer handle */
 odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt);
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classific

[lng-odp] [API-NEXT PATCH] api: clib: added standard c library api

2015-10-16 Thread Petri Savolainen
Some C library calls are often used in data plane code. This
API enables possibility to HW optimized implementation of those.
Added first memcpy and memset.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp.h |  1 +
 include/odp/api/std_clib.h| 64 +++
 platform/linux-generic/Makefile.am|  2 +
 platform/linux-generic/include/odp/std_clib.h | 30 +
 4 files changed, 97 insertions(+)
 create mode 100644 include/odp/api/std_clib.h
 create mode 100644 platform/linux-generic/include/odp/std_clib.h

diff --git a/include/odp.h b/include/odp.h
index 825c7e1..f2cd2d3 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -56,6 +56,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/std_clib.h b/include/odp/api/std_clib.h
new file mode 100644
index 000..2119ec4
--- /dev/null
+++ b/include/odp/api/std_clib.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP version of often used C library calls
+ */
+
+#ifndef ODP_API_STD_CLIB_H_
+#define ODP_API_STD_CLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup odp_std_clib ODP STD CLIB
+ * @details
+ * ODP version of often used C library calls
+ * @{
+ */
+
+/**
+ * Memcpy
+ *
+ * ODP version of C library memcpy function. It copies 'num' bytes from source
+ * to destination address. Source and destination memory blocks must not
+ * overlap.
+ *
+ * @param dstPointer to destination memory block
+ * @param srcPointer to source memory block
+ * @param numNumber of bytes to copy
+ *
+ * @return 'dst' address
+ */
+void *odp_memcpy(void *dst, const void *src, size_t num);
+
+/**
+ * Memset
+ *
+ * ODP version of C library memset function. It sets 'value' to first 'num'
+ * bytes of memory block pointed by 'ptr'.
+ *
+ * @param ptrPointer to the memory block
+ * @param value  Value to be set
+ * @param numNumber of bytes to set
+ *
+ * @return 'ptr' address
+ */
+void *odp_memset(void *ptr, int value, size_t num);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 85c976d..fc202cc 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -41,6 +41,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/shared_memory.h \
  $(srcdir)/include/odp/spinlock.h \
  $(srcdir)/include/odp/spinlock_recursive.h \
+ $(srcdir)/include/odp/std_clib.h \
  $(srcdir)/include/odp/std_types.h \
  $(srcdir)/include/odp/sync.h \
  $(srcdir)/include/odp/system_info.h \
@@ -108,6 +109,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/shared_memory.h \
  $(top_srcdir)/include/odp/api/spinlock.h \
  $(top_srcdir)/include/odp/api/spinlock_recursive.h \
+ $(top_srcdir)/include/odp/api/std_clib.h \
  $(top_srcdir)/include/odp/api/std_types.h \
  $(top_srcdir)/include/odp/api/sync.h \
  $(top_srcdir)/include/odp/api/system_info.h \
diff --git a/platform/linux-generic/include/odp/std_clib.h 
b/platform/linux-generic/include/odp/std_clib.h
new file mode 100644
index 000..c939c48
--- /dev/null
+++ b/platform/linux-generic/include/odp/std_clib.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_PLAT_STD_CLIB_H_
+#define ODP_PLAT_STD_CLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+static inline void *odp_memcpy(void *dst, const void *src, size_t num)
+{
+   return memcpy(dst, src, num);
+}
+
+static inline void *odp_memset(void *ptr, int value, size_t num)
+{
+   return memset(ptr, value, num);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 2/6] doc: add doxygen layout file to control group page output

2015-10-15 Thread Petri Savolainen
Group level documentation can be used for API level general
description. Layout file is needed to place detailed group
description on the top of a page. By default doxygen shows
only the brief description on top (the first sentence).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 doc/doxygen.cfg   |   1 +
 doc/doxygenlayout.xml | 195 ++
 2 files changed, 196 insertions(+)
 create mode 100644 doc/doxygenlayout.xml

diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg
index f28ec24..909f0ce 100644
--- a/doc/doxygen.cfg
+++ b/doc/doxygen.cfg
@@ -33,6 +33,7 @@ EXAMPLE_PATTERNS = *.c
 EXAMPLE_RECURSIVE = YES
 IMAGE_PATH = $(SRCDIR)/doc/images
 HTML_EXTRA_STYLESHEET = $(SRCDIR)/doc/odpdoxygen.css
+LAYOUT_FILE = $(SRCDIR)/doc/doxygenlayout.xml
 ENABLE_PREPROCESSING = YES
 MACRO_EXPANSION = YES
 EXPAND_ONLY_PREDEF = YES
diff --git a/doc/doxygenlayout.xml b/doc/doxygenlayout.xml
new file mode 100644
index 000..54467c8
--- /dev/null
+++ b/doc/doxygenlayout.xml
@@ -0,0 +1,195 @@
+
+  
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+  
+  
+
+
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+
+  
+
+  
+  
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+  
+
+  
+  
+
+
+
+  
+  
+
+
+  
+
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 6/6] api: atomic: added 32 bit acquire and release

2015-10-15 Thread Petri Savolainen
Added 32 bit acquire load/cas and release store/add/sub calls.
These are the minimum set of non-relaxed calls that are needed
for building lock-free algorithms. 64 bit versions can be added
later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 80 -
 platform/linux-generic/include/odp/atomic.h | 32 
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 957d304..cbf241d 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -21,7 +21,7 @@ extern "C" {
 /**
  * @defgroup odp_atomic ODP ATOMIC
  * @details
- *  Atomic integers 
+ *  Atomic integers using relaxed memory ordering 
  *
  * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
  * implement e.g. shared counters. If not otherwise documented, operations in
@@ -31,6 +31,18 @@ extern "C" {
  * before or after the operation), only atomicity of the operation itself is
  * guaranteed.
  *
+ *  Operations with other than relaxed memory ordering 
+ *
+ *  An operation with RELEASE  memory ordering 
(odp_atomic_xxx_rls_xxx())
+ * ensures that other threads loading the same atomic variable with ACQUIRE
+ * memory ordering see all stores (from the calling thread) that happened 
before
+ * this releasing store.
+ *
+ *  An operation with ACQUIRE  memory ordering 
(odp_atomic_xxx_acq_xxx())
+ * ensures that the calling thread sees all stores (done by the releasing
+ * thread) that happened before a RELEASE memory ordered store to the same
+ * atomic variable.
+ *
  * @{
  */
 
@@ -265,6 +277,72 @@ void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
   uint64_t new_val);
 
+/*
+ * Operations with other than relaxed memory ordering
+ * --
+ */
+
+/**
+ * Load value of atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ *
+ * @return Value of the variable
+ */
+uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
+
+/**
+ * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
+ * Store value to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
+ */
+void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Add to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
+ */
+void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Subtract from atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
+ */
+void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 5a143a5..8f83c04 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -204,6 +204,38 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t 
*atom, uint64_t *old_val,
   __ATOMIC_RELAXED);
 }
 
+static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
+{
+   return __atomic_load_n(>v, __ATOMIC_ACQUIRE);
+}
+
+static inline int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom,
+uint32_t *old_val, uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_ACQUIRE,
+  __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_stor

[lng-odp] [API-NEXT PATCH 1/6] api: doc: remove broken doxygen reference

2015-10-15 Thread Petri Savolainen
Reference caused warning when creating doxygen documentation.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h| 2 +-
 platform/linux-generic/include/odp/debug.h | 8 
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3479af1..c17f8fa 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -30,7 +30,7 @@ extern "C" {
  * odp_pktio_send().
  * Diagnostic messages can be enhanced by using odp_pktio_to_u64 which
  * will generate a printable reference for a pktio handle for use with
- * the logging @ref odp_ver_abt_log_dbg.
+ * the logging.
  *  @{
  */
 
diff --git a/platform/linux-generic/include/odp/debug.h 
b/platform/linux-generic/include/odp/debug.h
index 987ced2..a2e59bf 100644
--- a/platform/linux-generic/include/odp/debug.h
+++ b/platform/linux-generic/include/odp/debug.h
@@ -17,14 +17,6 @@
 extern "C" {
 #endif
 
-/** @ingroup odp_ver_abt_log_dbg
- *  @{
- */
-
-/**
- * @}
- */
-
 #include 
 
 #ifdef __cplusplus
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 5/6] api: atomic: added cas operations

2015-10-15 Thread Petri Savolainen
Added cas operations for 32 and 64 bit atomic variables. These
use relaxed memory order (as all other operations).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h| 37 +
 platform/linux-generic/include/odp/atomic.h | 18 ++
 2 files changed, 55 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 97e8639..957d304 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,25 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Compare and swap atomic uint32 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ *
+ */
+int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+  uint32_t new_val);
+
+/**
  * Initialize atomic uint64 variable
  *
  * @param atomPointer to atomic variable
@@ -229,6 +248,24 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Compare and swap atomic uint64 variable
+ *
+ * Compares value of atomic variable to the value pointed by 'old_val'.
+ * If values are equal, the operation writes 'new_val' into the atomic variable
+ * and returns success. If they are not equal, the operation writes current
+ * value of atomic variable into 'old_val' and returns failure.
+ *
+ * @param atom  Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *  Operation updates this value on failure.
+ * @param new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+  uint64_t new_val);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index deb4039..5a143a5 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -85,6 +85,15 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
(void)__atomic_fetch_sub(>v, 1, __ATOMIC_RELAXED);
 }
 
+static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+uint32_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
atom->v = val;
@@ -186,6 +195,15 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t 
*atom)
 #endif
 }
 
+static inline int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
+uint64_t new_val)
+{
+   return __atomic_compare_exchange_n(>v, old_val, new_val,
+  0 /* strong */,
+  __ATOMIC_RELAXED,
+  __ATOMIC_RELAXED);
+}
+
 /**
  * @}
  */
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 4/6] api: atomic: clean atomic API documentation

2015-10-15 Thread Petri Savolainen
Refined and centralized comment about relaxed memory ordering.
Removed in/out doxygen tags since 'atom' pointer to an object
that application must not directly access (only through the API).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h | 112 ---
 1 file changed, 48 insertions(+), 64 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 8aacc9d..97e8639 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,10 +18,20 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_atomic ODP ATOMIC
- *  Atomic types and relaxed operations. These operations cannot be used for
- *  synchronization.
- *  @{
+/**
+ * @defgroup odp_atomic ODP ATOMIC
+ * @details
+ *  Atomic integers 
+ *
+ * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
+ * implement e.g. shared counters. If not otherwise documented, operations in
+ * this API are implemented using  RELAXED memory ordering  (see memory
+ * order descriptions in the C11 specification). Relaxed operations do not
+ * provide synchronization or ordering for other memory accesses (initiated
+ * before or after the operation), only atomicity of the operation itself is
+ * guaranteed.
+ *
+ * @{
  */
 
 /**
@@ -34,19 +44,16 @@ extern "C" {
 
 /**
  * Initialize atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to initialize the variable with
+ * @param atomPointer to atomic variable
+ * @param val Value to initialize the variable with
  */
 void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val);
 
-
 /**
  * Load value of atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable
  */
@@ -54,19 +61,17 @@ uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom);
 
 /**
  * Store value to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[out] atom Pointer to an atomic uint32 variable
- * @param val Value to store in the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to store in the variable
  */
 void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  *
  * @return Value of the variable before the addition
  */
@@ -74,19 +79,17 @@ uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Add to atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be added to the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be added to the variable
  */
 void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val A value to be subracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subracted from the variable
  *
  * @return Value of the variable before the subtraction
  */
@@ -94,37 +97,32 @@ uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, 
uint32_t val);
 
 /**
  * Subtract from atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
- * @param val Value to be subtracted from the variable
+ * @param atomPointer to atomic variable
+ * @param val Value to be subtracted from the variable
  */
 void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
 
 /**
  * Fetch and increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  *
  * @return Value of the variable before the increment
  */
-
 uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Increment atomic uint32 variable
- * @note Relaxed memory order, cannot be used for synchronization
  *
- * @param[in,out] atom Pointer to an atomic uint32 variable
+ * @param atomPointer to atomic variable
  */
 void odp_atomic_inc_u32(odp_atomic_u32_t *atom);
 
 /**
  * Fetch and decrement atomic uint32 variabl

[lng-odp] [API-NEXT PATCH 3/6] api: doc: re-organize doxygen doc for synchronizer

2015-10-15 Thread Petri Savolainen
Removed module synchronizer from doxygen documentation and
introduced new modules for locks, atomics and barriers. Removed
unnecessary group tagging from internal headers, which are not
visible to doxygen anyway.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h  |  2 +-
 include/odp/api/barrier.h |  4 ++--
 include/odp/api/rwlock.h  | 19 +++
 include/odp/api/rwlock_recursive.h| 17 ++---
 include/odp/api/spinlock.h| 11 ---
 include/odp/api/spinlock_recursive.h  | 15 +--
 include/odp/api/sync.h|  2 +-
 include/odp/api/ticketlock.h  | 16 ++--
 platform/linux-generic/include/odp/atomic.h   |  2 +-
 platform/linux-generic/include/odp/barrier.h  |  8 
 .../linux-generic/include/odp/plat/atomic_types.h |  8 
 .../linux-generic/include/odp/plat/barrier_types.h|  8 
 .../include/odp/plat/rwlock_recursive_types.h | 13 +
 .../linux-generic/include/odp/plat/rwlock_types.h | 13 +
 .../include/odp/plat/spinlock_recursive_types.h   | 13 +
 .../linux-generic/include/odp/plat/spinlock_types.h   | 14 +-
 .../linux-generic/include/odp/plat/ticketlock_types.h | 13 +
 platform/linux-generic/include/odp/rwlock.h   |  8 
 platform/linux-generic/include/odp/spinlock.h |  8 
 platform/linux-generic/include/odp/sync.h |  8 
 platform/linux-generic/include/odp/ticketlock.h   |  9 -
 platform/linux-generic/include/odp_atomic_internal.h  |  9 -
 22 files changed, 58 insertions(+), 162 deletions(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index ba5c354..8aacc9d 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
+/** @defgroup odp_atomic ODP ATOMIC
  *  Atomic types and relaxed operations. These operations cannot be used for
  *  synchronization.
  *  @{
diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h
index 28310ba..8ca2647 100644
--- a/include/odp/api/barrier.h
+++ b/include/odp/api/barrier.h
@@ -18,8 +18,8 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Synchronize threads.
+/** @defgroup odp_barrier ODP BARRIER
+ *  Thread excution and memory ordering barriers.
  *  @{
  */
 
diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h
index d730a70..54f426f 100644
--- a/include/odp/api/rwlock.h
+++ b/include/odp/api/rwlock.h
@@ -17,18 +17,21 @@
 extern "C" {
 #endif
 
-/** @defgroup odp_synchronizers ODP SYNCRONIZERS
- *  Operations on reader/writer locks.
- *  A reader/writer lock allows multiple simultaneous readers but only one
- *  writer at a time.
- *  A thread that wants write access will have to wait until there are no
- *  threads that want read access. This casues a risk for starvation.
- *  @{
+/**
+ * @defgroup odp_locks ODP LOCKS
+ * @details
+ *  Reader / writer lock (odp_rwlock_t) 
+ *
+ * A reader/writer lock allows multiple simultaneous readers but only one
+ * writer at a time. A thread that wants write access will have to wait until
+ * there are no threads that want read access. This casues a risk for
+ * starvation.
+ * @{
  */
 
 /**
  * @typedef odp_rwlock_t
- * ODP rwlock
+ * ODP reader/writer lock
  */
 
 
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
index 4c7556a..10b2f79 100644
--- a/include/odp/api/rwlock_recursive.h
+++ b/include/odp/api/rwlock_recursive.h
@@ -17,15 +17,12 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on recursive rwlocks.
- *  @{
- */
-
 /**
- * @typedef odp_rwlock_recursive_t
- * Recursive rwlock
+ * @addtogroup odp_locks
+ * @details
+ *  Recursive reader/writer lock (odp_rwlock_recursive_t) 
  *
+ * This is recursive version of the reader/writer lock.
  * A thread can read- or write-acquire a recursive read-write lock multiple
  * times without a deadlock. To release the lock, the thread must unlock it
  * the same number of times. Recursion is supported only for a pure series of
@@ -38,6 +35,12 @@ extern "C" {
  *
  * ... but this is not supported.
  *   * read_lock(); write_lock(); write_unlock(); read_unlock();
+ * @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
  */
 
 /**
diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h
index 9a5a929..154d025 100644
--- a/include/odp/api/spinlock.h
+++ b/include/odp/api/spinlock.h
@@ -18,9 +18,14 @@
 extern "C" {
 #endif
 
-/** @addtogroup odp_synchronizers
- *  Operations on spin locks.
- *  @{
+/**
+ *

[lng-odp] [PATCH] linux-generic: pktio: fill in L2 parse results by default

2015-10-12 Thread Petri Savolainen
Optimize and simplify packet parsing. Fill in L2 metadata
allways in packet input. Perform full packet parsing only
if other than L2 metadata is requested. Perform parsing only
for packets received from the network (disable parsing of
user created packets).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .../linux-generic/include/odp_packet_internal.h|  61 ++-
 platform/linux-generic/odp_classification.c|   4 +-
 platform/linux-generic/odp_packet.c| 184 ++---
 platform/linux-generic/odp_packet_flags.c  |  24 ++-
 platform/linux-generic/odp_pool.c  |   3 -
 platform/linux-generic/pktio/loop.c|   8 +-
 platform/linux-generic/pktio/netmap.c  |  10 +-
 platform/linux-generic/pktio/socket.c  |  10 +-
 platform/linux-generic/pktio/socket_mmap.c |  11 +-
 9 files changed, 186 insertions(+), 129 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_internal.h 
b/platform/linux-generic/include/odp_packet_internal.h
index 8c41491..7c42bcb 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -36,7 +36,8 @@ typedef union {
uint32_t all;
 
struct {
-   uint32_t unparsed:1;  /**< Set to inticate parse needed */
+   uint32_t parsed_l2:1; /**< L2 parsed */
+   uint32_t parsed_all:1;/**< Parsing complite */
 
uint32_t l2:1;/**< known L2 protocol present */
uint32_t l3:1;/**< known L3 protocol present */
@@ -152,43 +153,6 @@ static inline odp_packet_hdr_t 
*odp_packet_hdr(odp_packet_t pkt)
return (odp_packet_hdr_t *)odp_buf_to_hdr((odp_buffer_t)pkt);
 }
 
-/**
- * Initialize packet buffer
- */
-static inline void packet_init(pool_entry_t *pool,
-  odp_packet_hdr_t *pkt_hdr,
-  size_t size)
-{
-   /*
-   * Reset parser metadata.  Note that we clear via memset to make
-   * this routine indepenent of any additional adds to packet metadata.
-   */
-   const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
-   uint8_t *start;
-   size_t len;
-
-   start = (uint8_t *)pkt_hdr + start_offset;
-   len = sizeof(odp_packet_hdr_t) - start_offset;
-   memset(start, 0, len);
-
-   /* Set metadata items that initialize to non-zero values */
-   pkt_hdr->l2_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
-   pkt_hdr->payload_offset = ODP_PACKET_OFFSET_INVALID;
-
-   /*
-   * Packet headroom is set from the pool's headroom
-   * Packet tailroom is rounded up to fill the last
-   * segment occupied by the allocated length.
-   */
-   pkt_hdr->frame_len = size;
-   pkt_hdr->headroom  = pool->s.headroom;
-   pkt_hdr->tailroom  =
-   (pool->s.seg_size * pkt_hdr->buf_hdr.segcount) -
-   (pool->s.headroom + size);
-}
-
 static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
   odp_packet_hdr_t *dst_hdr)
 {
@@ -250,12 +214,14 @@ static inline void packet_set_len(odp_packet_t pkt, 
uint32_t len)
odp_packet_hdr(pkt)->frame_len = len;
 }
 
-#define ODP_PACKET_UNPARSED ~0
+static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
+{
+   return !pkt_hdr->input_flags.parsed_l2;
+}
 
-static inline void _odp_packet_reset_parse(odp_packet_t pkt)
+static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
 {
-   odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
-   pkt_hdr->input_flags.all = ODP_PACKET_UNPARSED;
+   return !pkt_hdr->input_flags.parsed_all;
 }
 
 /* Forward declarations */
@@ -265,9 +231,16 @@ int _odp_packet_copy_to_packet(odp_packet_t srcpkt, 
uint32_t srcoffset,
 
 void _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt);
 
-odp_packet_t _odp_packet_alloc(odp_pool_t pool_hdl);
+odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len, int parse);
 
-int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr);
+/* Fill in parser metadata for L2 */
+void packet_parse_l2(odp_packet_hdr_t *pkt_hdr);
+
+/* Perform full packet parse */
+int packet_parse_full(odp_packet_hdr_t *pkt_hdr);
+
+/* Reset parser metadata for a new parse */
+void packet_parse_reset(odp_packet_t pkt);
 
 /* Convert a packet handle to a buffer handle */
 odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt);
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index fb1b019..28d1d50 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -829,8 +829,8 @@ cos_t *pktio_select_

[lng-odp] [API-NEXT PATCH] api: pktio: improve pktio_start and stop documentation

2015-10-05 Thread Petri Savolainen
Improved documentation of open, start and stop calls.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/packet_io.h | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index d8e69ed..f6227c6 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -103,6 +103,11 @@ typedef struct odp_pktio_param_t {
  * errno set. Use odp_pktio_lookup() to obtain a handle to an already open
  * device. Packet IO parameters provide interface level configuration options.
  *
+ * This call does not activate packet receive and transmit is on the interface.
+ * The interface is activated with a call to odp_pktio_start(). By default,
+ * interface level configuration must not be changed when the interface is
+ * active (between start and stop calls).
+ *
  * @param devPacket IO device name
  * @param pool   Default pool from which to allocate storage for packets
  *   received over this interface, must be of type ODP_POOL_PACKET
@@ -121,6 +126,8 @@ typedef struct odp_pktio_param_t {
  *  assigned the packet to a specific CoS. The default pool specified
  *  here is applicable only for those packets that are not assigned to a
  *  more specific CoS.
+ *
+ * @see odp_pktio_start(), odp_pktio_stop()
  */
 odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool,
   const odp_pktio_param_t *param);
@@ -128,6 +135,9 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool,
 /**
  * Start packet receive and transmit
  *
+ * Activate packet receive and transmit on a previously opened or stopped
+ * interface. The interface can be stopped with a call to odp_pktio_stop().
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
@@ -138,6 +148,11 @@ int odp_pktio_start(odp_pktio_t pktio);
 /**
  * Stop packet receive and transmit
  *
+ * Stop packet receive and transmit on a previously started interface. New
+ * packets are not received from or transmitted to the network. Packets already
+ * received from the network can be still received (normally) from
+ * the interface.
+ *
  * @param pktio  Packet IO handle
  *
  * @retval 0 on success
-- 
2.6.0

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH v2] linux-generic: pktio: enable classifier only when needed

2015-09-28 Thread Petri Savolainen
Packet input does not call packet_classifier function when
there are no cos (pmr, default cos or l2/l3 table) set for
the pktio interface.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .../linux-generic/include/odp_packet_io_internal.h | 10 +++
 platform/linux-generic/odp_classification.c|  5 ++
 platform/linux-generic/odp_packet_io.c | 97 ++
 3 files changed, 78 insertions(+), 34 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index a21c683..6b03051 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -109,6 +109,16 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t 
pktio)
return pktio_entry_ptr[pktio_to_id(pktio)];
 }
 
+static inline int pktio_cls_enabled(pktio_entry_t *entry)
+{
+   return entry->s.cls_enabled;
+}
+
+static inline void pktio_cls_enabled_set(pktio_entry_t *entry, int ena)
+{
+   entry->s.cls_enabled = ena;
+}
+
 int pktin_poll(pktio_entry_t *entry);
 
 extern const pktio_if_ops_t sock_mmsg_pktio_ops;
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index 6c1aff4..fb1b019 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -307,6 +307,7 @@ int odp_pktio_default_cos_set(odp_pktio_t pktio_in, 
odp_cos_t default_cos)
}
 
entry->s.cls.default_cos = cos;
+   pktio_cls_enabled_set(entry, 1);
return 0;
 }
 
@@ -378,6 +379,7 @@ int odp_cos_with_l2_priority(odp_pktio_t pktio_in,
l2_cos->cos[qos_table[i]] = cos;
}
}
+   pktio_cls_enabled_set(entry, 1);
UNLOCK(_cos->lock);
return 0;
 }
@@ -410,6 +412,7 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in,
l3_cos->cos[qos_table[i]] = cos;
}
}
+   pktio_cls_enabled_set(entry, 1);
UNLOCK(_cos->lock);
return 0;
 }
@@ -488,6 +491,7 @@ int odp_pktio_pmr_cos(odp_pmr_t pmr_id,
pktio_entry->s.cls.pmr[num_pmr] = pmr;
pktio_entry->s.cls.cos[num_pmr] = cos;
pktio_entry->s.cls.num_pmr++;
+   pktio_cls_enabled_set(pktio_entry, 1);
UNLOCK(_entry->s.cls.lock);
 
return 0;
@@ -625,6 +629,7 @@ int odp_pktio_pmr_match_set_cos(odp_pmr_set_t pmr_set_id, 
odp_pktio_t src_pktio,
pktio_entry->s.cls.pmr[num_pmr] = pmr;
pktio_entry->s.cls.cos[num_pmr] = cos;
pktio_entry->s.cls.num_pmr++;
+   pktio_cls_enabled_set(pktio_entry, 1);
UNLOCK(_entry->s.cls.lock);
 
return 0;
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index d724933..2e7b199 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -154,9 +154,7 @@ static void unlock_entry_classifier(pktio_entry_t *entry)
 static void init_pktio_entry(pktio_entry_t *entry)
 {
set_taken(entry);
-   /* Currently classifier is enabled by default. It should be enabled
-  only when used. */
-   entry->s.cls_enabled = 1;
+   pktio_cls_enabled_set(entry, 0);
entry->s.inq_default = ODP_QUEUE_INVALID;
 
pktio_classifier_init(entry);
@@ -542,30 +540,42 @@ odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
odp_buffer_hdr_t *buf_hdr;
odp_buffer_t buf;
odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
-   odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
+   odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
int pkts, i, j;
+   odp_pktio_t pktio;
 
buf_hdr = queue_deq(qentry);
if (buf_hdr != NULL)
return buf_hdr;
 
-   pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, QUEUE_MULTI_MAX);
+   pktio = qentry->s.pktin;
+
+   pkts = odp_pktio_recv(pktio, pkt_tbl, QUEUE_MULTI_MAX);
if (pkts <= 0)
return NULL;
 
-   for (i = 0, j = 0; i < pkts; ++i) {
-   buf = _odp_packet_to_buffer(pkt_tbl[i]);
-   buf_hdr = odp_buf_to_hdr(buf);
-   if (0 > packet_classifier(qentry->s.pktin, pkt_tbl[i]))
-   tmp_hdr_tbl[j++] = buf_hdr;
+   if (pktio_cls_enabled(get_pktio_entry(pktio))) {
+   for (i = 0, j = 0; i < pkts; i++) {
+   if (0 > packet_classifier(pktio, pkt_tbl[i])) {
+   buf = _odp_packet_to_buffer(pkt_tbl[i]);
+   hdr_tbl[j++] = odp_buf_to_hdr(buf);
+   }
+   }
+   } else {
+   for (i = 0; i < pkts; i++) {
+   buf= _odp_packet_to_buffer(pkt_tbl[i]);
+   hdr_tbl[i] = odp_buf_

[lng-odp] [PATCH] linux-generic: pktio: enable classifier only when needed

2015-09-18 Thread Petri Savolainen
Skip packet_classifier function as long as there's no pmr
set for an pktio interface.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/include/odp_packet_io_internal.h | 10 ++
 platform/linux-generic/odp_classification.c |  2 ++
 platform/linux-generic/odp_packet_io.c  |  6 ++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index a21c683..6b03051 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -109,6 +109,16 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t 
pktio)
return pktio_entry_ptr[pktio_to_id(pktio)];
 }
 
+static inline int pktio_cls_enabled(pktio_entry_t *entry)
+{
+   return entry->s.cls_enabled;
+}
+
+static inline void pktio_cls_enabled_set(pktio_entry_t *entry, int ena)
+{
+   entry->s.cls_enabled = ena;
+}
+
 int pktin_poll(pktio_entry_t *entry);
 
 extern const pktio_if_ops_t sock_mmsg_pktio_ops;
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index 6c1aff4..7809a42 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -488,6 +488,7 @@ int odp_pktio_pmr_cos(odp_pmr_t pmr_id,
pktio_entry->s.cls.pmr[num_pmr] = pmr;
pktio_entry->s.cls.cos[num_pmr] = cos;
pktio_entry->s.cls.num_pmr++;
+   pktio_cls_enabled_set(pktio_entry, 1);
UNLOCK(_entry->s.cls.lock);
 
return 0;
@@ -625,6 +626,7 @@ int odp_pktio_pmr_match_set_cos(odp_pmr_set_t pmr_set_id, 
odp_pktio_t src_pktio,
pktio_entry->s.cls.pmr[num_pmr] = pmr;
pktio_entry->s.cls.cos[num_pmr] = cos;
pktio_entry->s.cls.num_pmr++;
+   pktio_cls_enabled_set(pktio_entry, 1);
UNLOCK(_entry->s.cls.lock);
 
return 0;
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index d724933..aa2b566 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -154,9 +154,7 @@ static void unlock_entry_classifier(pktio_entry_t *entry)
 static void init_pktio_entry(pktio_entry_t *entry)
 {
set_taken(entry);
-   /* Currently classifier is enabled by default. It should be enabled
-  only when used. */
-   entry->s.cls_enabled = 1;
+   pktio_cls_enabled_set(entry, 0);
entry->s.inq_default = ODP_QUEUE_INVALID;
 
pktio_classifier_init(entry);
@@ -642,7 +640,7 @@ int pktin_poll(pktio_entry_t *entry)
buf = _odp_packet_to_buffer(pkt_tbl[i]);
hdr = odp_buf_to_hdr(buf);
 
-   if (entry->s.cls_enabled) {
+   if (pktio_cls_enabled(entry)) {
if (packet_classifier(entry->s.handle, pkt_tbl[i]) < 0)
hdr_tbl[num_enq++] = hdr;
} else {
-- 
2.5.3

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [PATCH] checkpatch: allow comparison to NULL

2015-09-15 Thread Petri Savolainen
Allow comparison to NULL since ODP API calls may return NULL
and test applications should be able to compare against that,
instead of forced to compare against 0 (!ptr).

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .checkpatch.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.checkpatch.conf b/.checkpatch.conf
index c9f2896..69af101 100644
--- a/.checkpatch.conf
+++ b/.checkpatch.conf
@@ -3,5 +3,6 @@
 --ignore=SPLIT_STRING
 --ignore=NEW_TYPEDEFS
 --ignore=DEPRECATED_VARIABLE
+--ignore=COMPARISON_TO_NULL
 --codespell
 --codespellfile=/usr/share/codespell/dictionary.txt
-- 
2.5.2

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 3/3] api: config: removed ODP_CONFIG_MAX_THREADS

2015-09-15 Thread Petri Savolainen
New thread API call odp_thread_count_max() replaces the
preprocessor macro in the API. A macro is still used
internally.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/config.h   |  5 ---
 .../linux-generic/include/odp/plat/cpumask_types.h |  3 +-
 .../include/odp/plat/rwlock_recursive_types.h  |  4 +--
 .../linux-generic/include/odp_buffer_internal.h|  3 +-
 .../linux-generic/include/odp_config_internal.h| 29 
 platform/linux-generic/odp_thread.c| 11 +++---
 platform/linux-generic/odp_thrmask.c   |  4 +--
 test/performance/odp_pktio_perf.c  | 40 +++---
 test/validation/thread/thread.c|  2 +-
 9 files changed, 79 insertions(+), 22 deletions(-)
 create mode 100644 platform/linux-generic/include/odp_config_internal.h

diff --git a/include/odp/api/config.h b/include/odp/api/config.h
index 302eaf5..bf88be8 100644
--- a/include/odp/api/config.h
+++ b/include/odp/api/config.h
@@ -24,11 +24,6 @@ extern "C" {
  */
 
 /**
- * Maximum number of threads
- */
-#define ODP_CONFIG_MAX_THREADS  128
-
-/**
  * Maximum number of pools
  */
 #define ODP_CONFIG_POOLS16
diff --git a/platform/linux-generic/include/odp/plat/cpumask_types.h 
b/platform/linux-generic/include/odp/plat/cpumask_types.h
index 6fba832..affe59b 100644
--- a/platform/linux-generic/include/odp/plat/cpumask_types.h
+++ b/platform/linux-generic/include/odp/plat/cpumask_types.h
@@ -23,11 +23,12 @@ extern "C" {
  */
 
 #include 
+#include 
 
 /**
  * Minimum size of output buffer for odp_cpumask_to_str()
  */
-#define ODP_CPUMASK_STR_SIZE ((ODP_CONFIG_MAX_THREADS + 3) / 4 + 3)
+#define ODP_CPUMASK_STR_SIZE ((_ODP_INTERNAL_MAX_THREADS + 3) / 4 + 3)
 
 /**
  * CPU mask
diff --git a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h 
b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
index 9e220f5..ee81872 100644
--- a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
+++ b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
@@ -19,7 +19,7 @@ extern "C" {
 
 #include 
 #include 
-#include 
+#include 
 
 /**
  * @internal
@@ -29,7 +29,7 @@ struct odp_rwlock_recursive_s {
odp_rwlock_t lock;   /**< the lock */
int wr_owner;/**< write owner thread */
uint32_t wr_cnt; /**< write recursion count */
-   uint8_t  rd_cnt[ODP_CONFIG_MAX_THREADS]; /**< read recursion count */
+   uint8_t  rd_cnt[_ODP_INTERNAL_MAX_THREADS]; /**< read recursion count */
 };
 
 /** @addtogroup odp_synchronizers
diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
b/platform/linux-generic/include/odp_buffer_internal.h
index 4cacca1..edd6794 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -30,6 +30,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #define ODP_BITSIZE(x) \
((x) <= 2 ?  1 : \
@@ -143,7 +144,7 @@ struct odp_buffer_hdr_t {
 
 /** @internal Compile time assert that the
  * allocator field can handle any allocator id*/
-_ODP_STATIC_ASSERT(INT16_MAX >= ODP_CONFIG_MAX_THREADS,
+_ODP_STATIC_ASSERT(INT16_MAX >= _ODP_INTERNAL_MAX_THREADS,
   "ODP_BUFFER_HDR_T__ALLOCATOR__SIZE_ERROR");
 
 typedef struct odp_buffer_hdr_stride {
diff --git a/platform/linux-generic/include/odp_config_internal.h 
b/platform/linux-generic/include/odp_config_internal.h
new file mode 100644
index 000..4f20ff8
--- /dev/null
+++ b/platform/linux-generic/include/odp_config_internal.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Linux-generic platform internal configuration
+ */
+
+#ifndef ODP_CONFIG_INTERNAL_H_
+#define ODP_CONFIG_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Maximum number of threads
+ */
+#define _ODP_INTERNAL_MAX_THREADS  128
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/odp_thread.c 
b/platform/linux-generic/odp_thread.c
index a8ce133..2f39343 100644
--- a/platform/linux-generic/odp_thread.c
+++ b/platform/linux-generic/odp_thread.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,7 +32,7 @@ typedef struct {
 
 
 typedef struct {
-   thread_state_t thr[ODP_CONFIG_MAX_THREADS];
+   thread_state_t thr[_ODP_INTERNAL_MAX_THREADS];
union {
/* struct order must be kept in sync with schedule_types.h */
struct {
@@ -101,10 +102,10 @@ static int alloc_id(odp_thread_type_t type)
int thr;
odp_thrmask_t *all = _globals->all;
 
-   if (thread_globals

[lng-odp] [API-NEXT PATCH v3 1/3] api: init: added thread count params

2015-09-15 Thread Petri Savolainen
Added max number of worker/control threads as global init
parameters. Implementation can e.g. optimize it's per worker
thread resource reservation or configuration accordingly.

Maximum values are platform specific. These values come
typically from the user as command line arguments, etc.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/init.h | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/init.h b/include/odp/api/init.h
index 0683d8d..737ff6d 100644
--- a/include/odp/api/init.h
+++ b/include/odp/api/init.h
@@ -110,8 +110,18 @@ typedef void (*odp_abort_func_t)(void) ODP_NORETURN;
  * @note It is expected that all unassigned members are zero
  */
 typedef struct odp_init_t {
-   odp_log_func_t log_fn; /**< Replacement for the default log fn */
-   odp_abort_func_t abort_fn; /**< Replacement for the default abort fn */
+   /** Maximum number of worker threads the user will run concurrently.
+   Valid range is from 0 to platform specific maximum. Set both
+   num_worker and num_control to zero for default number of threads. */
+   int num_worker;
+   /** Maximum number of control threads the user will run concurrently.
+   Valid range is from 0 to platform specific maximum. Set both
+   num_worker and num_control to zero for default number of threads. */
+   int num_control;
+   /** Replacement for the default log fn */
+   odp_log_func_t log_fn;
+   /** Replacement for the default abort fn */
+   odp_abort_func_t abort_fn;
 } odp_init_t;
 
 /**
@@ -133,9 +143,10 @@ typedef struct odp_platform_init_t {
  * functions.
  *
  * @param params  Those parameters that are interpreted by the ODP API.
+ *Use NULL to set all parameters to their defaults.
  * @param platform_params Those parameters that are passed without
  *interpretation by the ODP API to the implementation.
- *
+ *Use NULL to set all parameters to their defaults.
  * @retval 0 on success
  * @retval <0 on failure
  *
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v3 2/3] api: thread: added thread count max

2015-09-15 Thread Petri Savolainen
Maximum thread count is needed for preparation to remove
ODP_CONFIG_MAX_THREADS. It can be used e.g. to allocate
resources per thread ID. Thread IDs range from 0 to
count_max - 1.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/thread.h| 14 --
 platform/linux-generic/odp_thread.c |  5 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/include/odp/api/thread.h b/include/odp/api/thread.h
index 89eae2b..3029342 100644
--- a/include/odp/api/thread.h
+++ b/include/odp/api/thread.h
@@ -54,7 +54,7 @@ typedef enum odp_thread_type_e {
  * Get thread identifier
  *
  * Returns the thread identifier of the current thread. Thread ids range from 0
- * to ODP_CONFIG_MAX_THREADS-1. The ODP thread id is assinged by
+ * to odp_thread_count_max() - 1. The ODP thread id is assigned by
  * odp_init_local() and freed by odp_term_local(). Thread id is unique within
  * the ODP instance.
  *
@@ -68,13 +68,23 @@ int odp_thread_id(void);
  * Returns the current ODP thread count. This is the number of active threads
  * running the ODP instance. Each odp_init_local() call increments and each
  * odp_term_local() call decrements the count. The count is always between 1 
and
- * ODP_CONFIG_MAX_THREADS.
+ * odp_thread_count_max().
  *
  * @return Current thread count
  */
 int odp_thread_count(void);
 
 /**
+ * Maximum thread count
+ *
+ * Returns the maximum thread count, which is a constant value and set in
+ * ODP initialization phase.
+ *
+ * @return Maximum thread count
+ */
+int odp_thread_count_max(void);
+
+/**
  * Thread type
  *
  * Returns the thread type of the current thread.
diff --git a/platform/linux-generic/odp_thread.c 
b/platform/linux-generic/odp_thread.c
index 770c64e..a8ce133 100644
--- a/platform/linux-generic/odp_thread.c
+++ b/platform/linux-generic/odp_thread.c
@@ -204,6 +204,11 @@ int odp_thread_count(void)
return thread_globals->num;
 }
 
+int odp_thread_count_max(void)
+{
+   return __ODP_CONFIG_MAX_THREADS;
+}
+
 odp_thread_type_t odp_thread_type(void)
 {
return this_thread->type;
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 1/3] api: init: added thread count params

2015-09-11 Thread Petri Savolainen
Added max number of worker/control threads as global init
parameters. Implementation can e.g. optimize it's per worker
thread resource reservation or configuration accordingly.

Maximum values are platform specific. These values come
typically from the user as command line arguments, etc.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/init.h | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/init.h b/include/odp/api/init.h
index 0683d8d..d327305 100644
--- a/include/odp/api/init.h
+++ b/include/odp/api/init.h
@@ -110,8 +110,16 @@ typedef void (*odp_abort_func_t)(void) ODP_NORETURN;
  * @note It is expected that all unassigned members are zero
  */
 typedef struct odp_init_t {
-   odp_log_func_t log_fn; /**< Replacement for the default log fn */
-   odp_abort_func_t abort_fn; /**< Replacement for the default abort fn */
+   /** Maximum number of worker threads the user will run concurrently.
+   Valid range is from 0 to platform specific maximum. */
+   int num_worker;
+   /** Maximum number of control threads the user will run concurrently.
+   Valid range is from 0 to platform specific maximum. */
+   int num_control;
+   /** Replacement for the default log fn */
+   odp_log_func_t log_fn;
+   /** Replacement for the default abort fn */
+   odp_abort_func_t abort_fn;
 } odp_init_t;
 
 /**
@@ -133,9 +141,10 @@ typedef struct odp_platform_init_t {
  * functions.
  *
  * @param params  Those parameters that are interpreted by the ODP API.
+ *Use NULL to set all parameters to their defaults.
  * @param platform_params Those parameters that are passed without
  *interpretation by the ODP API to the implementation.
- *
+ *Use NULL to set all parameters to their defaults.
  * @retval 0 on success
  * @retval <0 on failure
  *
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 3/3] api: config: removed ODP_CONFIG_MAX_THREADS

2015-09-11 Thread Petri Savolainen
New thread API call odp_thread_count_max() replaces the
preprocessor macro in the API. A macro is still used
internally.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/config.h   |  5 ---
 .../linux-generic/include/odp/plat/cpumask_types.h |  3 +-
 .../include/odp/plat/rwlock_recursive_types.h  |  4 +--
 .../linux-generic/include/odp_buffer_internal.h|  3 +-
 .../linux-generic/include/odp_config_internal.h| 29 
 platform/linux-generic/odp_thread.c|  9 ++---
 platform/linux-generic/odp_thrmask.c   |  4 +--
 test/performance/odp_pktio_perf.c  | 40 +++---
 test/validation/thread/thread.c|  2 +-
 9 files changed, 78 insertions(+), 21 deletions(-)
 create mode 100644 platform/linux-generic/include/odp_config_internal.h

diff --git a/include/odp/api/config.h b/include/odp/api/config.h
index 302eaf5..bf88be8 100644
--- a/include/odp/api/config.h
+++ b/include/odp/api/config.h
@@ -24,11 +24,6 @@ extern "C" {
  */
 
 /**
- * Maximum number of threads
- */
-#define ODP_CONFIG_MAX_THREADS  128
-
-/**
  * Maximum number of pools
  */
 #define ODP_CONFIG_POOLS16
diff --git a/platform/linux-generic/include/odp/plat/cpumask_types.h 
b/platform/linux-generic/include/odp/plat/cpumask_types.h
index 6fba832..d3bf988 100644
--- a/platform/linux-generic/include/odp/plat/cpumask_types.h
+++ b/platform/linux-generic/include/odp/plat/cpumask_types.h
@@ -23,11 +23,12 @@ extern "C" {
  */
 
 #include 
+#include 
 
 /**
  * Minimum size of output buffer for odp_cpumask_to_str()
  */
-#define ODP_CPUMASK_STR_SIZE ((ODP_CONFIG_MAX_THREADS + 3) / 4 + 3)
+#define ODP_CPUMASK_STR_SIZE ((__ODP_CONFIG_MAX_THREADS + 3) / 4 + 3)
 
 /**
  * CPU mask
diff --git a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h 
b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
index 9e220f5..0e20b40 100644
--- a/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
+++ b/platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
@@ -19,7 +19,7 @@ extern "C" {
 
 #include 
 #include 
-#include 
+#include 
 
 /**
  * @internal
@@ -29,7 +29,7 @@ struct odp_rwlock_recursive_s {
odp_rwlock_t lock;   /**< the lock */
int wr_owner;/**< write owner thread */
uint32_t wr_cnt; /**< write recursion count */
-   uint8_t  rd_cnt[ODP_CONFIG_MAX_THREADS]; /**< read recursion count */
+   uint8_t  rd_cnt[__ODP_CONFIG_MAX_THREADS]; /**< read recursion count */
 };
 
 /** @addtogroup odp_synchronizers
diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
b/platform/linux-generic/include/odp_buffer_internal.h
index 4cacca1..7671ea7 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -30,6 +30,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #define ODP_BITSIZE(x) \
((x) <= 2 ?  1 : \
@@ -143,7 +144,7 @@ struct odp_buffer_hdr_t {
 
 /** @internal Compile time assert that the
  * allocator field can handle any allocator id*/
-_ODP_STATIC_ASSERT(INT16_MAX >= ODP_CONFIG_MAX_THREADS,
+_ODP_STATIC_ASSERT(INT16_MAX >= __ODP_CONFIG_MAX_THREADS,
   "ODP_BUFFER_HDR_T__ALLOCATOR__SIZE_ERROR");
 
 typedef struct odp_buffer_hdr_stride {
diff --git a/platform/linux-generic/include/odp_config_internal.h 
b/platform/linux-generic/include/odp_config_internal.h
new file mode 100644
index 000..c60ec66
--- /dev/null
+++ b/platform/linux-generic/include/odp_config_internal.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Linux-generic platform internal configuration
+ */
+
+#ifndef ODP_INTERNAL_CONFIG_H_
+#define ODP_INTERNAL_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Maximum number of threads
+ */
+#define __ODP_CONFIG_MAX_THREADS  128
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/odp_thread.c 
b/platform/linux-generic/odp_thread.c
index a8ce133..8acf647 100644
--- a/platform/linux-generic/odp_thread.c
+++ b/platform/linux-generic/odp_thread.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,7 +32,7 @@ typedef struct {
 
 
 typedef struct {
-   thread_state_t thr[ODP_CONFIG_MAX_THREADS];
+   thread_state_t thr[__ODP_CONFIG_MAX_THREADS];
union {
/* struct order must be kept in sync with schedule_types.h */
struct {
@@ -101,10 +102,10 @@ static int alloc_id(odp_thread_type_t type)
int thr;
odp_thrmask_t *all = _globals->all;
 
-   if (thread_globals->num >= ODP_CONF

[lng-odp] [API-NEXT PATCH v3 2/2] api: rwlock_recursive: added recursive rwlock

2015-09-09 Thread Petri Savolainen
Added recursive read-write lock. It allows threads to
read lock or write lock the rwlock multiple times without
deadlocking. Mixing of read and write lock operations is
not supported.

ODP version of recursive rwlock enables porting legacy
applications, which use these kind of locks.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp.h  |  1 +
 include/odp/api/rwlock_recursive.h | 94 ++
 platform/linux-generic/Makefile.am |  4 +
 .../include/odp/plat/rwlock_recursive_types.h  | 49 +++
 .../linux-generic/include/odp/rwlock_recursive.h   | 28 +++
 platform/linux-generic/odp_rwlock_recursive.c  | 70 
 6 files changed, 246 insertions(+)
 create mode 100644 include/odp/api/rwlock_recursive.h
 create mode 100644 
platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
 create mode 100644 platform/linux-generic/include/odp/rwlock_recursive.h
 create mode 100644 platform/linux-generic/odp_rwlock_recursive.c

diff --git a/include/odp.h b/include/odp.h
index b47ab82..825c7e1 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -55,6 +55,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
new file mode 100644
index 000..4c7556a
--- /dev/null
+++ b/include/odp/api/rwlock_recursive.h
@@ -0,0 +1,94 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive read/write lock
+ */
+
+#ifndef ODP_API_RWLOCK_RECURSIVE_H_
+#define ODP_API_RWLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive rwlocks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
+ *
+ * A thread can read- or write-acquire a recursive read-write lock multiple
+ * times without a deadlock. To release the lock, the thread must unlock it
+ * the same number of times. Recursion is supported only for a pure series of
+ * read or write lock calls. Read and write lock calls must not be mixed when
+ * recursing.
+ *
+ * For example, these are supported...
+ *   * read_lock(); read_lock(); read_unlock(); read_unlock();
+ *   * write_lock(); write_lock(); write_unlock(); write_unlock();
+ *
+ * ... but this is not supported.
+ *   * read_lock(); write_lock(); write_unlock(); read_unlock();
+ */
+
+/**
+ * Initialize recursive rwlock
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_init(odp_rwlock_recursive_t *lock);
+
+/**
+ * Acquire recursive rwlock for reading
+ *
+ * This call allows the thread to acquire the same lock multiple times for
+ * reading. The lock cannot be acquired for writing while holding it
+ * for reading.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Release recursive rwlock after reading
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_read_unlock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Acquire recursive rwlock for writing
+ *
+ * This call allows the thread to acquire the same lock multiple times for
+ * writing. The lock cannot be acquired for reading while holding it
+ * for writing.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Release recursive rwlock after writing
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 96e4f9e..0e10848 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -35,6 +35,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/queue.h \
  $(srcdir)/include/odp/random.h \
  $(srcdir)/include/odp/rwlock.h \
+ $(srcdir)/include/odp/rwlock_recursive.h \
  $(srcdir)/include/odp/schedule.h \
  $(srcdir)/include/odp/schedule_types.h \
  $(srcdir)/include/odp/shared_memory.h \
@@ -65,6 +66,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/pool_types.h \
  $(srcdir)/include/odp/plat/queue_types.h \
  $(srcdir)/include/odp/plat/rwlock_types.h \
+ $(srcdir)/include/odp/plat/rwlock_recursive_types.h \
  $(srcdir)/include/odp/plat/schedule_types.h \
  $(srcdir)/include/odp/plat/shared_memory_types.h \
  $(srcdir)/include/odp/plat/spinlock_types.h \
@@ -100,6 +102,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdi

[lng-odp] [API-NEXT PATCH v3 1/2] api: spinlock_recursive: added recursive spinlock

2015-09-09 Thread Petri Savolainen
Applications can use recursive spinlocks to avoid deadlock from
single thread acquiring the same lock multiple times. Recursive
locks are used in legacy applications. ODP version of recursive
spinlock enable porting of those applications.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp.h  |  1 +
 include/odp/api/spinlock_recursive.h   | 82 ++
 platform/linux-generic/Makefile.am |  4 ++
 .../include/odp/plat/spinlock_recursive_types.h| 47 +
 .../linux-generic/include/odp/spinlock_recursive.h | 28 
 platform/linux-generic/odp_spinlock_recursive.c| 70 ++
 6 files changed, 232 insertions(+)
 create mode 100644 include/odp/api/spinlock_recursive.h
 create mode 100644 
platform/linux-generic/include/odp/plat/spinlock_recursive_types.h
 create mode 100644 platform/linux-generic/include/odp/spinlock_recursive.h
 create mode 100644 platform/linux-generic/odp_spinlock_recursive.c

diff --git a/include/odp.h b/include/odp.h
index fe1dc74..b47ab82 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -54,6 +54,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/spinlock_recursive.h 
b/include/odp/api/spinlock_recursive.h
new file mode 100644
index 000..46b6be7
--- /dev/null
+++ b/include/odp/api/spinlock_recursive.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive spinlock
+ */
+
+#ifndef ODP_API_SPINLOCK_RECURSIVE_H_
+#define ODP_API_SPINLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive spinlocks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_spinlock_recursive_t
+ * Recursive spinlock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times.
+ */
+
+/**
+ * Initialize recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_init(odp_spinlock_recursive_t *lock);
+
+/**
+ * Acquire recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_lock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Try to acquire recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock acquired
+ * @retval 0 lock not acquired
+ */
+int odp_spinlock_recursive_trylock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Release recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_unlock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Check if recursive spinlock is locked.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock is locked
+ * @retval 0 lock is not locked
+ */
+int odp_spinlock_recursive_is_locked(odp_spinlock_recursive_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 4c79730..96e4f9e 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -39,6 +39,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/schedule_types.h \
  $(srcdir)/include/odp/shared_memory.h \
  $(srcdir)/include/odp/spinlock.h \
+ $(srcdir)/include/odp/spinlock_recursive.h \
  $(srcdir)/include/odp/std_types.h \
  $(srcdir)/include/odp/sync.h \
  $(srcdir)/include/odp/system_info.h \
@@ -67,6 +68,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/schedule_types.h \
  $(srcdir)/include/odp/plat/shared_memory_types.h \
  $(srcdir)/include/odp/plat/spinlock_types.h \
+ $(srcdir)/include/odp/plat/spinlock_recursive_types.h \
  $(srcdir)/include/odp/plat/strong_types.h \
  $(srcdir)/include/odp/plat/thrmask_types.h \
  $(srcdir)/include/odp/plat/ticketlock_types.h \
@@ -102,6 +104,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/schedule_types.h \
  $(top_srcdir)/include/odp/api/shared_memory.h \
  $(top_srcdir)/include/odp/api/spinlock.h \
+ $(top_srcdir)/include/odp/api/spinlock_recursive.h \
  $(top_srcdir)/include/odp/api/std_types.h \
  $(top_srcdir)/include/odp/api/sync.h \
  $(top_srcdir)/include/odp/api/system_info.h \
@@ -159,6 +162,7 @@ __LIB__libodp_la_SOURCES = \
   odp_schedule.c \
   odp_shared_memory.c \
   odp_spinlock.c \
+  odp_spinlock_recursive.c \
  

[lng-odp] [API-NEXT PATCH v2 0/5] CPU cycle count API

2015-09-08 Thread Petri Savolainen
Raw CPU cycle count API is needed for measuring CPU cycle consumption. This can
replace many of the odp_time_cycles() when time API moves to real time from 
CPU cycles. 

v2:
  * corrected comparison in diff
  * code style changes in patch 5

Petri Savolainen (5):
  api: cpu: added cpu cycle count API
  linux-generic: cpu: created arch depedent cpu_cycles files
  linux-generic: cpu: rename time_cycles to cpu_cycles
  linux-generic: cpu: implementation for cycle count API
  performance: sched: update scheduling test to use cycle counts

 include/odp/api/cpu.h  |  52 
 platform/linux-generic/Makefile.am |   9 +-
 platform/linux-generic/arch/linux/odp_cpu_cycles.c |  48 +++
 .../linux-generic/arch/linux/odp_time_cycles.c |  38 --
 .../linux-generic/arch/mips64/odp_cpu_cycles.c |  31 +
 .../linux-generic/arch/mips64/odp_time_cycles.c|  21 ---
 platform/linux-generic/arch/x86/odp_cpu_cycles.c   |  33 +
 platform/linux-generic/arch/x86/odp_time_cycles.c  |  23 
 platform/linux-generic/odp_cpu.c   |  16 +++
 platform/linux-generic/odp_time.c  |   6 +
 test/performance/odp_scheduling.c  | 147 ++---
 11 files changed, 259 insertions(+), 165 deletions(-)
 create mode 100644 platform/linux-generic/arch/linux/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/linux/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/mips64/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/mips64/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/x86/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/x86/odp_time_cycles.c
 create mode 100644 platform/linux-generic/odp_cpu.c

-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 1/5] api: cpu: added cpu cycle count API

2015-09-08 Thread Petri Savolainen
Raw CPU cycle counts can be used to measure performance
in CPU cycles. These functions will replace some usage of
odp_time_cycles() of odp_time_diff_cycles().

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/cpu.h | 52 +++
 1 file changed, 52 insertions(+)

diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h
index c389093..50a7e3d 100644
--- a/include/odp/api/cpu.h
+++ b/include/odp/api/cpu.h
@@ -18,6 +18,8 @@
 extern "C" {
 #endif
 
+#include 
+
 /** @defgroup odp_cpu ODP CPU
  *  @{
  */
@@ -44,6 +46,56 @@ int odp_cpu_id(void);
 int odp_cpu_count(void);
 
 /**
+ * Current CPU cycle count
+ *
+ * Return current CPU cycle count. Cycle count may not be reset at ODP init
+ * and thus may wrap back to zero between two calls. Use odp_cpu_cycles_max()
+ * to read the maximum count value after which it wraps. Cycle count frequency
+ * follows the CPU frequency and thus may change at any time. The count may
+ * advance in steps larger than one. Use odp_cpu_cycles_resolution() to read
+ * the step size.
+ *
+ * @note Do not use CPU count for time measurements since the frequency may
+ * vary.
+ *
+ * @return Current CPU cycle count
+ */
+uint64_t odp_cpu_cycles(void);
+
+/**
+ * CPU cycle count difference
+ *
+ * Calculate difference between cycle counts c1 and c2. Parameter c1 must be 
the
+ * first cycle count sample and c2 the second. The function handles correctly
+ * single cycle count wrap between c1 and c2.
+ *
+ * @param c1First cycle count
+ * @param c2Second cycle count
+ *
+ * @return CPU cycles from c1 to c2
+ */
+uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2);
+
+/**
+ * Maximum CPU cycle count
+ *
+ * Maximum CPU cycle count value before it wraps back to zero.
+ *
+ * @return Maximum CPU cycle count value
+ */
+uint64_t odp_cpu_cycles_max(void);
+
+/**
+ * Resolution of CPU cycle count
+ *
+ * CPU cycle count may advance in steps larger than one. This function returns
+ * resolution of odp_cpu_cycles() in CPU cycles.
+ *
+ * @return CPU cycle count resolution in CPU cycles
+ */
+uint64_t odp_cpu_cycles_resolution(void);
+
+/**
  * @}
  */
 
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles

2015-09-08 Thread Petri Savolainen
Implemented odp_cpu_cycles() be renaming odp_time_cycles()
implementation. Time implementation uses odp_cpu_cycles
temporarely.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/arch/linux/odp_cpu_cycles.c  | 4 ++--
 platform/linux-generic/arch/mips64/odp_cpu_cycles.c | 4 ++--
 platform/linux-generic/arch/x86/odp_cpu_cycles.c| 4 ++--
 platform/linux-generic/odp_time.c   | 6 ++
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c 
b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
index 256ad7c..c312f3d 100644
--- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
@@ -9,14 +9,14 @@
 #include 
 #include 
 
-#include 
+#include 
 #include 
 #include 
 #include 
 
 #define GIGA 10
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
struct timespec time;
uint64_t sec, ns, hz, cycles;
diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c 
b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
index 4fb790b..acd7058 100644
--- a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include 
+#include 
 #include 
 #include 
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
#define CVMX_TMP_STR2(x) #x
diff --git a/platform/linux-generic/arch/x86/odp_cpu_cycles.c 
b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
index a111561..20ad44a 100644
--- a/platform/linux-generic/arch/x86/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
@@ -3,9 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include 
+#include 
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
union {
uint64_t tsc_64;
diff --git a/platform/linux-generic/odp_time.c 
b/platform/linux-generic/odp_time.c
index a08833d..6e69e53 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -9,9 +9,15 @@
 #include 
 #include 
 #include 
+#include 
 
 #define GIGA 10
 
+uint64_t odp_time_cycles(void)
+{
+   return odp_cpu_cycles();
+}
+
 uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2)
 {
if (odp_likely(t2 > t1))
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH v2 4/5] linux-generic: cpu: implementation for cycle count API

2015-09-08 Thread Petri Savolainen
Added implementation for CPU cycle diff, max and resolution.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/Makefile.am  |  1 +
 platform/linux-generic/arch/linux/odp_cpu_cycles.c  | 10 ++
 platform/linux-generic/arch/mips64/odp_cpu_cycles.c | 10 ++
 platform/linux-generic/arch/x86/odp_cpu_cycles.c| 10 ++
 platform/linux-generic/odp_cpu.c| 16 
 5 files changed, 47 insertions(+)
 create mode 100644 platform/linux-generic/odp_cpu.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index c2a4778..43f8de8 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -139,6 +139,7 @@ __LIB__libodp_la_SOURCES = \
   odp_barrier.c \
   odp_buffer.c \
   odp_classification.c \
+  odp_cpu.c \
   odp_cpumask.c \
   odp_cpumask_task.c \
   odp_crypto.c \
diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c 
b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
index c312f3d..37a4d94 100644
--- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
@@ -36,3 +36,13 @@ uint64_t odp_cpu_cycles(void)
 
return cycles;
 }
+
+uint64_t odp_cpu_cycles_max(void)
+{
+   return UINT64_MAX;
+}
+
+uint64_t odp_cpu_cycles_resolution(void)
+{
+   return 1;
+}
diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c 
b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
index acd7058..a20a313 100644
--- a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
@@ -19,3 +19,13 @@ uint64_t odp_cpu_cycles(void)
 
return cycle;
 }
+
+uint64_t odp_cpu_cycles_max(void)
+{
+   return UINT64_MAX;
+}
+
+uint64_t odp_cpu_cycles_resolution(void)
+{
+   return 1;
+}
diff --git a/platform/linux-generic/arch/x86/odp_cpu_cycles.c 
b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
index 20ad44a..1c5c0ec 100644
--- a/platform/linux-generic/arch/x86/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
@@ -21,3 +21,13 @@ uint64_t odp_cpu_cycles(void)
 
return tsc.tsc_64;
 }
+
+uint64_t odp_cpu_cycles_max(void)
+{
+   return UINT64_MAX;
+}
+
+uint64_t odp_cpu_cycles_resolution(void)
+{
+   return 1;
+}
diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c
new file mode 100644
index 000..45a79db
--- /dev/null
+++ b/platform/linux-generic/odp_cpu.c
@@ -0,0 +1,16 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include 
+#include 
+
+uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2)
+{
+   if (odp_likely(c2 >= c1))
+   return c2 - c1;
+
+   return c2 + (odp_cpu_cycles_max() - c1);
+}
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 2/5] linux-generic: cpu: created arch depedent cpu_cycles files

2015-09-07 Thread Petri Savolainen
Renamed time_cycles files to cpu_cycles, since those files
implement cpu cycle counter read needed by cpu API but not
needed by new time API.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/Makefile.am |  8 ++---
 platform/linux-generic/arch/linux/odp_cpu_cycles.c | 38 ++
 .../linux-generic/arch/linux/odp_time_cycles.c | 38 --
 .../linux-generic/arch/mips64/odp_cpu_cycles.c | 21 
 .../linux-generic/arch/mips64/odp_time_cycles.c| 21 
 platform/linux-generic/arch/x86/odp_cpu_cycles.c   | 23 +
 platform/linux-generic/arch/x86/odp_time_cycles.c  | 23 -
 7 files changed, 86 insertions(+), 86 deletions(-)
 create mode 100644 platform/linux-generic/arch/linux/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/linux/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/mips64/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/mips64/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/x86/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/x86/odp_time_cycles.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 4c79730..c2a4778 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -167,9 +167,9 @@ __LIB__libodp_la_SOURCES = \
   odp_timer.c \
   odp_version.c \
   odp_weak.c \
-  arch/@ARCH@/odp_time_cycles.c
+  arch/@ARCH@/odp_cpu_cycles.c
 
 EXTRA_DIST = \
-arch/linux/odp_time_cycles.c \
-arch/mips64/odp_time_cycles.c \
-arch/x86/odp_time_cycles.c
+arch/linux/odp_cpu_cycles.c \
+arch/mips64/odp_cpu_cycles.c \
+arch/x86/odp_cpu_cycles.c
diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c 
b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
new file mode 100644
index 000..256ad7c
--- /dev/null
+++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
@@ -0,0 +1,38 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define _POSIX_C_SOURCE 199309L
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define GIGA 10
+
+uint64_t odp_time_cycles(void)
+{
+   struct timespec time;
+   uint64_t sec, ns, hz, cycles;
+   int ret;
+
+   ret = clock_gettime(CLOCK_MONOTONIC_RAW, );
+
+   if (ret != 0)
+   ODP_ABORT("clock_gettime failed\n");
+
+   hz  = odp_sys_cpu_hz();
+   sec = (uint64_t)time.tv_sec;
+   ns  = (uint64_t)time.tv_nsec;
+
+   cycles  = sec * hz;
+   cycles += (ns * hz) / GIGA;
+
+   return cycles;
+}
diff --git a/platform/linux-generic/arch/linux/odp_time_cycles.c 
b/platform/linux-generic/arch/linux/odp_time_cycles.c
deleted file mode 100644
index 4dc0764..000
--- a/platform/linux-generic/arch/linux/odp_time_cycles.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2015, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#define _POSIX_C_SOURCE 199309L
-
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-
-#define GIGA 10
-
-uint64_t odp_time_cycles(void)
-{
-   struct timespec time;
-   uint64_t sec, ns, hz, cycles;
-   int ret;
-
-   ret = clock_gettime(CLOCK_MONOTONIC_RAW, );
-
-   if (ret != 0)
-   ODP_ABORT("clock_gettime failed\n");
-
-   hz  = odp_sys_cpu_hz();
-   sec = (uint64_t) time.tv_sec;
-   ns  = (uint64_t) time.tv_nsec;
-
-   cycles  = sec * hz;
-   cycles += (ns * hz) / GIGA;
-
-   return cycles;
-}
diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c 
b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
new file mode 100644
index 000..4fb790b
--- /dev/null
+++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
@@ -0,0 +1,21 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include 
+#include 
+#include 
+
+uint64_t odp_time_cycles(void)
+{
+   #define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
+   #define CVMX_TMP_STR2(x) #x
+   uint64_t cycle;
+
+   __asm__ __volatile__ ("rdhwr %[rt],$" CVMX_TMP_STR(31) :
+  [rt] "=d" (cycle) : : "memory");
+
+   return cycle;
+}
diff --git a/platform/linux-generic/arch/mips64/odp_time_cycles.c 
b/platform/linux-generic/arch/mips64/odp_time_cycles.c
deleted file mode 100644
index 4fb790b..000
--- a/platform/linux-generic/arch/mips64/odp_time_cycles.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (c) 2015, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:

[lng-odp] [API-NEXT PATCH 3/5] linux-generic: cpu: rename time_cycles to cpu_cycles

2015-09-07 Thread Petri Savolainen
Implemented odp_cpu_cycles() be renaming odp_time_cycles()
implementation. Time implementation uses odp_cpu_cycles
temporarely.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/arch/linux/odp_cpu_cycles.c  | 4 ++--
 platform/linux-generic/arch/mips64/odp_cpu_cycles.c | 4 ++--
 platform/linux-generic/arch/x86/odp_cpu_cycles.c| 4 ++--
 platform/linux-generic/odp_time.c   | 6 ++
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c 
b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
index 256ad7c..c312f3d 100644
--- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c
@@ -9,14 +9,14 @@
 #include 
 #include 
 
-#include 
+#include 
 #include 
 #include 
 #include 
 
 #define GIGA 10
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
struct timespec time;
uint64_t sec, ns, hz, cycles;
diff --git a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c 
b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
index 4fb790b..acd7058 100644
--- a/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/mips64/odp_cpu_cycles.c
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include 
+#include 
 #include 
 #include 
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
#define CVMX_TMP_STR2(x) #x
diff --git a/platform/linux-generic/arch/x86/odp_cpu_cycles.c 
b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
index a111561..20ad44a 100644
--- a/platform/linux-generic/arch/x86/odp_cpu_cycles.c
+++ b/platform/linux-generic/arch/x86/odp_cpu_cycles.c
@@ -3,9 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include 
+#include 
 
-uint64_t odp_time_cycles(void)
+uint64_t odp_cpu_cycles(void)
 {
union {
uint64_t tsc_64;
diff --git a/platform/linux-generic/odp_time.c 
b/platform/linux-generic/odp_time.c
index a08833d..6e69e53 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -9,9 +9,15 @@
 #include 
 #include 
 #include 
+#include 
 
 #define GIGA 10
 
+uint64_t odp_time_cycles(void)
+{
+   return odp_cpu_cycles();
+}
+
 uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2)
 {
if (odp_likely(t2 > t1))
-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 0/5] CPU cycle count API

2015-09-07 Thread Petri Savolainen
Raw CPU cycle count API is needed for measuring CPU cycle consumption. This can
replace many of the odp_time_cycles() when time API moves to real time from 
CPU cycles. 

Petri Savolainen (5):
  api: cpu: added cpu cycle count API
  linux-generic: cpu: created arch depedent cpu_cycles files
  linux-generic: cpu: rename time_cycles to cpu_cycles
  linux-generic: cpu: implementation for cycle count API
  performance: sched: update scheduling test to use cycle counts

 include/odp/api/cpu.h  |  52 
 platform/linux-generic/Makefile.am |   9 +-
 platform/linux-generic/arch/linux/odp_cpu_cycles.c |  48 
 .../linux-generic/arch/linux/odp_time_cycles.c |  38 --
 .../linux-generic/arch/mips64/odp_cpu_cycles.c |  31 +
 .../linux-generic/arch/mips64/odp_time_cycles.c|  21 
 platform/linux-generic/arch/x86/odp_cpu_cycles.c   |  33 ++
 platform/linux-generic/arch/x86/odp_time_cycles.c  |  23 
 platform/linux-generic/odp_cpu.c   |  16 +++
 platform/linux-generic/odp_time.c  |   6 +
 test/performance/odp_scheduling.c  | 132 +
 11 files changed, 248 insertions(+), 161 deletions(-)
 create mode 100644 platform/linux-generic/arch/linux/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/linux/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/mips64/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/mips64/odp_time_cycles.c
 create mode 100644 platform/linux-generic/arch/x86/odp_cpu_cycles.c
 delete mode 100644 platform/linux-generic/arch/x86/odp_time_cycles.c
 create mode 100644 platform/linux-generic/odp_cpu.c

-- 
2.5.1

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 1/2] api: spinlock_recursive: added recursive spinlock

2015-08-31 Thread Petri Savolainen
Applications can use recursive spinlocks to avoid deadlock from
single thread acquiring the same lock multiple times. Recursive
locks are used in legacy applications. ODP version of recursive
spinlock enable porting of those applications.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp.h  |  1 +
 include/odp/api/spinlock_recursive.h   | 82 ++
 platform/linux-generic/Makefile.am |  4 ++
 .../include/odp/plat/spinlock_recursive_types.h| 46 
 .../linux-generic/include/odp/spinlock_recursive.h | 28 
 platform/linux-generic/odp_spinlock_recursive.c| 70 ++
 6 files changed, 231 insertions(+)
 create mode 100644 include/odp/api/spinlock_recursive.h
 create mode 100644 
platform/linux-generic/include/odp/plat/spinlock_recursive_types.h
 create mode 100644 platform/linux-generic/include/odp/spinlock_recursive.h
 create mode 100644 platform/linux-generic/odp_spinlock_recursive.c

diff --git a/include/odp.h b/include/odp.h
index fe1dc74..b47ab82 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -54,6 +54,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/spinlock_recursive.h 
b/include/odp/api/spinlock_recursive.h
new file mode 100644
index 000..46b6be7
--- /dev/null
+++ b/include/odp/api/spinlock_recursive.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive spinlock
+ */
+
+#ifndef ODP_API_SPINLOCK_RECURSIVE_H_
+#define ODP_API_SPINLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive spinlocks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_spinlock_recursive_t
+ * Recursive spinlock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times.
+ */
+
+/**
+ * Initialize recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_init(odp_spinlock_recursive_t *lock);
+
+/**
+ * Acquire recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_lock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Try to acquire recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock acquired
+ * @retval 0 lock not acquired
+ */
+int odp_spinlock_recursive_trylock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Release recursive spinlock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_spinlock_recursive_unlock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Check if recursive spinlock is locked.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock is locked
+ * @retval 0 lock is not locked
+ */
+int odp_spinlock_recursive_is_locked(odp_spinlock_recursive_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index f2c081a..6dfdf76 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -39,6 +39,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/schedule_types.h \
  $(srcdir)/include/odp/shared_memory.h \
  $(srcdir)/include/odp/spinlock.h \
+ $(srcdir)/include/odp/spinlock_recursive.h \
  $(srcdir)/include/odp/std_types.h \
  $(srcdir)/include/odp/sync.h \
  $(srcdir)/include/odp/system_info.h \
@@ -67,6 +68,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/schedule_types.h \
  $(srcdir)/include/odp/plat/shared_memory_types.h \
  $(srcdir)/include/odp/plat/spinlock_types.h \
+ $(srcdir)/include/odp/plat/spinlock_recursive_types.h \
  $(srcdir)/include/odp/plat/strong_types.h \
  $(srcdir)/include/odp/plat/thrmask_types.h \
  $(srcdir)/include/odp/plat/ticketlock_types.h \
@@ -102,6 +104,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/schedule_types.h \
  $(top_srcdir)/include/odp/api/shared_memory.h \
  $(top_srcdir)/include/odp/api/spinlock.h \
+ $(top_srcdir)/include/odp/api/spinlock_recursive.h \
  $(top_srcdir)/include/odp/api/std_types.h \
  $(top_srcdir)/include/odp/api/sync.h \
  $(top_srcdir)/include/odp/api/system_info.h \
@@ -158,6 +161,7 @@ __LIB__libodp_la_SOURCES = \
   odp_schedule.c \
   odp_shared_memory.c \
   odp_spinlock.c \
+  odp_spinlock_recursive.c \
  

[lng-odp] [API-NEXT PATCH 2/2] api: rwlock_recursive: added recursive rwlock

2015-08-31 Thread Petri Savolainen
Added recursive read-write lock. It allows threads to
read lock or write lock the rwlock multiple times without
deadlocking. Mixing read and write lock operations is
not supported.

ODP version of recursive rwlock enables porting legacy
applications, which use these kind of locks.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp.h  |  1 +
 include/odp/api/rwlock_recursive.h | 86 ++
 platform/linux-generic/Makefile.am |  4 +
 .../include/odp/plat/rwlock_recursive_types.h  | 49 
 .../linux-generic/include/odp/rwlock_recursive.h   | 28 +++
 platform/linux-generic/odp_rwlock_recursive.c  | 70 ++
 6 files changed, 238 insertions(+)
 create mode 100644 include/odp/api/rwlock_recursive.h
 create mode 100644 
platform/linux-generic/include/odp/plat/rwlock_recursive_types.h
 create mode 100644 platform/linux-generic/include/odp/rwlock_recursive.h
 create mode 100644 platform/linux-generic/odp_rwlock_recursive.c

diff --git a/include/odp.h b/include/odp.h
index b47ab82..825c7e1 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -55,6 +55,7 @@ extern "C" {
 #include 
 #include 
 #include 
+#include 
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/rwlock_recursive.h 
b/include/odp/api/rwlock_recursive.h
new file mode 100644
index 000..ce2df58
--- /dev/null
+++ b/include/odp/api/rwlock_recursive.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive read/write lock
+ */
+
+#ifndef ODP_API_RWLOCK_RECURSIVE_H_
+#define ODP_API_RWLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive rwlocks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_rwlock_recursive_t
+ * Recursive rwlock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times. Recursion is
+ * limited to a series of read lock or write lock calls. Mixing read and write
+ * lock calls in recursion results undefined behaviour.
+ */
+
+/**
+ * Initialize recursive rwlock
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_init(odp_rwlock_recursive_t *lock);
+
+/**
+ * Acquire recursive rwlock for reading
+ *
+ * This call allows the thread to acquire the same lock multiple times for
+ * reading. The lock cannot be acquired for writing while holding it
+ * for reading.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Release recursive rwlock after reading
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_read_unlock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Acquire recursive rwlock for writing
+ *
+ * This call allows the thread to acquire the same lock multiple times for
+ * writing. The lock cannot be acquired for reading while holding it
+ * for writing.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *lock);
+
+/**
+ * Release recursive rwlock after writing
+ *
+ * @param lockPointer to a lock
+ */
+void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 6dfdf76..5a6b984 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -35,6 +35,7 @@ odpinclude_HEADERS = \
  $(srcdir)/include/odp/queue.h \
  $(srcdir)/include/odp/random.h \
  $(srcdir)/include/odp/rwlock.h \
+ $(srcdir)/include/odp/rwlock_recursive.h \
  $(srcdir)/include/odp/schedule.h \
  $(srcdir)/include/odp/schedule_types.h \
  $(srcdir)/include/odp/shared_memory.h \
@@ -65,6 +66,7 @@ odpplatinclude_HEADERS = \
  $(srcdir)/include/odp/plat/pool_types.h \
  $(srcdir)/include/odp/plat/queue_types.h \
  $(srcdir)/include/odp/plat/rwlock_types.h \
+ $(srcdir)/include/odp/plat/rwlock_recursive_types.h \
  $(srcdir)/include/odp/plat/schedule_types.h \
  $(srcdir)/include/odp/plat/shared_memory_types.h \
  $(srcdir)/include/odp/plat/spinlock_types.h \
@@ -100,6 +102,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/queue.h \
  $(top_srcdir)/include/odp/api/random.h \
  $(top_srcdir)/include/odp/api/rwlock.h \
+ $(top_srcdir)/include/odp/api/rwlock_recursive.h \
  $(top_srcdir)/include/odp/api/schedule.h \
  $(top_srcdir)/includ

[lng-odp] [API-NEXT PATCH v2] api: reclock: added recursive lock

2015-07-03 Thread Petri Savolainen
Applications can use recursive locks to avoid deadlock from single
thread acquiring the same lock multiple times. Recursive locks
are commonly used by legacy applications.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp.h  |  1 +
 include/odp/api/reclock.h  | 82 ++
 platform/linux-generic/Makefile.am |  4 ++
 .../linux-generic/include/odp/plat/reclock_types.h | 46 
 platform/linux-generic/include/odp/reclock.h   | 28 
 platform/linux-generic/odp_reclock.c   | 70 ++
 6 files changed, 231 insertions(+)
 create mode 100644 include/odp/api/reclock.h
 create mode 100644 platform/linux-generic/include/odp/plat/reclock_types.h
 create mode 100644 platform/linux-generic/include/odp/reclock.h
 create mode 100644 platform/linux-generic/odp_reclock.c

diff --git a/include/odp.h b/include/odp.h
index fe1dc74..9acd1c4 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -54,6 +54,7 @@ extern C {
 #include odp/random.h
 #include odp/errno.h
 #include odp/thrmask.h
+#include odp/reclock.h
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/reclock.h b/include/odp/api/reclock.h
new file mode 100644
index 000..06ea702
--- /dev/null
+++ b/include/odp/api/reclock.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive lock
+ */
+
+#ifndef ODP_API_RECLOCK_H_
+#define ODP_API_RECLOCK_H_
+
+#ifdef __cplusplus
+extern C {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive locks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_reclock_t
+ * Recursive lock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times.
+ */
+
+/**
+ * Initialize recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_init(odp_reclock_t *lock);
+
+/**
+ * Acquire recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_lock(odp_reclock_t *lock);
+
+/**
+ * Try to acquire recursive lock.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock acquired
+ * @retval 0 lock not acquired
+ */
+int odp_reclock_trylock(odp_reclock_t *lock);
+
+/**
+ * Release recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_unlock(odp_reclock_t *lock);
+
+/**
+ * Check if recursive lock is locked.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock is locked
+ * @retval 0 lock is not locked
+ */
+int odp_reclock_is_locked(odp_reclock_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 765db34..b6fd611 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -32,6 +32,7 @@ odpinclude_HEADERS = \
  $(top_srcdir)/platform/linux-generic/include/odp/pool.h \
  $(top_srcdir)/platform/linux-generic/include/odp/queue.h \
  $(top_srcdir)/platform/linux-generic/include/odp/random.h \
+ $(top_srcdir)/platform/linux-generic/include/odp/reclock.h \
  $(top_srcdir)/platform/linux-generic/include/odp/rwlock.h \
  $(top_srcdir)/platform/linux-generic/include/odp/schedule.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/shared_memory.h \
@@ -60,6 +61,7 @@ odpplatinclude_HEADERS = \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/packet_io_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/pool_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/queue_types.h \
+ 
$(top_srcdir)/platform/linux-generic/include/odp/plat/reclock_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/rwlock_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/schedule_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/shared_memory_types.h \
@@ -94,6 +96,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/pool.h \
  $(top_srcdir)/include/odp/api/queue.h \
  $(top_srcdir)/include/odp/api/random.h \
+ $(top_srcdir)/include/odp/api/reclock.h \
  $(top_srcdir)/include/odp/api/rwlock.h \
  $(top_srcdir)/include/odp/api/schedule.h \
  $(top_srcdir)/include/odp/api/shared_memory.h \
@@ -162,6 +165,7 @@ __LIB__libodp_la_SOURCES = \
   odp_pool.c \
   odp_queue.c \
   ../../helper/ring.c \
+  odp_reclock.c \
   odp_rwlock.c

[lng-odp] [API-NEXT PATCH] api: reclock: added recursive lock

2015-07-03 Thread Petri Savolainen
Applications can use recursive locks to avoid deadlock from single
thread acquiring the same lock multiple times. Recursive locks
are commonly used by legacy applications.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp.h  |  1 +
 include/odp/api/reclock.h  | 82 ++
 platform/linux-generic/Makefile.am |  4 ++
 .../linux-generic/include/odp/plat/reclock_types.h | 46 
 platform/linux-generic/include/odp/reclock.h   | 28 
 platform/linux-generic/odp_reclock.c   | 68 ++
 6 files changed, 229 insertions(+)
 create mode 100644 include/odp/api/reclock.h
 create mode 100644 platform/linux-generic/include/odp/plat/reclock_types.h
 create mode 100644 platform/linux-generic/include/odp/reclock.h
 create mode 100644 platform/linux-generic/odp_reclock.c

diff --git a/include/odp.h b/include/odp.h
index fe1dc74..9acd1c4 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -54,6 +54,7 @@ extern C {
 #include odp/random.h
 #include odp/errno.h
 #include odp/thrmask.h
+#include odp/reclock.h
 
 #ifdef __cplusplus
 }
diff --git a/include/odp/api/reclock.h b/include/odp/api/reclock.h
new file mode 100644
index 000..06ea702
--- /dev/null
+++ b/include/odp/api/reclock.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive lock
+ */
+
+#ifndef ODP_API_RECLOCK_H_
+#define ODP_API_RECLOCK_H_
+
+#ifdef __cplusplus
+extern C {
+#endif
+
+/** @addtogroup odp_synchronizers
+ *  Operations on recursive locks.
+ *  @{
+ */
+
+/**
+ * @typedef odp_reclock_t
+ * Recursive lock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times.
+ */
+
+/**
+ * Initialize recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_init(odp_reclock_t *lock);
+
+/**
+ * Acquire recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_lock(odp_reclock_t *lock);
+
+/**
+ * Try to acquire recursive lock.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock acquired
+ * @retval 0 lock not acquired
+ */
+int odp_reclock_trylock(odp_reclock_t *lock);
+
+/**
+ * Release recursive lock.
+ *
+ * @param lockPointer to a lock
+ */
+void odp_reclock_unlock(odp_reclock_t *lock);
+
+/**
+ * Check if recursive lock is locked.
+ *
+ * @param lockPointer to a lock
+ *
+ * @retval 1 lock is locked
+ * @retval 0 lock is not locked
+ */
+int odp_reclock_is_locked(odp_reclock_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 765db34..b6fd611 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -32,6 +32,7 @@ odpinclude_HEADERS = \
  $(top_srcdir)/platform/linux-generic/include/odp/pool.h \
  $(top_srcdir)/platform/linux-generic/include/odp/queue.h \
  $(top_srcdir)/platform/linux-generic/include/odp/random.h \
+ $(top_srcdir)/platform/linux-generic/include/odp/reclock.h \
  $(top_srcdir)/platform/linux-generic/include/odp/rwlock.h \
  $(top_srcdir)/platform/linux-generic/include/odp/schedule.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/shared_memory.h \
@@ -60,6 +61,7 @@ odpplatinclude_HEADERS = \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/packet_io_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/pool_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/queue_types.h \
+ 
$(top_srcdir)/platform/linux-generic/include/odp/plat/reclock_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/rwlock_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/schedule_types.h \
  
$(top_srcdir)/platform/linux-generic/include/odp/plat/shared_memory_types.h \
@@ -94,6 +96,7 @@ odpapiinclude_HEADERS = \
  $(top_srcdir)/include/odp/api/pool.h \
  $(top_srcdir)/include/odp/api/queue.h \
  $(top_srcdir)/include/odp/api/random.h \
+ $(top_srcdir)/include/odp/api/reclock.h \
  $(top_srcdir)/include/odp/api/rwlock.h \
  $(top_srcdir)/include/odp/api/schedule.h \
  $(top_srcdir)/include/odp/api/shared_memory.h \
@@ -162,6 +165,7 @@ __LIB__libodp_la_SOURCES = \
   odp_pool.c \
   odp_queue.c \
   ../../helper/ring.c \
+  odp_reclock.c \
   odp_rwlock.c

[lng-odp] [API-NEXT PATCH 1/2] api: pktio: rename pktio_input_mode enum

2015-07-03 Thread Petri Savolainen
We have decided to standardize enum naming to typedef _t,
renamed the enum according to that.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/packet_io.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 3d42ee0..bc6011e 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -48,14 +48,14 @@ extern C {
 /**
  * Packet input mode
  */
-enum odp_pktio_input_mode {
+typedef enum odp_pktio_input_mode_t {
/** Application polls packet input directly with odp_pktio_recv() */
ODP_PKTIN_MODE_RECV = 0,
/** Packet input through scheduled queues */
ODP_PKTIN_MODE_SCHED,
/** Application polls packet input queues */
ODP_PKTIN_MODE_POLL
-};
+} odp_pktio_input_mode_t;
 
 /**
  * Packet IO parameters
@@ -65,7 +65,7 @@ enum odp_pktio_input_mode {
  */
 typedef struct odp_pktio_param_t {
/** Packet input mode */
-   enum odp_pktio_input_mode in_mode;
+   odp_pktio_input_mode_t in_mode;
 } odp_pktio_param_t;
 
 /**
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 2/2] api: pktio: added output mode

2015-07-03 Thread Petri Savolainen
Added pktio parameter to select packet output mode. Left out
default output queue option, since it may disappear when TM
is integrated. Can be added later if still needed.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/packet_io.h | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index bc6011e..bade895 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -58,14 +58,26 @@ typedef enum odp_pktio_input_mode_t {
 } odp_pktio_input_mode_t;
 
 /**
+ * Packet output mode
+ */
+typedef enum odp_pktio_output_mode_t {
+   /** Direct packet output on the interface with odp_pktio_send() */
+   ODP_PKTOUT_MODE_SEND = 0,
+   /** Packet output through traffic manager API */
+   ODP_PKTOUT_MODE_TM
+} odp_pktio_output_mode_t;
+
+/**
  * Packet IO parameters
  *
- * In minimum, user must select the input mode. Use 0 for defaults. Initialize
- * entire struct with zero to maintain API compatibility.
+ * In minimum, user must select input and output modes. Use 0 for defaults.
+ * Initialize entire struct with zero to maintain API compatibility.
  */
 typedef struct odp_pktio_param_t {
/** Packet input mode */
odp_pktio_input_mode_t in_mode;
+   /** Packet output mode */
+   odp_pktio_output_mode_t out_mode;
 } odp_pktio_param_t;
 
 /**
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 01/11] api: sched: removed SYNC_DEFAULT

2015-07-02 Thread Petri Savolainen
User should pick a synchronisation method and use SYNC_NONE if
does not need synchronization.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/queue.h   | 5 -
 platform/linux-generic/include/odp/plat/queue_types.h | 2 --
 platform/linux-generic/odp_queue.c| 2 +-
 3 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/include/odp/api/queue.h b/include/odp/api/queue.h
index f7a0777..bdda845 100644
--- a/include/odp/api/queue.h
+++ b/include/odp/api/queue.h
@@ -138,11 +138,6 @@ extern C {
  */
 
 /**
- * @def ODP_SCHED_SYNC_DEFAULT
- * Default queue synchronisation
- */
-
-/**
  * @typedef odp_schedule_group_t
  * ODP schedule core group
  */
diff --git a/platform/linux-generic/include/odp/plat/queue_types.h 
b/platform/linux-generic/include/odp/plat/queue_types.h
index 1cecc90..9f398a1 100644
--- a/platform/linux-generic/include/odp/plat/queue_types.h
+++ b/platform/linux-generic/include/odp/plat/queue_types.h
@@ -58,8 +58,6 @@ typedef int odp_schedule_sync_t;
 #define ODP_SCHED_SYNC_ATOMIC   1
 #define ODP_SCHED_SYNC_ORDERED  2
 
-#define ODP_SCHED_SYNC_DEFAULT  ODP_SCHED_SYNC_ATOMIC
-
 typedef int odp_schedule_group_t;
 
 #define ODP_SCHED_GROUP_ALL 0
diff --git a/platform/linux-generic/odp_queue.c 
b/platform/linux-generic/odp_queue.c
index 4a0465b..7f48176 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -61,7 +61,7 @@ static void queue_init(queue_entry_t *queue, const char *name,
/* Defaults */
memset(queue-s.param, 0, sizeof(odp_queue_param_t));
queue-s.param.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
-   queue-s.param.sched.sync  = ODP_SCHED_SYNC_DEFAULT;
+   queue-s.param.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
queue-s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
}
 
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 02/11] api: sched: clarify usage of PRIO_DEFAULT

2015-07-02 Thread Petri Savolainen
Default prio is used when priority scheduling is not important.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/queue.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/odp/api/queue.h b/include/odp/api/queue.h
index bdda845..10bac16 100644
--- a/include/odp/api/queue.h
+++ b/include/odp/api/queue.h
@@ -92,10 +92,11 @@ extern C {
 
 /**
  * @def ODP_SCHED_PRIO_DEFAULT
- * Default scheduling priority
+ * Default scheduling priority. User does not care about the selected priority
+ * level - throughput, load balacing and synchronization features are more
+ * important than priority scheduling.
  */
 
-
 /**
  * @typedef odp_schedule_sync_t
  * ODP schedule synchronisation
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 10/11] api: sched: added schedule prefetch

2015-07-02 Thread Petri Savolainen
This is a hint to the scheduler for prefetching more events.
Performance is improved when scheduler may prefetch events in
parallel to application finishing processing of previous events.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/schedule.h | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/include/odp/api/schedule.h b/include/odp/api/schedule.h
index 316f27b..4db8d5b 100644
--- a/include/odp/api/schedule.h
+++ b/include/odp/api/schedule.h
@@ -159,6 +159,20 @@ void odp_schedule_release_atomic(void);
 void odp_schedule_release_ordered(void);
 
 /**
+ * Prefetch events for next schedule call
+ *
+ * Hint the scheduler that application is about to finish processing the 
current
+ * event(s) and will soon request more events. The scheduling context status is
+ * not affect. The call does not guarantee that the next schedule call will
+ * return any number of events. It may improve system performance, since the
+ * scheduler may prefetch the next (batch of) event(s) in parallel to
+ * application processing the current event(s).
+ *
+ * @param num Number of events to prefetch
+ */
+void odp_schedule_prefetch(int num);
+
+/**
  * Number of scheduling priorities
  *
  * @return Number of scheduling priorities
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


[lng-odp] [API-NEXT PATCH 09/11] api: sched: added release ordered

2015-07-02 Thread Petri Savolainen
For performance optimization user can allow ordered context
release as soon as the last enqueue which needs ordering support
is finished.

Signed-off-by: Petri Savolainen petri.savolai...@nokia.com
---
 include/odp/api/schedule.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/include/odp/api/schedule.h b/include/odp/api/schedule.h
index ca4bc28..316f27b 100644
--- a/include/odp/api/schedule.h
+++ b/include/odp/api/schedule.h
@@ -142,6 +142,23 @@ void odp_schedule_resume(void);
 void odp_schedule_release_atomic(void);
 
 /**
+ * Release the current ordered context
+ *
+ * This call is valid only for source queues with ordered synchronization. It
+ * hints the scheduler that the user has done all enqueues that need to 
maintain
+ * event order in the current ordered context. The scheduler is allowed to
+ * release the ordered context of this thread and avoid reordering any 
following
+ * enqueues. However, the context may be still held until the next
+ * odp_schedule() or odp_schedule_multi() call - this call allows but does not
+ * force the scheduler to release the context early.
+ *
+ * Early ordered context release may increase parallelism and thus system
+ * performance, since scheduler may start reordering events sooner than the 
next
+ * schedule call.
+ */
+void odp_schedule_release_ordered(void);
+
+/**
  * Number of scheduling priorities
  *
  * @return Number of scheduling priorities
-- 
2.4.5

___
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp


<    3   4   5   6   7   8   9   10   11   >