From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from dpdk.org (dpdk.org [92.243.14.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 66F3DA04A5;
	Thu, 18 Jun 2020 00:15:57 +0200 (CEST)
Received: from [92.243.14.124] (localhost [127.0.0.1])
	by dpdk.org (Postfix) with ESMTP id EEFFF1252;
	Thu, 18 Jun 2020 00:15:56 +0200 (CEST)
Received: from mga01.intel.com (mga01.intel.com [192.55.52.88])
 by dpdk.org (Postfix) with ESMTP id 4582EFFA
 for <dev@dpdk.org>; Thu, 18 Jun 2020 00:15:55 +0200 (CEST)
IronPort-SDR: 9pkXsnetdhQZ4u3JDyaiSPPKIUVCtZG3iwxmwepGwub/BdV4tXZjr88dMUtdKtWRNUeHkx5fan
 nvDFifed5x8A==
X-Amp-Result: SKIPPED(no attachment in message)
X-Amp-File-Uploaded: False
Received: from fmsmga004.fm.intel.com ([10.253.24.48])
 by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 17 Jun 2020 15:15:54 -0700
IronPort-SDR: ttJwBE7hgNHFcn+rdVl4oNBFFhfc37+PTQMm9CdWu8h16haoOOcS8JmS/I9PBj2qe8d80numeR
 ZRFk2W3LFLyQ==
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.73,523,1583222400"; d="scan'208";a="299453164"
Received: from orsmsx101.amr.corp.intel.com ([10.22.225.128])
 by fmsmga004.fm.intel.com with ESMTP; 17 Jun 2020 15:15:54 -0700
Received: from [10.166.30.253] (10.166.30.253) by ORSMSX101.amr.corp.intel.com
 (10.22.225.128) with Microsoft SMTP Server (TLS) id 14.3.439.0;
 Wed, 17 Jun 2020 15:15:53 -0700
To: Fady Bader <fady@mellanox.com>, <dev@dpdk.org>
CC: <thomas@monjalon.net>, <tbashar@mellanox.com>, <talshn@mellanox.com>,
 <yohadt@mellanox.com>, <dmitry.kozliuk@gmail.com>,
 <harini.ramakrishnan@microsoft.com>, <ocardona@microsoft.com>,
 <pallavi.kadam@intel.com>
References: <20200423144350.4016-2-fady@mellanox.com>
 <20200617093915.16428-1-fady@mellanox.com>
 <20200617093915.16428-3-fady@mellanox.com>
From: Ranjit Menon <ranjit.menon@intel.com>
Message-ID: <ded7afaf-dfd3-420b-713e-da16a20418e0@intel.com>
Date: Wed, 17 Jun 2020 15:15:51 -0700
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101
 Thunderbird/68.8.1
MIME-Version: 1.0
In-Reply-To: <20200617093915.16428-3-fady@mellanox.com>
Content-Type: text/plain; charset="utf-8"; format=flowed
Content-Transfer-Encoding: 7bit
Content-Language: en-US
X-Originating-IP: [10.166.30.253]
Subject: Re: [dpdk-dev] [PATCH v9 2/2] timer: support EAL functions on
	Windows
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>


On 6/17/2020 2:39 AM, Fady Bader wrote:
> Implemented the needed Windows eal timer functions.
>
> Signed-off-by: Fady Bader <fady@mellanox.com>
> ---
>   lib/librte_eal/common/meson.build       |  1 +
>   lib/librte_eal/windows/eal.c            |  6 +++
>   lib/librte_eal/windows/eal_timer.c      | 91 +++++++++++++++++++++++++++++++++
>   lib/librte_eal/windows/include/rte_os.h |  2 +
>   lib/librte_eal/windows/meson.build      |  1 +
>   5 files changed, 101 insertions(+)
>   create mode 100644 lib/librte_eal/windows/eal_timer.c
>
> diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
> index 3108442697..4bdf77922f 100644
> --- a/lib/librte_eal/common/meson.build
> +++ b/lib/librte_eal/common/meson.build
> @@ -26,6 +26,7 @@ if is_windows
>   		'malloc_elem.c',
>   		'malloc_heap.c',
>   		'rte_malloc.c',
> +		'eal_common_timer.c',
>   	)
>   	subdir_done()
>   endif
> diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c
> index 427a5557fa..b6bffd3d92 100644
> --- a/lib/librte_eal/windows/eal.c
> +++ b/lib/librte_eal/windows/eal.c
> @@ -354,6 +354,12 @@ rte_eal_init(int argc, char **argv)
>   		return -1;
>   	}
>   
> +	if (rte_eal_timer_init() < 0) {
> +		rte_eal_init_alert("Cannot init TSC timer");
> +		rte_errno = EFAULT;
> +		return -1;
> +	}
> +
>   	eal_thread_init_master(rte_config.master_lcore);
>   
>   	RTE_LCORE_FOREACH_SLAVE(i) {
> diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c
> new file mode 100644
> index 0000000000..59099e8942
> --- /dev/null
> +++ b/lib/librte_eal/windows/eal_timer.c
> @@ -0,0 +1,91 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2020 Mellanox Technologies, Ltd
> + */
> +#include <inttypes.h>
> +
> +#include <rte_windows.h>
> +#include <rte_common.h>
> +#include <rte_cycles.h>
> +#include <rte_eal.h>
> +#include <rte_errno.h>
> +#include "eal_private.h"
> +
> +#define US_PER_SEC 1E6
> +#define CYC_PER_10MHZ 1E7
> +
> +void
> +rte_delay_us_sleep(unsigned int us)
> +{
> +	HANDLE timer;
> +	LARGE_INTEGER due_time;
> +
> +	/* create waitable timer */
> +	timer = CreateWaitableTimer(NULL, TRUE, NULL);
> +	if (!timer) {
> +		RTE_LOG_WIN32_ERR("CreateWaitableTimer()");
> +		rte_errno = ENOMEM;
> +		return;
> +	}
> +
> +	/*
> +	 * due_time's uom is 100 ns, multiply by 10 to convert to microseconds
> +	 * set us microseconds time for timer
> +	 */
> +	due_time.QuadPart = -((int64_t)us * 10);
> +	if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) {
> +		RTE_LOG_WIN32_ERR("SetWaitableTimer()");
> +		rte_errno = EINVAL;
> +		goto end;
> +	}
> +	/* start wait for timer for us microseconds */
> +	if (WaitForSingleObject(timer, INFINITE) == WAIT_FAILED) {
> +		RTE_LOG_WIN32_ERR("WaitForSingleObject()");
> +		rte_errno = EINVAL;
> +	}
> +
> +end:
> +	CloseHandle(timer);
> +}
> +
> +uint64_t
> +get_tsc_freq(void)
> +{
> +	LARGE_INTEGER t_start, t_end, elapsed_us;
> +	LARGE_INTEGER frequency;
> +	uint64_t tsc_hz;
> +	uint64_t end, start = rte_get_tsc_cycles();

I think a better implementation may be:

uint64_t start, end;

QueryPerformanceFrequency(&frequency);

start = rte_get_tsc_cycles();
QueryPerformanceCounter(&t_start);

rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */

.....

> +
> +	QueryPerformanceCounter(&t_start);
> +	QueryPerformanceFrequency(&frequency);
> +
> +	rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */
> +
> +	if (rte_errno != 0)
> +		return 0;
> +
> +	QueryPerformanceCounter(&t_end);
> +	end = rte_get_tsc_cycles();
> +
> +	elapsed_us.QuadPart = t_end.QuadPart - t_start.QuadPart;
> +
> +	/*
> +	 * To guard against loss-of-precision, convert to microseconds
> +	 * *before* dividing by ticks-per-second.
> +	 */
> +	elapsed_us.QuadPart *= US_PER_SEC;
> +	elapsed_us.QuadPart /= frequency.QuadPart;
> +
> +	double secs = ((double)elapsed_us.QuadPart)/US_PER_SEC;
> +	tsc_hz = (uint64_t)((end - start)/secs);
> +
> +	/* Round up to 10Mhz. 1E7 ~ 10Mhz */
> +	return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ);
> +}

[Snip]

ranjit m.