From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ig0-f175.google.com (mail-ig0-f175.google.com [209.85.213.175]) by dpdk.org (Postfix) with ESMTP id 49D1A5A56 for ; Wed, 3 Jun 2015 08:31:48 +0200 (CEST) Received: by igblz2 with SMTP id lz2so7033305igb.1 for ; Tue, 02 Jun 2015 23:31:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=j4HxtygPXaoThXeoyYOMG6yw5XjRkvSoDUZPZOBQBHc=; b=BrHoeY4Z63l6KZIDeEiStwDl0iTEYzzu1Vb1b1imZpNcnXvdi82ddwjgtr/DkWT5mG lSl4TXDBcbUJqibWKOCwXV/2WPPt0HAxEcxLMiHU+2WyQzQGD3qVdKpuUuGb2qBiTmAd gWwGvjZfXJKxn5/r3goO1BpyWiixKfljGn1/3Cg3UqHddNX4HVHLnFPL1VuerLQQoe7f NK4ovt5aPiJMlmNy1KHZSmlq/3Rmd7T49Eszs3NYEzyL9dl2PsTzxZjCwcayQx+/2qXG jQ95XBvYZ31Jfqax6CBLAegg0/Z2O+U854xWcXLTG2zECwjOkvnKqg63MykftO22bvOX Q2Mg== MIME-Version: 1.0 X-Received: by 10.50.27.6 with SMTP id p6mr24976119igg.46.1433313107658; Tue, 02 Jun 2015 23:31:47 -0700 (PDT) Received: by 10.79.112.140 with HTTP; Tue, 2 Jun 2015 23:31:47 -0700 (PDT) Date: Wed, 3 Jun 2015 14:31:47 +0800 Message-ID: From: Selmon Yang To: dev@dpdk.org Content-Type: text/plain; charset=UTF-8 Subject: [dpdk-dev] rte_eal_alarm_set() is affected by discontinuous jumps in the system time X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jun 2015 06:31:48 -0000 Hi, I found that, in dpdk 2.0, rte_eal_alarm_set() is affected by discontinuous jumps in the system time because eal_alarm_callback() and rte_eal_alarm_set() use gettimeofday() to get the current time. Here is what I encountered. I set up a rte eal alarm as below, and I like it to be triggered every second. #define USE_PER_S 1000 * 1000 void my_alarm_cb(void *arg) { /* send heartbeat signal out, etc. */ rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL); return; } int main(void) { /* ..., do something */ rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL); /* ... do something else */ } It works fine in most of time. However, if I change system time manually, it is possible that rte alarm function works out of my expectation. Suppose that current time is 11:00:00 AM, and eal_alarm_callback() is triggered because I executed rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL) at 10:59:59 AM. eal_alarm_callback() gets the current time (11:00:00 AM) and calls my_alarm_cb() as below. while ((ap = LIST_FIRST(&alarm_list)) !=NULL && gettimeofday(&now, NULL) == 0 && (ap->time.tv_sec < now.tv_sec || (ap->time.tv_sec == now.tv_sec && ap->time.tv_usec <= now.tv_usec))){ ap->executing = 1; ap->executing_id = pthread_self(); rte_spinlock_unlock(&alarm_list_lk); ap->cb_fn(ap->cb_arg); rte_spinlock_lock(&alarm_list_lk); LIST_REMOVE(ap, next); rte_free(ap); } In my_alarm_cb(), rte_eal_alarm_set() is called again. rte_eall_alarm_set() gets the current time (11:00:00 AM), plus 1 second, and adds the new alarm entry to alarm_list. /* use current time to calculate absolute time of alarm */ gettimeofday(&now, NULL); new_alarm->cb_fn = cb_fn; new_alarm->cb_arg = cb_arg; new_alarm->time.tv_usec = (now.tv_usec + us) % US_PER_S; new_alarm->time.tv_sec = now.tv_sec + ((now.tv_usec + us) / US_PER_S); rte_spinlock_lock(&alarm_list_lk); if (!handler_registered) { ret |= rte_intr_callback_register(&intr_handle, eal_alarm_callback, NULL); handler_registered = (ret == 0) ? 1 : 0; } if (LIST_EMPTY(&alarm_list)) LIST_INSERT_HEAD(&alarm_list, new_alarm, next); else { LIST_FOREACH(ap, &alarm_list, next) { if (ap->time.tv_sec > new_alarm->time.tv_sec || (ap->time.tv_sec == new_alarm->time.tv_sec && ap->time.tv_usec > new_alarm->time.tv_usec)){ LIST_INSERT_BEFORE(ap, new_alarm, next); break; } if (LIST_NEXT(ap, next) == NULL) { LIST_INSERT_AFTER(ap, new_alarm, next); break; } } } After the new alarm entry is added to alarm_list, if current time is set to 8:00:00 AM manually, the current time in eal_alarm_callback() will be updated to 8:00:00 AM, too. Then the new alarm entry will be triggered after 3 hours and 1 second. I think rte alarm should not be affected by discontinuous jumps in the system time. I tried to replace gettimeofday() with clock_gettime(CLOCK_MONOTONIC_RAW, &now), and it looks work fine. What do you think about this modification? Will you consider to modify rte_alarm functions to be not affected by discontinuous jumps in the system time?