This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, api-next has been updated via afeda4d14bb6f449cb269680cdbd56b26726eedf (commit) via 1b259a7a4e573080f4debc542cab7a0b996f4c88 (commit) via 4ce7bdf3d99cc1d7634a80f961fc0e9e7523a0ac (commit) via 55fd230da7d8515452c08256f8fd8471d32d7601 (commit) via b529f843814f70068de2090e02df632113afa800 (commit) via fa78c11ad2de706ce07a7691168bdb5b58d060d4 (commit) via 5a2376365df984e160b92463be37740786a10bd6 (commit) via 3f3d7651c7cd7ba3b941904bbcbdabcac9a7dfd0 (commit) via 72a4e9f9bad9dfeaafba4e29a7450ee7edca5d1c (commit) via 7f3624154ff59ab85352c35e1c6df3c9597f9f51 (commit) via bbefeae66a2a6ac6c9386bb8a083022b7f323fc9 (commit) via a08dba6c24af81142efc6176eae2bdd561b478e3 (commit) via 1c02e217fac2ed2d015205ad36bd86c4924ce6cc (commit) via a3bc051085b95170101a3f81379e78c48e5a636c (commit) via fa281989523b82177f974abe7b4adfec47705dfa (commit) via 3bacbfd55edf76b897a4b2e5c62b59ca6fa95331 (commit) via 37b430cb9e8f6834a3c76ab108489cec719b9e32 (commit) via 4d38a376cd9976dfbeb565e509c028d07dfb1ed8 (commit) via c16af6486eea240609f334b1bdc81a11404275de (commit) from 60a1a4f1cc531d7f0117cd79daf1cbe4206e12ef (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit afeda4d14bb6f449cb269680cdbd56b26726eedf Merge: 60a1a4f1 1b259a7a Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Fri Oct 13 14:20:08 2017 +0300
Merge branch 'master' into api-next
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --cc platform/linux-generic/odp_timer.c index 5ef38dd7,70a9c97b..bee63383 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@@ -173,9 -166,8 +173,10 @@@ static inline void set_next_free(_odp_t * Inludes alloc and free timer *****************************************************************************/
- typedef struct odp_timer_pool_s { + typedef struct timer_pool_s { + /* Put frequently accessed fields in the first cache line */ + odp_time_t prev_scan; /* Time when previous scan started */ + odp_time_t time_per_tick; /* Time per timer pool tick */ odp_atomic_u64_t cur_tick;/* Current tick value */ uint64_t min_rel_tck; uint64_t max_rel_tck; @@@ -198,12 -190,10 +199,12 @@@
#define MAX_TIMER_POOLS 255 /* Leave one for ODP_TIMER_INVALID */ #define INDEX_BITS 24 +#define TIMER_RES_TEST_LOOP_COUNT 10 +#define TIMER_RES_ROUNDUP_FACTOR 10 static odp_atomic_u32_t num_timer_pools; - static odp_timer_pool *timer_pool[MAX_TIMER_POOLS]; + static timer_pool_t *timer_pool[MAX_TIMER_POOLS];
- static inline odp_timer_pool *handle_to_tp(odp_timer_t hdl) + static inline timer_pool_t *handle_to_tp(odp_timer_t hdl) { uint32_t tp_idx = _odp_typeval(hdl) >> INDEX_BITS; if (odp_likely(tp_idx < MAX_TIMER_POOLS)) { @@@ -253,9 -244,7 +255,10 @@@ static odp_timer_pool_t timer_pool_new( if (odp_unlikely(shm == ODP_SHM_INVALID)) ODP_ABORT("%s: timer pool shm-alloc(%zuKB) failed\n", name, (sz0 + sz1 + sz2) / 1024); - odp_timer_pool *tp = (odp_timer_pool *)odp_shm_addr(shm); ++ + timer_pool_t *tp = (timer_pool_t *)odp_shm_addr(shm); + tp->prev_scan = odp_time_global(); + tp->time_per_tick = odp_time_global_from_ns(param->res_ns); odp_atomic_init_u64(&tp->cur_tick, 0);
if (name == NULL) { @@@ -688,84 -673,6 +691,84 @@@ static unsigned odp_timer_pool_expire(o return nexp; }
+/****************************************************************************** + * Inline timer processing + *****************************************************************************/ + +static unsigned process_timer_pools(void) +{ - odp_timer_pool *tp; ++ timer_pool_t *tp; + odp_time_t prev_scan, now; + uint64_t nticks; + unsigned nexp = 0; + + for (size_t i = 0; i < MAX_TIMER_POOLS; i++) { + tp = timer_pool[i]; + + if (tp == NULL) + continue; + + /* + * Check the last time this timer pool was expired. If one + * or more periods have passed, attempt to expire it. + */ + prev_scan = tp->prev_scan; + now = odp_time_global(); + + nticks = (now.u64 - prev_scan.u64) / tp->time_per_tick.u64; + + if (nticks < 1) + continue; + + if (__atomic_compare_exchange_n( + &tp->prev_scan.u64, &prev_scan.u64, + prev_scan.u64 + (tp->time_per_tick.u64 * nticks), + false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) { + uint64_t tp_tick = _odp_atomic_u64_fetch_add_mm( + &tp->cur_tick, nticks, _ODP_MEMMODEL_RLX); + + if (tp->notify_overrun && nticks > 1) { + ODP_ERR("\n\t%d ticks overrun on timer pool " + ""%s", timer resolution too high\n", + nticks - 1, tp->name); + tp->notify_overrun = 0; + } + nexp += odp_timer_pool_expire(tp, tp_tick + nticks); + } + } + return nexp; +} + +static odp_time_t time_per_ratelimit_period; + +unsigned _timer_run(void) +{ + static __thread odp_time_t last_timer_run; + static __thread unsigned timer_run_cnt = + CONFIG_TIMER_RUN_RATELIMIT_ROUNDS; + odp_time_t now; + + if (odp_atomic_load_u32(&num_timer_pools) == 0) + return 0; + + /* Rate limit how often this thread checks the timer pools. */ + + if (CONFIG_TIMER_RUN_RATELIMIT_ROUNDS > 1) { + if (--timer_run_cnt) + return 0; + timer_run_cnt = CONFIG_TIMER_RUN_RATELIMIT_ROUNDS; + } + + now = odp_time_global(); + if (odp_time_cmp(odp_time_diff(now, last_timer_run), + time_per_ratelimit_period) == -1) + return 0; + last_timer_run = now; + + /* Check the timer pools. */ + return process_timer_pools(); +} + /****************************************************************************** * POSIX timer support * Functions that use Linux/POSIX per-process timers and related facilities @@@ -831,85 -738,7 +834,85 @@@ static void *timer_thread(void *arg return NULL; }
+/* Get the max timer resolution without overrun and fill in timer_res variable. + * + * Set timer's interval with candidate resolutions to get the max resolution + * that the timer would not be overrun. + * The candidate resolution value is from 1ms to 100us, 10us...1ns etc. + */ +static int timer_res_init(void) +{ + struct sigevent sigev; + timer_t timerid; + uint64_t res, sec, nsec; + struct itimerspec ispec; + sigset_t sigset; + siginfo_t si; + int loop_cnt; + struct timespec tmo; + + sigev.sigev_notify = SIGEV_THREAD_ID; + sigev._sigev_un._tid = (pid_t)syscall(SYS_gettid); + sigev.sigev_value.sival_ptr = NULL; + sigev.sigev_signo = SIGUSR1; + + /* Create timer */ + if (timer_create(CLOCK_MONOTONIC, &sigev, &timerid)) + ODP_ABORT("timer_create() returned error %s\n", + strerror(errno)); + + /* Timer resolution start from 1ms */ + res = ODP_TIME_MSEC_IN_NS; + /* Set initial value of timer_res */ + highest_res_ns = res; + sigemptyset(&sigset); + /* Add SIGUSR1 to sigset */ + sigaddset(&sigset, SIGUSR1); + sigprocmask(SIG_BLOCK, &sigset, NULL); + + while (res > 0) { + /* Loop for 10 times to test the result */ + loop_cnt = TIMER_RES_TEST_LOOP_COUNT; + sec = res / ODP_TIME_SEC_IN_NS; + nsec = res - sec * ODP_TIME_SEC_IN_NS; + + memset(&ispec, 0, sizeof(ispec)); + ispec.it_interval.tv_sec = (time_t)sec; + ispec.it_interval.tv_nsec = (long)nsec; + ispec.it_value.tv_sec = (time_t)sec; + ispec.it_value.tv_nsec = (long)nsec; + + if (timer_settime(timerid, 0, &ispec, NULL)) + ODP_ABORT("timer_settime() returned error %s\n", + strerror(errno)); + /* Set signal wait timeout to 10*res */ + tmo.tv_sec = 0; + tmo.tv_nsec = res * 10; + while (loop_cnt--) { + if (sigtimedwait(&sigset, &si, &tmo) > 0) { + if (timer_getoverrun(timerid)) + /* overrun at this resolution */ + /* goto the end */ + goto timer_res_init_done; + } + } + /* Set timer_res */ + highest_res_ns = res; + /* Test the next timer resolution candidate */ + res /= 10; + } + +timer_res_init_done: + highest_res_ns *= TIMER_RES_ROUNDUP_FACTOR; + if (timer_delete(timerid) != 0) + ODP_ABORT("timer_delete() returned error %s\n", + strerror(errno)); + sigemptyset(&sigset); + sigprocmask(SIG_BLOCK, &sigset, NULL); + return 0; +} + - static void itimer_init(odp_timer_pool *tp) + static void itimer_init(timer_pool_t *tp) { struct sigevent sigev; struct itimerspec ispec; @@@ -990,14 -805,7 +993,14 @@@ odp_timer_pool_create(const char *name __odp_errno = EINVAL; return ODP_TIMER_POOL_INVALID; } + + if (min_res_ns > param->res_ns) { + min_res_ns = param->res_ns; + time_per_ratelimit_period = + odp_time_global_from_ns(min_res_ns / 2); + } + - return odp_timer_pool_new(name, param); + return timer_pool_new(name, param); }
void odp_timer_pool_start(void) diff --cc test/Makefile.inc index e8e63b55,c1503c98..348a0058 --- a/test/Makefile.inc +++ b/test/Makefile.inc @@@ -21,8 -21,5 +21,7 @@@ AM_CFLAGS = $(CUNIT_CFLAGS AM_LDFLAGS = -L$(LIB) -static
@VALGRIND_CHECK_RULES@ - valgrind_tools = memcheck
-TESTS_ENVIRONMENT= ODP_PLATFORM=${with_platform} EXEEXT=${EXEEXT} +TESTS_ENVIRONMENT = ODP_PLATFORM=${with_platform} \ + EXEEXT=${EXEEXT} \ + ODP_SYSCONFIG_FILE=none
-----------------------------------------------------------------------
Summary of changes: .travis.yml | 10 +- configure.ac | 3 + example/classifier/odp_classifier.c | 14 +-- example/generator/odp_generator.c | 12 +-- example/ipsec/odp_ipsec.c | 12 +-- example/l3fwd/odp_l3fwd.c | 14 +-- example/packet/odp_pktio.c | 12 +-- example/switch/odp_switch.c | 14 +-- example/timer/odp_timer_test.c | 10 +- m4/ax_valgrind_check.m4 | 23 +++-- .../linux-generic/arch/default/odp_sysinfo_parse.c | 5 + .../linux-generic/arch/mips64/odp_sysinfo_parse.c | 5 + .../linux-generic/arch/powerpc/odp_sysinfo_parse.c | 5 + .../linux-generic/arch/x86/odp_sysinfo_parse.c | 36 +++++++ .../include/odp/api/plat/timer_types.h | 4 +- platform/linux-generic/include/odp_internal.h | 1 + platform/linux-generic/odp_pool.c | 47 ++++++++- platform/linux-generic/odp_system_info.c | 7 +- platform/linux-generic/odp_timer.c | 110 +++++++++++---------- test/Makefile.inc | 1 - test/common_plat/m4/validation.m4 | 2 +- test/common_plat/performance/odp_bench_packet.c | 14 +-- test/common_plat/performance/odp_l2fwd.c | 14 +-- test/common_plat/performance/odp_pktio_ordered.c | 14 +-- test/common_plat/performance/odp_pktio_perf.c | 42 +++++--- test/common_plat/performance/odp_scheduling.c | 12 +-- test/common_plat/validation/api/packet/packet.c | 1 - test/linux-generic/pktio_ipc/ipc_common.c | 8 +- 28 files changed, 225 insertions(+), 227 deletions(-)
hooks/post-receive