Sample test code that measures speed of ODP crypto operations.
  o measures operation elapsed, cpu time, and throughput
  o supports multiple algorithms
  o supports multiple payload sizes
  o support synch and async crypto operation modes

Signed-off-by: Victor Kamensky <[email protected]>
---
 configure.ac                |   1 +
 example/Makefile.am         |   2 +-
 example/cspeed/Makefile.am  |   6 +
 example/cspeed/odp_cspeed.c | 918 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 926 insertions(+), 1 deletion(-)
 create mode 100644 example/cspeed/Makefile.am
 create mode 100644 example/cspeed/odp_cspeed.c

diff --git a/configure.ac b/configure.ac
index b1fc859..0592334 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,6 +153,7 @@ AC_CONFIG_FILES([Makefile
                 platform/linux-keystone2/Makefile
                 platform/linux-dpdk/Makefile
                 example/Makefile
+                example/cspeed/Makefile
                 example/generator/Makefile
                 example/l2fwd/Makefile
                 example/odp_example/Makefile
diff --git a/example/Makefile.am b/example/Makefile.am
index 01a3305..d7fb80a 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -1 +1 @@
-SUBDIRS = generator l2fwd odp_example packet packet_netmap timer
+SUBDIRS = cspeed generator l2fwd odp_example packet packet_netmap timer
diff --git a/example/cspeed/Makefile.am b/example/cspeed/Makefile.am
new file mode 100644
index 0000000..9b0b2ee
--- /dev/null
+++ b/example/cspeed/Makefile.am
@@ -0,0 +1,6 @@
+include $(top_srcdir)/example/Makefile.inc
+
+bin_PROGRAMS = odp_cspeed
+odp_cspeed_LDFLAGS = $(AM_LDFLAGS) -static
+
+dist_odp_cspeed_SOURCES = odp_cspeed.c
diff --git a/example/cspeed/odp_cspeed.c b/example/cspeed/odp_cspeed.c
new file mode 100644
index 0000000..8e59180
--- /dev/null
+++ b/example/cspeed/odp_cspeed.c
@@ -0,0 +1,918 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif /* _GNU_SOURCE */
+
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <odp.h>
+
+
+#define cspeed_error(fmt, ...) \
+       fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
+               __LINE__, __func__, ##__VA_ARGS__)
+
+
+/** @def SHM_PKT_POOL_SIZE
+ * @brief Size of the shared memory block
+ */
+#define SHM_PKT_POOL_SIZE      (512*2048*2)
+
+
+/** @def SHM_PKT_POOL_BUF_SIZE
+ * @brief Buffer size of the packet pool buffer
+ */
+#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
+
+
+static uint8_t test_iv[8] = "01234567";
+
+
+static uint8_t test_key16[16] = { 0x01, 0x02, 0x03, 0x04, 0x05,
+                                 0x06, 0x07, 0x08, 0x09, 0x0a,
+                                 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+                                 0x10,
+};
+
+
+static uint8_t test_key24[24] = { 0x01, 0x02, 0x03, 0x04, 0x05,
+                                 0x06, 0x07, 0x08, 0x09, 0x0a,
+                                 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+                                 0x10, 0x11, 0x12, 0x13, 0x14,
+                                 0x15, 0x16, 0x17, 0x18
+};
+
+/**
+ * Structure that holds template for session create call
+ * for different algorithms supported by test
+ */
+typedef struct {
+       const char *name;                     /**< Algorithm name */
+       odp_crypto_session_params_t session;  /**< Prefilled crypto session 
params */
+       unsigned int hash_adjust;             /**< Size of hash */
+} cspeed_alg_config_t;
+
+
+/**
+ * Parsed command line cspeed arguments. Describes test configuration.
+ */
+typedef struct {
+       /**
+        * If non zero prints content of packets. Enabled by -d or
+        * --debug option.
+        */
+       int debug_packets;
+
+       /**
+        * If non zero Try to run crypto operation in place. Note some
+        * implementation may not support such mode. Enabled by -n or
+        * --inplace option.
+        */
+       int in_place;
+
+       /**
+        * If non zeor output of previous operation taken as input for
+        * next encrypt operations. Enabled by -r or --reuse option.
+        */
+       int reuse_packet;
+
+       /**
+        * Maxiumum number of outstanding encryption requests. Note code
+        * poll for results over queue and if nothing is available it can
+        * submit more encryption requests up to maximum number specified by
+        * this option. Specified through -f or --flight option.
+        */
+       int in_flight;
+
+       /**
+        * Number of core to run on. Currently is not used.
+        */
+       int core_count;
+
+       /**
+        * Number of iteration to repeat crypto operation to get good
+        * average number. Specified through -i or --terations option.
+        * Default is 10000.
+        */
+       int iteration_count;
+
+       /**
+        * Maxium sessions. Currently is not used.
+        */
+       int max_sessions;
+
+       /**
+        * Payload size to test. If 0 set of predefined payload sizes
+        * is tested. Specified through -p or --payload option.
+        */
+       int payload_size;
+
+       /**
+        * Pointer to selected algorithm to test. If NULL all available
+        * alogorthims are tested. Name of algorithm is passed through
+        * -a or --algorithm option.
+        */
+       cspeed_alg_config_t *alg_config;
+} cspeed_args_t;
+
+
+/*
+ * Helper structure that holds averages for test of one algorithm
+ * for given payload size.
+ */
+typedef struct {
+       /**
+        * Elapsed time for one crypto operation.
+        */
+       double elapsed;
+
+       /**
+        * CPU time spent pre one crypto operation by whole process
+        * i.e include current and all other threads in process.
+        * It is filled with 'getrusage(RUSAGE_SELF, ...)' call.
+        */
+       double rusage_self;
+
+       /**
+        * CPU time spent per one crypto operation by current thread
+        * only. It is filled with 'getrusage(RUSAGE_THREAD, ...)'
+        * call.
+        */
+       double rusage_thread;
+} cspeed_run_result_t;
+
+
+/**
+ * Structure holds one snap to misc times of current process.
+ */
+typedef struct {
+       struct timeval tv;       /**< Elapsed time */
+       struct rusage ru_self;   /**< Rusage value for whole process */
+       struct rusage ru_thread; /**< Rusage value for current thread */
+} time_record_t;
+
+
+static void parse_args(int argc, char *argv[], cspeed_args_t *cargs);
+static void usage(char *progname);
+
+/**
+ * Set of predefined payloads. Make sure that maximum payload
+ * size is not bigger than SHM_PKT_POOL_BUF_SIZE. May relax when
+ * implementation start support segmented buffers/packets.
+ */
+static unsigned int payloads[] = {
+       16,
+       64,
+       256,
+       1024,
+       8192,
+       16384
+};
+
+/**
+ * Set of known algorithms to test
+ */
+static cspeed_alg_config_t algs_config[] = {
+       {
+               .name = "3des-cbs-null",
+               .session = {
+                       .cipher_alg = ODP_CIPHER_ALG_3DES_CBC,
+                       .cipher_key = {
+                               .data = test_key24,
+                               .length = sizeof(test_key24)
+                       },
+                       .iv = {
+                               .data = test_iv,
+                               .length = 8,
+                       },
+                       .auth_alg = ODP_AUTH_ALG_NULL
+               },
+       },
+       {
+               .name = "3des-cbs-hmac-md5-96",
+               .session = {
+                       .cipher_alg = ODP_CIPHER_ALG_3DES_CBC,
+                       .cipher_key = {
+                               .data = test_key24,
+                               .length = sizeof(test_key24)
+                       },
+                       .iv = {
+                               .data = test_iv,
+                               .length = 8,
+                       },
+                       .auth_alg = ODP_AUTH_ALG_MD5_96,
+                       .auth_key = {
+                               .data = test_key16,
+                               .length = sizeof(test_key16)
+                       }
+               },
+               .hash_adjust = 12
+       },
+       {
+               .name ="null-hmac-md5-96",
+               .session = {
+                       .cipher_alg = ODP_CIPHER_ALG_NULL,
+                       .auth_alg = ODP_AUTH_ALG_MD5_96,
+                       .auth_key = {
+                               .data = test_key16,
+                               .length = sizeof(test_key16)
+                       }
+               },
+               .hash_adjust = 12
+       },
+};
+
+
+/**
+ * Find corresponding config for given name. Returns NULL
+ * if config for given name is not found.
+ */
+static cspeed_alg_config_t *
+find_config_by_name(const char *name) {
+       unsigned int i;
+       cspeed_alg_config_t *ret = NULL;
+
+       for (i = 0; i < sizeof(algs_config)/sizeof(cspeed_alg_config_t); i++) {
+               if (strcmp(algs_config[i].name, name) == 0) {
+                       ret = algs_config+i;
+                       break;
+               }
+       }
+       return ret;
+}
+
+
+/**
+ * Helper function that prints list of algorithms that this
+ * test understands.
+ */
+static void
+print_config_names(const char *prefix) {
+       unsigned int i;
+
+       for (i = 0; i < sizeof(algs_config)/sizeof(cspeed_alg_config_t); i++) {
+               printf("%s %s\n", prefix, algs_config[i].name);
+       }
+}
+
+
+/**
+ * Snap current time values and put them into 'rec'.
+ */
+static void
+fill_time_record(time_record_t *rec)
+{
+       gettimeofday(&rec->tv, NULL);
+       getrusage(RUSAGE_SELF, &rec->ru_self);
+       getrusage(RUSAGE_THREAD, &rec->ru_thread);
+}
+
+
+/**
+ * Calculated CPU time difference for given two rusage structures.
+ * Note it adds user space and system time together.
+ */
+static unsigned long long
+get_rusage_diff (struct rusage *start, struct rusage *end)
+{
+       unsigned long long rusage_diff;
+       unsigned long long rusage_start;
+       unsigned long long rusage_end;
+
+       rusage_start = (start->ru_utime.tv_sec * 1000000) +
+                      (start->ru_utime.tv_usec);
+       rusage_start += (start->ru_stime.tv_sec * 1000000) +
+                       (start->ru_stime.tv_usec);
+
+       rusage_end = (end->ru_utime.tv_sec * 1000000) +
+                    (end->ru_utime.tv_usec);
+       rusage_end += (end->ru_stime.tv_sec * 1000000) +
+                     (end->ru_stime.tv_usec);
+
+       rusage_diff = rusage_end - rusage_start;
+
+       return rusage_diff;
+}
+
+
+/**
+ * Get diff for RUSAGE_SELF (whole process) between two time snap
+ * records.
+ */
+static unsigned long long
+get_rusage_self_diff (time_record_t *start, time_record_t *end)
+{
+       return get_rusage_diff(&start->ru_self, &end->ru_self);
+}
+
+
+/**
+ * Get diff for RUSAGE_THREAD (current thread only) between two
+ * time snap records.
+ */
+static unsigned long long
+get_rusage_thread_diff (time_record_t *start, time_record_t *end)
+{
+       return get_rusage_diff(&start->ru_thread, &end->ru_thread);
+}
+
+
+/**
+ * Get diff of elapsed time between two time snap records
+ */
+static unsigned long long
+get_elapsed_usec (time_record_t *start, time_record_t *end)
+{
+       unsigned long long s;
+       unsigned long long e;
+
+       s = (start->tv.tv_sec * 1000000) +
+           (start->tv.tv_usec);
+       e = (end->tv.tv_sec * 1000000) +
+           (end->tv.tv_usec);
+
+       return e - s;
+}
+
+#define REPORT_HEADER      "\n%30.30s %15s %15s %15s %15s %15s %15s\n"
+#define REPORT_LINE        "%30.30s %15d %15d %15.3f %15.3f %15.3f %15d\n"
+
+
+/**
+ * Print header line for our report.
+ */
+static void
+print_result_header(void)
+{
+       printf(REPORT_HEADER,
+              "algorithm", "avg over #", "payload (bytes)", "elapsed (us)",
+              "rusg self (us)", "rusg thrd (us)", "throughput (Kb)");
+}
+
+
+/**
+ * Print one line of our report.
+ */
+static void
+print_result(cspeed_args_t *cargs,
+            unsigned int payload_size,
+            cspeed_alg_config_t *config,
+            cspeed_run_result_t *result)
+{
+       unsigned int throughput;
+       throughput = (1000000.0 / result->elapsed) * payload_size / 1024;
+       printf(REPORT_LINE,
+              config->name, cargs->iteration_count, payload_size,
+              result->elapsed, result->rusage_self, result->rusage_thread,
+              throughput);
+}
+
+
+/**
+ * Print piece of memory with given size.
+ */
+static void
+print_memory (const char *msg,
+             const unsigned char *ptr,
+             unsigned int len)
+{
+       unsigned i, j;
+       char c;
+       char line[81];
+       char *p;
+
+       if (msg) {
+               printf("\n%s (bytes size = %d)", msg, len);
+       }
+
+       for (i=0; i < len; i+=16) {
+               p = line;
+               sprintf(p, "\n%04x   ", i); p +=8;
+
+               for (j = 0; j < 16; j++) {
+                       if (i+j == len) break;
+
+                       sprintf(p, " %02x", (ptr)[i+j]); p += 3;
+               }
+
+               for (; j < 16; j++) { sprintf(p, "   "); p += 3; }
+
+               sprintf(p, "   "); p += 3;
+
+               for (j = 0; j < 16; j++) {
+                       if (i+j == len) break;
+                       c = (ptr)[i+j];
+                       *p++ = (' ' <= c && c <= '~') ? c : '.';
+               }
+
+               *p = '\0';
+               printf("%s", line);
+       }
+       printf("\n");
+}
+
+
+/**
+ * Create ODP crypto session for given config.
+ */
+static int
+create_session_from_config(odp_crypto_session_t *session,
+                          cspeed_alg_config_t *config)
+{
+       odp_crypto_session_params_t params;
+       enum odp_crypto_ses_create_err ses_create_rc;
+       odp_buffer_pool_t pkt_pool;
+       odp_queue_t out_queue;
+
+       int rc = 0;
+
+       memcpy(&params, &config->session, sizeof(odp_crypto_session_params_t));
+       params.op = ODP_CRYPTO_OP_ENCODE;
+       params.pref_mode   = ODP_CRYPTO_SYNC;
+
+       if (!rc) {
+               /* Lookup the packet pool */
+               pkt_pool = odp_buffer_pool_lookup("packet_pool");
+               if (pkt_pool == ODP_BUFFER_POOL_INVALID) {
+                       cspeed_error("Error: 'packet_pool' buffer pull not 
found\n");
+                       rc = -1;
+               } else {
+                       params.output_pool = pkt_pool;
+               }
+       }
+
+
+       if (!rc) {
+               out_queue = odp_queue_lookup("crypto-out");
+               if (out_queue == ODP_QUEUE_INVALID) {
+                       cspeed_error("Error: 'crypto-out' queue not found\n");
+                       rc = -1;
+               } else {
+                       params.compl_queue = out_queue;
+               }
+               /*
+                * Uncomment below for generic implementation if inline
+                * encryption is desired. Note ks2 implementation cannot
+                * deal with that.
+                */
+               /* params.compl_queue = ODP_QUEUE_INVALID; */
+       }
+
+       if (!rc) {
+               /*
+                * Prefered synchronous session create for now, but it could be
+                * ignored by implementation
+                */
+               if (odp_crypto_session_create(&params, session,
+                                             &ses_create_rc)) {
+                       cspeed_error("Error: ODP crypto session create 
failed.\n");
+                       rc = -1;
+               }
+       }
+
+
+       return rc;
+}
+
+
+/**
+ * Run measurement iterations for given config and payload size.
+ * Result of run returned in 'result' out parameter.
+ */
+static int
+run_measure_one(cspeed_args_t *cargs,
+               cspeed_alg_config_t *config,
+               odp_crypto_session_t *session,
+               unsigned int payload_size,
+               cspeed_run_result_t *result)
+{
+       odp_crypto_op_params_t params;
+
+       odp_buffer_pool_t pkt_pool;
+       odp_queue_t out_queue;
+       odp_packet_t pkt;
+       odp_buffer_t buf;
+
+       bool posted = 0;
+       int rc = 0;
+
+
+       if (!rc) {
+               /* Lookup the packet pool */
+               pkt_pool = odp_buffer_pool_lookup("packet_pool");
+               if (pkt_pool == ODP_BUFFER_POOL_INVALID) {
+                       cspeed_error("Error: pkt_pool not found\n");
+                       rc = -1;
+               }
+       }
+
+       if (!rc) {
+               out_queue = odp_queue_lookup("crypto-out");
+               if (out_queue == ODP_QUEUE_INVALID) {
+                       cspeed_error("Error: 'crypto-out' queue not found\n");
+                       rc = -1;
+               }
+       }
+
+       if (!rc) {
+               buf = odp_buffer_alloc(pkt_pool);
+               if (buf == ODP_BUFFER_INVALID) {
+                       cspeed_error("Error: failed to allocate buffer\n");
+                       rc = -1;
+               } else {
+                       pkt = odp_packet_from_buffer(buf);
+                       odp_packet_set_len(pkt, payload_size);
+                               {
+                                       void *mem = odp_packet_start(pkt);
+                                       memset(mem, 1, payload_size);
+                               }
+               }
+       }
+
+       if (!rc) {
+               time_record_t start, end;
+               int packets_sent = 0;
+               int packets_received = 0;
+
+               /* Initialize parameters block */
+               memset(&params, 0, sizeof(params));
+               params.session = *session;
+               params.cipher_range.offset = 0;
+               params.cipher_range.length = payload_size;
+               /*
+                * Uncomment following line if hash itself have
+                * to be encrypted. Note ks2 cannot do that
+                */
+               /* params.cipher_range.length += config->hash_adjust; */
+               params.auth_range.offset = 0;
+               params.auth_range.length = payload_size;
+               params.hash_result_offset = payload_size;
+
+               if (cargs->reuse_packet) {
+                       params.pkt = pkt;
+                       params.out_pkt = cargs->in_place ? pkt :
+                                        ODP_PACKET_INVALID;
+               }
+
+               fill_time_record(&start);
+
+               while ((packets_sent < cargs->iteration_count) ||
+                      (packets_received <  cargs->iteration_count)) {
+                       void *mem;
+
+                       if ((packets_sent < cargs->iteration_count) &&
+                           (packets_sent - packets_received < 
cargs->in_flight)) {
+
+
+                               if (!cargs->reuse_packet) {
+                                       /*
+                                        * For in place test we use just one 
statically allocated
+                                        * buffer. For now in place test we 
have to allocate and
+                                        * initialize packet every time. Note 
we leaked one
+                                        * packet here.
+                                        */
+                                       if (!cargs->in_place) {
+                                               buf = 
odp_buffer_alloc(pkt_pool);
+                                               if (buf == ODP_BUFFER_INVALID) {
+                                                       cspeed_error("Error: 
failed to allocate buffer\n");
+                                                       rc = -1;
+                                               } else {
+                                                       pkt = 
odp_packet_from_buffer(buf);
+                                                       odp_packet_set_len(pkt, 
payload_size);
+                                                       {
+                                                               void *mem =
+                                                                       
odp_packet_start(pkt);
+                                                               memset(mem, 1, 
payload_size);
+                                                       }
+                                               }
+                                       }
+
+                                       params.pkt = pkt;
+                                       params.out_pkt = cargs->in_place ? pkt :
+                                                        ODP_PACKET_INVALID;
+                               }
+
+
+                               if (cargs->debug_packets) {
+                                       mem = odp_packet_start(params.pkt);
+                                       print_memory("Packet before 
encryption:",
+                                                    mem, payload_size);
+                               }
+
+                               rc = odp_crypto_operation(&params, &posted,
+                                                         
odp_buffer_from_packet(pkt));
+                               if (rc) {
+                                       cspeed_error("Error: failed 
odp_crypto_operation: rc = %d\n", rc);
+                               } else {
+                                       packets_sent++;
+                               }
+                       }
+
+                       if (!posted) {
+                               if (cargs->debug_packets) {
+                                       mem = odp_packet_start(params.out_pkt);
+                                       print_memory("Imediately encrypted 
packet",
+                                                    mem, payload_size + 
config->hash_adjust);
+                               }
+                               if (!cargs->in_place) {
+                                       if (cargs->reuse_packet) {
+                                               params.pkt = params.out_pkt;
+                                               params.out_pkt = 
ODP_PACKET_INVALID;
+                                       } else {
+                                               odp_buffer_free(params.out_pkt);
+                                       }
+                               }
+                       } else {
+                               odp_buffer_t completion;
+                               odp_packet_t out_pkt;
+
+                               completion = odp_queue_deq(out_queue);
+
+                               while (completion != ODP_BUFFER_INVALID) {
+                                       out_pkt = 
odp_crypto_get_operation_compl_packet(completion);
+
+                                       if (cargs->debug_packets) {
+                                               mem = odp_packet_start(out_pkt);
+                                               print_memory("Receieved 
encrypted packet",
+                                                            mem, payload_size 
+ config->hash_adjust);
+                                       }
+                                       if (!cargs->in_place) {
+                                               if (cargs->reuse_packet) {
+                                                       params.pkt = out_pkt;
+                                                       params.out_pkt = 
ODP_PACKET_INVALID;
+                                               } else {
+                                                       
odp_buffer_free(out_pkt);
+                                               }
+                                       }
+                                       packets_received++;
+
+                                       completion = odp_queue_deq(out_queue);
+                               };
+
+                       }
+               }
+
+               fill_time_record(&end);
+
+               {
+                       double count;
+
+                       count = get_elapsed_usec(&start, &end);
+                       result->elapsed = count /
+                                         cargs->iteration_count;
+
+                       count = get_rusage_self_diff(&start, &end);
+                       result->rusage_self = count /
+                                             cargs->iteration_count;
+
+                       count = get_rusage_thread_diff(&start, &end);
+                       result->rusage_thread = count /
+                                               cargs->iteration_count;
+               }
+       }
+       return rc;
+}
+
+
+/**
+ * Process one algorithm. Note if paload size is specicified it is
+ * only one run. Or iterate over set of predefined payloads.
+ */
+static int
+run_measure_one_config(cspeed_args_t *cargs,
+                      cspeed_alg_config_t *config)
+{
+       cspeed_run_result_t result;
+       odp_crypto_session_t session;
+       int rc = 0;
+
+       if (create_session_from_config(&session, config)) {
+               rc = -1;
+       }
+
+       if (!rc) {
+               if (cargs->payload_size) {
+                       rc = run_measure_one(cargs, config, &session,
+                                            cargs->payload_size, &result);
+                       if (!rc){
+                               print_result_header();
+                               print_result(cargs, cargs->payload_size,
+                                            config, &result);
+                       }
+               } else {
+                       unsigned int i;
+
+                       print_result_header();
+                       for (i = 0;
+                            i < sizeof(payloads)/sizeof(unsigned int);
+                            i++) {
+                               rc = run_measure_one(cargs, config, &session,
+                                                    payloads[i], &result);
+                               if(rc) {
+                                       break;
+                               } else {
+                                       print_result(cargs, payloads[i],
+                                                    config, &result);
+                               }
+                       }
+               }
+       }
+
+
+       // destroy session
+       if (session != ODP_CRYPTO_SESSION_INVALID) {
+               odp_crypto_session_destroy(session);
+       }
+       return rc;
+}
+
+
+int main(int argc, char *argv[])
+{
+       int thr_id;
+       cspeed_args_t cargs;
+       odp_buffer_pool_t pool;
+       odp_queue_t out_queue;
+       void *pool_base;
+
+       /* Init ODP before calling anything else */
+       if (odp_init_global()) {
+               cspeed_error("Error: ODP global init failed.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       /* Parse and store the application arguments */
+       parse_args(argc, argv, &cargs);
+
+       /* Init this thread */
+       thr_id = odp_thread_create(0);
+       odp_init_local(thr_id);
+
+       /* Create packet pool */
+       pool_base = odp_shm_reserve("shm_packet_pool",
+                                   SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE);
+       if (pool_base == NULL) {
+               cspeed_error("Error: packet pool mem alloc failed.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       pool = odp_buffer_pool_create("packet_pool", pool_base,
+                                     SHM_PKT_POOL_SIZE,
+                                     SHM_PKT_POOL_BUF_SIZE,
+                                     ODP_CACHE_LINE_SIZE,
+                                     ODP_BUFFER_TYPE_PACKET);
+       if (pool == ODP_BUFFER_POOL_INVALID) {
+               cspeed_error("Error: packet pool create failed.\n");
+               exit(EXIT_FAILURE);
+       }
+       /* odp_buffer_pool_print(pool); */
+
+       out_queue = odp_queue_create("crypto-out",ODP_QUEUE_TYPE_POLL, NULL);
+       if (out_queue == ODP_QUEUE_INVALID) {
+               cspeed_error("Can't create out crypto queue\n");
+               exit(EXIT_FAILURE);
+       }
+
+       if (cargs.alg_config) {
+               run_measure_one_config(&cargs, cargs.alg_config);
+       } else {
+               unsigned int i;
+               for (i = 0;
+                    i < sizeof(algs_config)/sizeof(cspeed_alg_config_t);
+                    i++) {
+                       run_measure_one_config(&cargs, algs_config + i);
+               }
+       }
+
+       return 0;
+}
+
+
+static void parse_args(int argc, char *argv[], cspeed_args_t *cargs)
+{
+       int opt;
+       int long_index;
+       static struct option longopts[] = {
+               {"algorithm", optional_argument, NULL, 'a'},
+               {"count", optional_argument, NULL, 'c'},
+               {"debug",  no_argument, NULL, 'd'},
+               {"flight", optional_argument, NULL, 'f'},
+               {"help", no_argument, NULL, 'h'},               /* return 'h' */
+               {"iterations", optional_argument, NULL, 'i'},
+               {"inplace", no_argument, NULL, 'n'},
+               {"payload", optional_argument, NULL, 'p'},
+               {"sessions", optional_argument, NULL, 'm'},
+               {"reuse", no_argument, NULL, 'r'},
+               {NULL, 0, NULL, 0}
+       };
+
+       cargs->in_place = 0;
+       cargs->in_flight = 1;
+       cargs->debug_packets = 0;
+       cargs->core_count = 1;
+       cargs->iteration_count = 10000;
+       cargs->payload_size = 0;
+       cargs->alg_config = NULL;
+
+       while (1) {
+               opt = getopt_long(argc, argv, "+a:c:df:hi:m:np:r",
+                                 longopts, &long_index);
+
+               if (opt == -1)
+                       break;  /* No more options */
+
+               switch (opt) {
+               case 'a':
+                       cargs->alg_config = find_config_by_name(optarg);
+                       if (!cargs->alg_config) {
+                               printf("cannot test crypto '%s' 
configuration\n", optarg);
+                               usage(argv[0]);
+                               exit(-1);
+                       }
+               case 'c':
+                       cargs->core_count = atoi(optarg);
+                       break;
+               case 'd':
+                       cargs->debug_packets = 1;
+                       break;
+               case 'i':
+                       cargs->iteration_count = atoi(optarg);
+                       break;
+               case 'f':
+                       cargs->in_flight = atoi(optarg);
+                       break;
+               case 'h':
+                       usage(argv[0]);
+                       exit(EXIT_SUCCESS);
+                       break;
+               case 'm':
+                       cargs->max_sessions = atoi(optarg);
+                       break;
+               case 'n':
+                       cargs->in_place = 1;
+                       break;
+               case 'p':
+                       cargs->payload_size = atoi(optarg);
+                       break;
+               case 'r':
+                       cargs->reuse_packet = 1;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       optind = 1;             /* reset 'extern optind' from the getopt lib */
+
+       if ((cargs->in_flight > 1) && cargs->reuse_packet) {
+               printf("-f (in flight > 1) and -r (reuse packet) options are 
not compatible\n");
+               usage(argv[0]);
+               exit(-1);
+       }
+
+       if ((cargs->in_flight > 1) && cargs->in_place) {
+                printf("-f (in flight > 1) and -n (in place) options are not 
compatible\n");
+               usage(argv[0]);
+               exit(-1);
+       }
+
+}
+
+
+/**
+ * Prinf usage information
+ */
+static void usage(char *progname)
+{
+       printf("\n"
+              "Usage: %s OPTIONS\n"
+              "  E.g. %s -i 100000\n"
+              "\n"
+              "OpenDataPlane crypto speed measure.\n"
+              "Optional OPTIONS\n"
+              "  -a, --algorithm <name> Specify algorithm name (default all)\n"
+              "                         Supported values are:\n",
+              progname, progname);
+
+       print_config_names("                                  ");
+       printf("  -c, --count <number> Core count. (NOT used)\n"
+              "  -d, --debug          Enable dump of processed packets.\n"
+              "  -f, --flight <number> Max number of packet processed in 
parallel (default 1)\n"
+              "  -i, --iterations <number> Number of iterations.\n"
+              "  -n, --inplace        Encrypt on place (ks2 does not support 
this).\n"
+              "  -p, --payload        Payload size.\n"
+              "  -r, --reuse          Output encrypted packet is passed as 
input\n"
+              "                       to next encrypt iteration.\n"
+              "  -h, --help           Display help and exit.\n"
+              "\n");
+}
-- 
1.8.1.4


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to