diff options
author | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-11-30 12:44:48 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-11-30 12:44:48 +0300 |
commit | 74785c4e170e035c08476179237d68a36fa23ec3 (patch) | |
tree | 2d614f6491c214b138ed72e5568eb611ef68fe19 /platform | |
parent | 56e6043816ecbe954e804004f0b13cdad5915341 (diff) | |
parent | 6f7fad3acc8254a273a0ed80833bf422ad01d9c0 (diff) |
Merge branch 'next'
Diffstat (limited to 'platform')
-rw-r--r-- | platform/linux-generic/Makefile.am | 1 | ||||
-rw-r--r-- | platform/linux-generic/include/odp/plat/crypto_types.h | 42 | ||||
-rw-r--r-- | platform/linux-generic/include/odp/plat/time_types.h | 36 | ||||
-rw-r--r-- | platform/linux-generic/include/odp/time.h | 1 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_buffer_internal.h | 2 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_cpu_internal.h | 2 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_crypto_internal.h | 20 | ||||
-rw-r--r-- | platform/linux-generic/odp_cpu.c | 4 | ||||
-rw-r--r-- | platform/linux-generic/odp_crypto.c | 205 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet.c | 32 | ||||
-rw-r--r-- | platform/linux-generic/odp_pool.c | 29 | ||||
-rw-r--r-- | platform/linux-generic/odp_queue.c | 40 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule.c | 16 | ||||
-rw-r--r-- | platform/linux-generic/odp_time.c | 62 | ||||
-rw-r--r-- | platform/linux-generic/odp_timer.c | 4 |
15 files changed, 410 insertions, 86 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 610e04d9e..70bd8fe85 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -70,6 +70,7 @@ odpplatinclude_HEADERS = \ $(srcdir)/include/odp/plat/strong_types.h \ $(srcdir)/include/odp/plat/thrmask_types.h \ $(srcdir)/include/odp/plat/ticketlock_types.h \ + $(srcdir)/include/odp/plat/time_types.h \ $(srcdir)/include/odp/plat/timer_types.h \ $(srcdir)/include/odp/plat/version_types.h diff --git a/platform/linux-generic/include/odp/plat/crypto_types.h b/platform/linux-generic/include/odp/plat/crypto_types.h index a91d88e6c..0cbbce8bd 100644 --- a/platform/linux-generic/include/odp/plat/crypto_types.h +++ b/platform/linux-generic/include/odp/plat/crypto_types.h @@ -27,48 +27,6 @@ extern "C" { typedef uint64_t odp_crypto_session_t; typedef ODP_HANDLE_T(odp_crypto_compl_t); -enum odp_crypto_op_mode { - ODP_CRYPTO_SYNC, - ODP_CRYPTO_ASYNC, -}; - -enum odp_crypto_op { - ODP_CRYPTO_OP_ENCODE, - ODP_CRYPTO_OP_DECODE, -}; - -enum odp_cipher_alg { - ODP_CIPHER_ALG_NULL, - ODP_CIPHER_ALG_DES, - ODP_CIPHER_ALG_3DES_CBC, -}; - -enum odp_auth_alg { - ODP_AUTH_ALG_NULL, - ODP_AUTH_ALG_MD5_96, -}; - -enum odp_crypto_ses_create_err { - ODP_CRYPTO_SES_CREATE_ERR_NONE, - ODP_CRYPTO_SES_CREATE_ERR_ENOMEM, - ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER, - ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH, -}; - -enum crypto_alg_err { - ODP_CRYPTO_ALG_ERR_NONE, - ODP_CRYPTO_ALG_ERR_DATA_SIZE, - ODP_CRYPTO_ALG_ERR_KEY_SIZE, - ODP_CRYPTO_ALG_ERR_ICV_CHECK, - ODP_CRYPTO_ALG_ERR_IV_INVALID, -}; - -enum crypto_hw_err { - ODP_CRYPTO_HW_ERR_NONE, - ODP_CRYPTO_HW_ERR_DMA, - ODP_CRYPTO_HW_ERR_BP_DEPLETED, -}; - /** Get printable format of odp_crypto_session_t */ static inline uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl) { diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h new file mode 100644 index 000000000..9ba1508c7 --- /dev/null +++ b/platform/linux-generic/include/odp/plat/time_types.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP time service + */ + +#ifndef ODP_TIME_TYPES_H_ +#define ODP_TIME_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup odp_time + * @{ + **/ + +typedef uint64_t odp_time_t; + +#define ODP_TIME_NULL ((odp_time_t)0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/time.h b/platform/linux-generic/include/odp/time.h index 3a3960b02..44e0d0d25 100644 --- a/platform/linux-generic/include/odp/time.h +++ b/platform/linux-generic/include/odp/time.h @@ -21,6 +21,7 @@ extern "C" { +#include <odp/plat/time_types.h> #include <odp/api/time.h> #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h index 462f4bf3b..74a0b5c4f 100644 --- a/platform/linux-generic/include/odp_buffer_internal.h +++ b/platform/linux-generic/include/odp_buffer_internal.h @@ -166,6 +166,8 @@ typedef struct { /* Forward declarations */ odp_buffer_t buffer_alloc(odp_pool_t pool, size_t size); +int buffer_alloc_multi(odp_pool_t pool_hdl, size_t size, + odp_buffer_t buf[], int num); #ifdef __cplusplus } diff --git a/platform/linux-generic/include/odp_cpu_internal.h b/platform/linux-generic/include/odp_cpu_internal.h index 5eeabefec..664e2df5d 100644 --- a/platform/linux-generic/include/odp_cpu_internal.h +++ b/platform/linux-generic/include/odp_cpu_internal.h @@ -14,7 +14,7 @@ extern "C" { #include <odp/cpu.h> static inline -uint64_t _odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) +uint64_t _odp_cpu_cycles_diff(uint64_t c2, uint64_t c1) { if (odp_likely(c2 >= c1)) return c2 - c1; diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index ebd6170e2..b9128a426 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -12,6 +12,7 @@ extern "C" { #endif #include <openssl/des.h> +#include <openssl/aes.h> #define OP_RESULT_MAGIC 0x91919191 @@ -22,20 +23,20 @@ typedef struct odp_crypto_generic_session odp_crypto_generic_session_t; * Algorithm handler function prototype */ typedef -enum crypto_alg_err (*crypto_func_t)(odp_crypto_op_params_t *params, - odp_crypto_generic_session_t *session); +odp_crypto_alg_err_t (*crypto_func_t)(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session); /** * Per crypto session data structure */ struct odp_crypto_generic_session { struct odp_crypto_generic_session *next; - enum odp_crypto_op op; + odp_crypto_op_t op; odp_bool_t do_cipher_first; odp_queue_t compl_queue; odp_pool_t output_pool; struct { - enum odp_cipher_alg alg; + odp_cipher_alg_t alg; struct { uint8_t *data; size_t len; @@ -46,16 +47,23 @@ struct odp_crypto_generic_session { DES_key_schedule ks2; DES_key_schedule ks3; } des; + struct { + AES_KEY key; + } aes; } data; crypto_func_t func; } cipher; struct { - enum odp_auth_alg alg; + odp_auth_alg_t alg; union { struct { uint8_t key[16]; uint32_t bytes; } md5; + struct { + uint8_t key[32]; + uint32_t bytes; + } sha256; } data; crypto_func_t func; } auth; @@ -73,7 +81,7 @@ typedef struct odp_crypto_generic_op_result { * Per session creation operation result */ typedef struct odp_crypto_generic_session_result { - enum odp_crypto_ses_create_err rc; + odp_crypto_ses_create_err_t rc; odp_crypto_session_t session; } odp_crypto_generic_session_result_t; diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c index e5ec4f08d..636f811f8 100644 --- a/platform/linux-generic/odp_cpu.c +++ b/platform/linux-generic/odp_cpu.c @@ -8,7 +8,7 @@ #include <odp/hints.h> #include <odp_cpu_internal.h> -uint64_t odp_cpu_cycles_diff(uint64_t c1, uint64_t c2) +uint64_t odp_cpu_cycles_diff(uint64_t c2, uint64_t c1) { - return _odp_cpu_cycles_diff(c1, c2); + return _odp_cpu_cycles_diff(c2, c1); } diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index d49e256d5..17fced930 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -66,17 +66,16 @@ void free_session(odp_crypto_generic_session_t *session) odp_spinlock_unlock(&global->lock); } -static -enum crypto_alg_err null_crypto_routine( - odp_crypto_op_params_t *params ODP_UNUSED, - odp_crypto_generic_session_t *session ODP_UNUSED) +static odp_crypto_alg_err_t +null_crypto_routine(odp_crypto_op_params_t *params ODP_UNUSED, + odp_crypto_generic_session_t *session ODP_UNUSED) { return ODP_CRYPTO_ALG_ERR_NONE; } static -enum crypto_alg_err md5_gen(odp_crypto_op_params_t *params, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t md5_gen(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(params->out_pkt); uint8_t *icv = data; @@ -103,8 +102,8 @@ enum crypto_alg_err md5_gen(odp_crypto_op_params_t *params, } static -enum crypto_alg_err md5_check(odp_crypto_op_params_t *params, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t md5_check(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(params->out_pkt); uint8_t *icv = data; @@ -141,10 +140,162 @@ enum crypto_alg_err md5_check(odp_crypto_op_params_t *params, } static -enum crypto_alg_err des_encrypt(odp_crypto_op_params_t *params, +odp_crypto_alg_err_t sha256_gen(odp_crypto_op_params_t *params, odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(params->out_pkt); + uint8_t *icv = data; + uint32_t len = params->auth_range.length; + uint8_t hash[EVP_MAX_MD_SIZE]; + + /* Adjust pointer for beginning of area to auth */ + data += params->auth_range.offset; + icv += params->hash_result_offset; + + /* Hash it */ + HMAC(EVP_sha256(), + session->auth.data.sha256.key, + 32, + data, + len, + hash, + NULL); + + /* Copy to the output location */ + memcpy(icv, hash, session->auth.data.sha256.bytes); + + return ODP_CRYPTO_ALG_ERR_NONE; +} + +static +odp_crypto_alg_err_t sha256_check(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) +{ + uint8_t *data = odp_packet_data(params->out_pkt); + uint8_t *icv = data; + uint32_t len = params->auth_range.length; + uint32_t bytes = session->auth.data.sha256.bytes; + uint8_t hash_in[EVP_MAX_MD_SIZE]; + uint8_t hash_out[EVP_MAX_MD_SIZE]; + + /* Adjust pointer for beginning of area to auth */ + data += params->auth_range.offset; + icv += params->hash_result_offset; + + /* Copy current value out and clear it before authentication */ + memset(hash_in, 0, sizeof(hash_in)); + memcpy(hash_in, icv, bytes); + memset(icv, 0, bytes); + memset(hash_out, 0, sizeof(hash_out)); + + /* Hash it */ + HMAC(EVP_sha256(), + session->auth.data.sha256.key, + 32, + data, + len, + hash_out, + NULL); + + /* Verify match */ + if (0 != memcmp(hash_in, hash_out, bytes)) + return ODP_CRYPTO_ALG_ERR_ICV_CHECK; + + /* Matched */ + return ODP_CRYPTO_ALG_ERR_NONE; +} + +static +odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) +{ + uint8_t *data = odp_packet_data(params->out_pkt); + uint32_t len = params->cipher_range.length; + unsigned char iv_enc[AES_BLOCK_SIZE]; + void *iv_ptr; + + if (params->override_iv_ptr) + iv_ptr = params->override_iv_ptr; + else if (session->cipher.iv.data) + iv_ptr = session->cipher.iv.data; + else + return ODP_CRYPTO_ALG_ERR_IV_INVALID; + + /* + * Create a copy of the IV. The DES library modifies IV + * and if we are processing packets on parallel threads + * we could get corruption. + */ + memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); + + /* Adjust pointer for beginning of area to cipher */ + data += params->cipher_range.offset; + /* Encrypt it */ + AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, + iv_enc, AES_ENCRYPT); + + return ODP_CRYPTO_ALG_ERR_NONE; +} + +static +odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) +{ + uint8_t *data = odp_packet_data(params->out_pkt); + uint32_t len = params->cipher_range.length; + unsigned char iv_enc[AES_BLOCK_SIZE]; + void *iv_ptr; + + if (params->override_iv_ptr) + iv_ptr = params->override_iv_ptr; + else if (session->cipher.iv.data) + iv_ptr = session->cipher.iv.data; + else + return ODP_CRYPTO_ALG_ERR_IV_INVALID; + + /* + * Create a copy of the IV. The DES library modifies IV + * and if we are processing packets on parallel threads + * we could get corruption. + */ + memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); + + /* Adjust pointer for beginning of area to cipher */ + data += params->cipher_range.offset; + /* Encrypt it */ + AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, + iv_enc, AES_DECRYPT); + + return ODP_CRYPTO_ALG_ERR_NONE; +} + +static +int process_aes_params(odp_crypto_generic_session_t *session, + odp_crypto_session_params_t *params) +{ + /* Verify IV len is either 0 or 16 */ + if (!((0 == params->iv.length) || (16 == params->iv.length))) + return -1; + + /* Set function */ + if (ODP_CRYPTO_OP_ENCODE == params->op) { + session->cipher.func = aes_encrypt; + AES_set_encrypt_key(params->cipher_key.data, 128, + &session->cipher.data.aes.key); + } else { + session->cipher.func = aes_decrypt; + AES_set_decrypt_key(params->cipher_key.data, 128, + &session->cipher.data.aes.key); + } + + return 0; +} + +static +odp_crypto_alg_err_t des_encrypt(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) +{ + uint8_t *data = odp_packet_data(params->out_pkt); uint32_t len = params->cipher_range.length; DES_cblock iv; void *iv_ptr; @@ -179,8 +330,8 @@ enum crypto_alg_err des_encrypt(odp_crypto_op_params_t *params, } static -enum crypto_alg_err des_decrypt(odp_crypto_op_params_t *params, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t des_decrypt(odp_crypto_op_params_t *params, + odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(params->out_pkt); uint32_t len = params->cipher_range.length; @@ -262,10 +413,30 @@ int process_md5_params(odp_crypto_generic_session_t *session, return 0; } +static +int process_sha256_params(odp_crypto_generic_session_t *session, + odp_crypto_session_params_t *params, + uint32_t bits) +{ + /* Set function */ + if (ODP_CRYPTO_OP_ENCODE == params->op) + session->auth.func = sha256_gen; + else + session->auth.func = sha256_check; + + /* Number of valid bytes */ + session->auth.data.sha256.bytes = bits / 8; + + /* Convert keys */ + memcpy(session->auth.data.sha256.key, params->auth_key.data, 32); + + return 0; +} + int odp_crypto_session_create(odp_crypto_session_params_t *params, odp_crypto_session_t *session_out, - enum odp_crypto_ses_create_err *status) + odp_crypto_ses_create_err_t *status) { int rc; odp_crypto_generic_session_t *session; @@ -305,6 +476,9 @@ odp_crypto_session_create(odp_crypto_session_params_t *params, case ODP_CIPHER_ALG_3DES_CBC: rc = process_des_params(session, params); break; + case ODP_CIPHER_ALG_AES128_CBC: + rc = process_aes_params(session, params); + break; default: rc = -1; } @@ -324,6 +498,9 @@ odp_crypto_session_create(odp_crypto_session_params_t *params, case ODP_AUTH_ALG_MD5_96: rc = process_md5_params(session, params, 96); break; + case ODP_AUTH_ALG_SHA256_128: + rc = process_sha256_params(session, params, 128); + break; default: rc = -1; } @@ -354,8 +531,8 @@ odp_crypto_operation(odp_crypto_op_params_t *params, odp_bool_t *posted, odp_crypto_op_result_t *result) { - enum crypto_alg_err rc_cipher = ODP_CRYPTO_ALG_ERR_NONE; - enum crypto_alg_err rc_auth = ODP_CRYPTO_ALG_ERR_NONE; + odp_crypto_alg_err_t rc_cipher = ODP_CRYPTO_ALG_ERR_NONE; + odp_crypto_alg_err_t rc_auth = ODP_CRYPTO_ALG_ERR_NONE; odp_crypto_generic_session_t *session; odp_crypto_op_result_t local_result; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 1b496247f..07c740cfa 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -15,6 +15,7 @@ #include <odp/helper/tcp.h> #include <odp/helper/udp.h> +#include <errno.h> #include <string.h> #include <stdio.h> @@ -127,11 +128,42 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) return packet_alloc(pool_hdl, len, 0); } +int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, + odp_packet_t pkt[], int num) +{ + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); + size_t pkt_size = len ? len : pool->s.params.buf.size; + int count, i; + + if (pool->s.params.type != ODP_POOL_PACKET) { + __odp_errno = EINVAL; + return -1; + } + + count = buffer_alloc_multi(pool_hdl, pkt_size, + (odp_buffer_t *)pkt, num); + + for (i = 0; i < count; ++i) { + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt[i]); + + packet_init(pool, pkt_hdr, pkt_size, 0); + if (len == 0) + pull_tail(pkt_hdr, pkt_size); + } + + return count; +} + void odp_packet_free(odp_packet_t pkt) { odp_buffer_free((odp_buffer_t)pkt); } +void odp_packet_free_multi(const odp_packet_t pkt[], int num) +{ + odp_buffer_free_multi((const odp_buffer_t *)pkt, num); +} + int odp_packet_reset(odp_packet_t pkt, uint32_t len) { odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 76a4aa585..9859ff6d9 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -529,12 +529,33 @@ odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size) return odp_hdr_to_buf(&buf->buf); } +int buffer_alloc_multi(odp_pool_t pool_hdl, size_t size, + odp_buffer_t buf[], int num) +{ + int count; + + for (count = 0; count < num; ++count) { + buf[count] = buffer_alloc(pool_hdl, size); + if (buf[count] == ODP_BUFFER_INVALID) + break; + } + + return count; +} + odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) { return buffer_alloc(pool_hdl, odp_pool_to_entry(pool_hdl)->s.params.buf.size); } +int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num) +{ + size_t buf_size = odp_pool_to_entry(pool_hdl)->s.params.buf.size; + + return buffer_alloc_multi(pool_hdl, buf_size, buf, num); +} + void odp_buffer_free(odp_buffer_t buf) { odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf); @@ -546,6 +567,14 @@ void odp_buffer_free(odp_buffer_t buf) ret_local_buf(&pool->s.local_cache[local_id], buf_hdr); } +void odp_buffer_free_multi(const odp_buffer_t buf[], int len) +{ + int i; + + for (i = 0; i < len; ++i) + odp_buffer_free(buf[i]); +} + void _odp_flush_caches(void) { int i; diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index a5e60d78c..db3399ce3 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -1063,3 +1063,43 @@ int release_order(queue_entry_t *origin_qe, uint64_t order, UNLOCK(&origin_qe->s.lock); return 0; } + +int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info) +{ + uint32_t queue_id; + queue_entry_t *queue; + int status; + + if (odp_unlikely(info == NULL)) { + ODP_ERR("Unable to store info, NULL ptr given\n"); + return -1; + } + + queue_id = queue_to_id(handle); + + if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) { + ODP_ERR("Invalid queue handle:%" PRIu64 "\n", + odp_queue_to_u64(handle)); + return -1; + } + + queue = get_qentry(queue_id); + + LOCK(&queue->s.lock); + status = queue->s.status; + + if (odp_unlikely(status == QUEUE_STATUS_FREE || + status == QUEUE_STATUS_DESTROYED)) { + UNLOCK(&queue->s.lock); + ODP_ERR("Invalid queue status:%d\n", status); + return -1; + } + + info->name = queue->s.name; + info->type = queue->s.type; + info->param = queue->s.param; + + UNLOCK(&queue->s.lock); + + return 0; +} diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index 5982f85a4..884ae60fd 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -586,10 +586,10 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait, odp_event_t out_ev[], unsigned int max_num, unsigned int max_deq) { - uint64_t start_cycle, cycle, diff; + odp_time_t start_time, time, diff; int ret; - start_cycle = 0; + start_time = ODP_TIME_NULL; while (1) { ret = schedule(out_queue, out_ev, max_num, max_deq); @@ -603,15 +603,15 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait, if (wait == ODP_SCHED_NO_WAIT) break; - if (start_cycle == 0) { - start_cycle = odp_time_cycles(); + if (!odp_time_cmp(ODP_TIME_NULL, start_time)) { + start_time = odp_time_local(); continue; } - cycle = odp_time_cycles(); - diff = odp_time_diff_cycles(start_cycle, cycle); + time = odp_time_local(); + diff = odp_time_diff(time, start_time); - if (wait < diff) + if (odp_time_cmp(wait, diff) < 0) break; } @@ -652,7 +652,7 @@ void odp_schedule_resume(void) uint64_t odp_schedule_wait_time(uint64_t ns) { - return odp_time_ns_to_cycles(ns); + return odp_time_to_u64(odp_time_local_from_ns(ns)); } diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 74f802b83..181d7323e 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -14,33 +14,73 @@ #define GIGA 1000000000 -uint64_t odp_time_cycles(void) +static inline +uint64_t time_to_tick(odp_time_t time) { - return odp_cpu_cycles(); + return (uint64_t)time; } -uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2) +static inline +odp_time_t tick_to_time(uint64_t tick) { - return _odp_cpu_cycles_diff(t1, t2); + return (odp_time_t)tick; } -uint64_t odp_time_cycles_to_ns(uint64_t cycles) +odp_time_t odp_time_local(void) +{ + return tick_to_time(odp_cpu_cycles()); +} + +odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) +{ + return tick_to_time(_odp_cpu_cycles_diff(t2, t1)); +} + +uint64_t odp_time_to_ns(odp_time_t time) { uint64_t hz = odp_sys_cpu_hz(); + uint64_t tick = time_to_tick(time); - if (cycles > (UINT64_MAX / GIGA)) - return (cycles/hz)*GIGA; + if (tick > (UINT64_MAX / GIGA)) + return (tick / hz) * GIGA; - return (cycles*GIGA)/hz; + return (tick * GIGA) / hz; } -uint64_t odp_time_ns_to_cycles(uint64_t ns) +odp_time_t odp_time_local_from_ns(uint64_t ns) { uint64_t hz = odp_sys_cpu_hz(); if (ns > (UINT64_MAX / hz)) - return (ns/GIGA)*hz; + return tick_to_time((ns / GIGA) * hz); + + return tick_to_time((ns * hz) / GIGA); +} + +int odp_time_cmp(odp_time_t t2, odp_time_t t1) +{ + uint64_t tick1 = time_to_tick(t1); + uint64_t tick2 = time_to_tick(t2); - return (ns*hz)/GIGA; + if (tick1 < tick2) + return 1; + + if (tick1 > tick2) + return -1; + + return 0; +} + +odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) +{ + uint64_t tick1 = time_to_tick(t1); + uint64_t tick2 = time_to_tick(t2); + + return tick_to_time(tick1 + tick2); +} + +uint64_t odp_time_to_u64(odp_time_t hdl) +{ + return time_to_tick(hdl); } diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 407ccc173..5c1f8ca7e 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -679,8 +679,8 @@ static void itimer_init(odp_timer_pool *tp) strerror(errno)); res = tp->param.res_ns; - sec = res / ODP_TIME_SEC; - nsec = res - sec * ODP_TIME_SEC; + sec = res / ODP_TIME_SEC_IN_NS; + nsec = res - sec * ODP_TIME_SEC_IN_NS; ispec.it_interval.tv_sec = (time_t)sec; ispec.it_interval.tv_nsec = (long)nsec; |