From patchwork Thu Aug 21 11:58:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petri Savolainen X-Patchwork-Id: 35750 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f69.google.com (mail-oa0-f69.google.com [209.85.219.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3E39B20540 for ; Thu, 21 Aug 2014 11:58:03 +0000 (UTC) Received: by mail-oa0-f69.google.com with SMTP id i7sf56709893oag.8 for ; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:subject :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:mime-version:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=ZnIIVIrmB2KQ/tQdeuie6F2deDBBYJ93tDqzUWwYx84=; b=FHfUQF/DVwQNPP/UYdyq6+Fqo+ib8FeS3S1w0SsJR9XBN9Zi0aN5gb0jv8j/HSpXOz lj0M2HIoGh/oYeSQoUVjnNguzWcB6L01/nGepE6EnSLC3gee7jgx5qu6H7PEGPFRLvH/ jTUUoBMWf4X4X8U0nJR28X33odcBYz7Xw1GMDDhSI//HOYub9iEKjaEwwypBwyEvezij cBP4jgSRJyGobwwhiIrF+WlmsC2BH6KNGHj3RQHB0hc8PoZTMrsMT2gB1F3Qsd60uVoN yrVKA7JuDxd1JujVSJdl5sEl+cO41Kq6WxpU/JT6n0uLy/Pvkaaog88ErDwsmQ42j3Zf yTaw== X-Gm-Message-State: ALoCoQlEEZ8dTAo9T/fEk7kq7XeblED9PHr0Olwtr/VLQRlJq/t/oHs3F3XyDbwebntjANUacYOn X-Received: by 10.182.68.17 with SMTP id r17mr27660027obt.26.1408622282885; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.94.210 with SMTP id g76ls698773qge.74.gmail; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-Received: by 10.220.114.5 with SMTP id c5mr41516651vcq.28.1408622282792; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) Received: from mail-vc0-f182.google.com (mail-vc0-f182.google.com [209.85.220.182]) by mx.google.com with ESMTPS id u3si1812585vda.87.2014.08.21.04.58.02 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 21 Aug 2014 04:58:02 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 as permitted sender) client-ip=209.85.220.182; Received: by mail-vc0-f182.google.com with SMTP id hy4so10444226vcb.41 for ; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-Received: by 10.220.114.5 with SMTP id c5mr41516637vcq.28.1408622282495; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp129097vcb; Thu, 21 Aug 2014 04:58:02 -0700 (PDT) X-Received: by 10.140.85.74 with SMTP id m68mr82019541qgd.50.1408622281219; Thu, 21 Aug 2014 04:58:01 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id z5si38326673qgz.64.2014.08.21.04.58.00 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 21 Aug 2014 04:58:01 -0700 (PDT) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XKR0C-0003a4-4q; Thu, 21 Aug 2014 11:58:00 +0000 Received: from mail-qa0-f41.google.com ([209.85.216.41]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XKR06-0003XL-F1 for lng-odp@lists.linaro.org; Thu, 21 Aug 2014 11:57:54 +0000 Received: by mail-qa0-f41.google.com with SMTP id j7so8195457qaq.0 for ; Thu, 21 Aug 2014 04:57:49 -0700 (PDT) X-Received: by 10.224.95.74 with SMTP id c10mr85032860qan.35.1408622269086; Thu, 21 Aug 2014 04:57:49 -0700 (PDT) Received: from localhost.localdomain (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id b2sm46109299qaq.4.2014.08.21.04.57.46 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 21 Aug 2014 04:57:48 -0700 (PDT) From: Petri Savolainen To: lng-odp@lists.linaro.org Date: Thu, 21 Aug 2014 14:58:27 +0300 Message-Id: <1408622307-4127-1-git-send-email-petri.savolainen@linaro.org> X-Mailer: git-send-email 2.1.0 X-Topics: timers patch Subject: [lng-odp] [PATCH] Timer bug corrections X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: petri.savolainen@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 - Start POSIX timer in odp_timer_create - return correct value int odp_timeout_tick Signed-off-by: Petri Savolainen Reviewed-by: Anders Roxell --- platform/linux-generic/odp_timer.c | 127 ++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 73a690b..1bf37f9 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -29,9 +29,11 @@ typedef struct { } tick_t; typedef struct { + int allocated; volatile int active; volatile uint64_t cur_tick; timer_t timerid; + odp_timer_t timer_hdl; odp_buffer_pool_t pool; uint64_t resolution_ns; uint64_t max_ticks; @@ -40,8 +42,10 @@ typedef struct { } timer_ring_t; typedef struct { - timer_ring_t timer[NUM_TIMERS]; - odp_atomic_int_t num_timers; + odp_spinlock_t lock; + int num_timers; + timer_ring_t timer[NUM_TIMERS]; + } timer_global_t; /* Global */ @@ -105,7 +109,7 @@ static int find_and_del_tmo(timeout_t **tmo, odp_timer_tmo_t handle) return 0; } -int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t tmo) +int odp_timer_cancel_tmo(odp_timer_t timer_hdl, odp_timer_tmo_t tmo) { int id; uint64_t tick_idx; @@ -114,7 +118,7 @@ int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t tmo) tick_t *tick; /* get id */ - id = timer - 1; + id = timer_hdl - 1; tmo_hdr = odp_timeout_hdr((odp_timeout_t) tmo); /* get tmo_buf to cancel */ @@ -137,19 +141,25 @@ int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t tmo) static void notify_function(union sigval sigval) { - (void) sigval; uint64_t cur_tick; timeout_t *tmo; tick_t *tick; + timer_ring_t *timer; + + timer = sigval.sival_ptr; - if (odp_timer.timer[0].active == 0) + if (timer->active == 0) { + ODP_DBG("Timer (%u) not active\n", timer->timer_hdl); return; + } /* ODP_DBG("Tick\n"); */ - cur_tick = odp_timer.timer[0].cur_tick++; + cur_tick = timer->cur_tick++; + + odp_sync_stores(); - tick = &odp_timer.timer[0].tick[cur_tick % MAX_TICKS]; + tick = &timer->tick[cur_tick % MAX_TICKS]; while ((tmo = rem_tmo(tick)) != NULL) { odp_queue_t queue; @@ -165,21 +175,21 @@ static void notify_function(union sigval sigval) } } -static void timer_init(void) +static void timer_start(timer_ring_t *timer) { struct sigevent sigev; struct itimerspec ispec; - ODP_DBG("Timer thread starts\n"); + ODP_DBG("\nTimer (%u) starts\n", timer->timer_hdl); memset(&sigev, 0, sizeof(sigev)); memset(&ispec, 0, sizeof(ispec)); sigev.sigev_notify = SIGEV_THREAD; sigev.sigev_notify_function = notify_function; + sigev.sigev_value.sival_ptr = timer; - if (timer_create(CLOCK_MONOTONIC, &sigev, - &odp_timer.timer[0].timerid)) { + if (timer_create(CLOCK_MONOTONIC, &sigev, &timer->timerid)) { ODP_DBG("Timer create failed\n"); return; } @@ -189,7 +199,7 @@ static void timer_init(void) ispec.it_value.tv_sec = 0; ispec.it_value.tv_nsec = RESOLUTION_NS; - if (timer_settime(odp_timer.timer[0].timerid, 0, &ispec, NULL)) { + if (timer_settime(timer->timerid, 0, &ispec, NULL)) { ODP_DBG("Timer set failed\n"); return; } @@ -199,14 +209,13 @@ static void timer_init(void) int odp_timer_init_global(void) { - int i; + ODP_DBG("Timer init ..."); memset(&odp_timer, 0, sizeof(timer_global_t)); - for (i = 0; i < MAX_TICKS; i++) - odp_spinlock_init(&odp_timer.timer[0].tick[i].lock); + odp_spinlock_init(&odp_timer.lock); - timer_init(); + ODP_DBG("done\n"); return 0; } @@ -216,7 +225,9 @@ int odp_timer_disarm_all(void) int timers; struct itimerspec ispec; - timers = odp_atomic_load_int(&odp_timer.num_timers); + odp_spinlock_lock(&odp_timer.lock); + + timers = odp_timer.num_timers; ispec.it_interval.tv_sec = 0; ispec.it_interval.tv_nsec = 0; @@ -227,11 +238,14 @@ int odp_timer_disarm_all(void) if (timer_settime(odp_timer.timer[timers].timerid, 0, &ispec, NULL)) { ODP_DBG("Timer reset failed\n"); + odp_spinlock_unlock(&odp_timer.lock); return -1; } - odp_atomic_fetch_sub_int(&odp_timer.num_timers, 1); + odp_timer.num_timers--; } + odp_spinlock_unlock(&odp_timer.lock); + return 0; } @@ -240,27 +254,50 @@ odp_timer_t odp_timer_create(const char *name, odp_buffer_pool_t pool, uint64_t max_tmo) { uint32_t id; + timer_ring_t *timer; + odp_timer_t timer_hdl; + int i; (void) name; (void) resolution; (void) min_tmo; (void) max_tmo; - if (odp_timer.num_timers >= NUM_TIMERS) - return ODP_TIMER_INVALID; + odp_spinlock_lock(&odp_timer.lock); - id = odp_atomic_fetch_inc_int(&odp_timer.num_timers); - if (id >= NUM_TIMERS) + if (odp_timer.num_timers >= NUM_TIMERS) { + odp_spinlock_unlock(&odp_timer.lock); return ODP_TIMER_INVALID; + } + + for (id = 0; id < NUM_TIMERS; id++) { + if (odp_timer.timer[id].allocated == 0) + break; + } - odp_timer.timer[id].pool = pool; - odp_timer.timer[id].resolution_ns = RESOLUTION_NS; - odp_timer.timer[id].max_ticks = MAX_TICKS; + timer = &odp_timer.timer[id]; + timer->allocated = 1; + odp_timer.num_timers++; + + odp_spinlock_unlock(&odp_timer.lock); + + timer_hdl = id + 1; + + timer->timer_hdl = timer_hdl; + timer->pool = pool; + timer->resolution_ns = RESOLUTION_NS; + timer->max_ticks = MAX_TICKS; + + for (i = 0; i < MAX_TICKS; i++) { + odp_spinlock_init(&timer->tick[i].lock); + timer->tick[i].list = NULL; + } + timer->active = 1; odp_sync_stores(); - odp_timer.timer[id].active = 1; + timer_start(timer); - return id + 1; + return timer_hdl; } -odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, uint64_t tmo_tick, +odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer_hdl, uint64_t tmo_tick, odp_queue_t queue, odp_buffer_t buf) { int id; @@ -269,10 +306,12 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, uint64_t tmo_tick, timeout_t *new_tmo; odp_buffer_t tmo_buf; odp_timeout_hdr_t *tmo_hdr; + timer_ring_t *timer; - id = timer - 1; + id = timer_hdl - 1; + timer = &odp_timer.timer[id]; - cur_tick = odp_timer.timer[id].cur_tick; + cur_tick = timer->cur_tick; if (tmo_tick <= cur_tick) { ODP_DBG("timeout too close\n"); return ODP_TIMER_TMO_INVALID; @@ -286,7 +325,7 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, uint64_t tmo_tick, tick = (cur_tick + tick) % MAX_TICKS; - tmo_buf = odp_buffer_alloc(odp_timer.timer[id].pool); + tmo_buf = odp_buffer_alloc(timer->pool); if (tmo_buf == ODP_BUFFER_INVALID) { ODP_DBG("alloc failed\n"); return ODP_TIMER_TMO_INVALID; @@ -306,48 +345,48 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, uint64_t tmo_tick, else new_tmo->buf = tmo_buf; - add_tmo(&odp_timer.timer[id].tick[tick], new_tmo); + add_tmo(&timer->tick[tick], new_tmo); return tmo_buf; } -uint64_t odp_timer_tick_to_ns(odp_timer_t timer, uint64_t ticks) +uint64_t odp_timer_tick_to_ns(odp_timer_t timer_hdl, uint64_t ticks) { uint32_t id; - id = timer - 1; + id = timer_hdl - 1; return ticks * odp_timer.timer[id].resolution_ns; } -uint64_t odp_timer_ns_to_tick(odp_timer_t timer, uint64_t ns) +uint64_t odp_timer_ns_to_tick(odp_timer_t timer_hdl, uint64_t ns) { uint32_t id; - id = timer - 1; + id = timer_hdl - 1; return ns / odp_timer.timer[id].resolution_ns; } -uint64_t odp_timer_resolution(odp_timer_t timer) +uint64_t odp_timer_resolution(odp_timer_t timer_hdl) { uint32_t id; - id = timer - 1; + id = timer_hdl - 1; return odp_timer.timer[id].resolution_ns; } -uint64_t odp_timer_maximum_tmo(odp_timer_t timer) +uint64_t odp_timer_maximum_tmo(odp_timer_t timer_hdl) { uint32_t id; - id = timer - 1; + id = timer_hdl - 1; return odp_timer.timer[id].max_ticks; } -uint64_t odp_timer_current_tick(odp_timer_t timer) +uint64_t odp_timer_current_tick(odp_timer_t timer_hdl) { uint32_t id; - id = timer - 1; + id = timer_hdl - 1; return odp_timer.timer[id].cur_tick; } @@ -359,5 +398,5 @@ odp_timeout_t odp_timeout_from_buffer(odp_buffer_t buf) uint64_t odp_timeout_tick(odp_timeout_t tmo) { odp_timeout_hdr_t *tmo_hdr = odp_timeout_hdr(tmo); - return tmo_hdr->meta.tick; + return tmo_hdr->meta.tmo_tick; }