From patchwork Sat Mar 16 19:01:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavan Nikhilesh Bhagavatula X-Patchwork-Id: 51241 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A205011C5; Sat, 16 Mar 2019 20:02:00 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id 13CE611A4 for ; Sat, 16 Mar 2019 20:01:58 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x2GJ1wRA028185; Sat, 16 Mar 2019 12:01:58 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pfpt0818; bh=XdWFzKl2vK0mzte/PX+NtjFKefd7YLo+hjk5HkU251w=; b=Ala/65n5vVAAx6jjdGwcQzL5N+XUF1kc7GnJtUT7iLpuOk26LJn9Pt9FEtAJjLJ6RYjb KWIGmwYsEiprMTlXNmmh+UoufLX0pl2NY0TeSuE/eKfbLi6cDJQsGe80K9ykW9N3MjPK +Jc4OdQkce/GG2zofSNDEo7mH55SWGWMXcaUSPFVd+GQJit9lDBC7EngIhJmlc86P35L sH7sZz5fzexV6vsEavzbeE6CJfeCn2mjEdPOPdx7l81Bisp5U227ByCdQ//Sd9dQxLn6 349JSa6afPnmMwCF50X/ZTLpZP6GFaC/LjwIC5ugwNPodzhQnlwfDMxRAbsgeFJwcYrd 5w== Received: from sc-exch04.marvell.com ([199.233.58.184]) by mx0b-0016f401.pphosted.com with ESMTP id 2r90njgrnx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sat, 16 Mar 2019 12:01:58 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH04.marvell.com (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sat, 16 Mar 2019 12:01:55 -0700 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (104.47.38.57) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1367.3 via Frontend Transport; Sat, 16 Mar 2019 12:01:55 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.onmicrosoft.com; s=selector1-marvell-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XdWFzKl2vK0mzte/PX+NtjFKefd7YLo+hjk5HkU251w=; b=OjtMf2mFUtGYEgQ1MoJUIhFxXsSpbOCT9WZ3eu3vvoWTAvme3urNwvHNtC6Uz0DKXpEnpeRbvCpa7seFg4uV3FzL57mSi0QPKcsJtajI7DSrLK4hEmZihLhvzKLnWiiHpUjhQ4K8TVTi2wIfWuAMiZHESGX+V+ziX1oU+EbM804= Received: from CY4PR1801MB1863.namprd18.prod.outlook.com (10.171.255.14) by CY4PR1801MB1879.namprd18.prod.outlook.com (10.171.255.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1709.13; Sat, 16 Mar 2019 19:01:50 +0000 Received: from CY4PR1801MB1863.namprd18.prod.outlook.com ([fe80::286d:5e93:974e:8bfa]) by CY4PR1801MB1863.namprd18.prod.outlook.com ([fe80::286d:5e93:974e:8bfa%2]) with mapi id 15.20.1709.011; Sat, 16 Mar 2019 19:01:50 +0000 From: Pavan Nikhilesh Bhagavatula To: Jerin Jacob Kollanukkaran , "keith.wiles@intel.com" , "stephen@networkplumber.org" , "thomas@monjalon.net" CC: "dev@dpdk.org" , Pavan Nikhilesh Bhagavatula Thread-Topic: [dpdk-dev] [PATCH v3 1/2] eal: add macro to align value to the nearest multiple Thread-Index: AQHU3Cq1ZZdqtyPLD0aA7uJCQBFjSg== Date: Sat, 16 Mar 2019 19:01:50 +0000 Message-ID: <20190316190119.6142-1-pbhagavatula@marvell.com> References: <20181129083138.23029-1-pbhagavatula@caviumnetworks.com> In-Reply-To: <20181129083138.23029-1-pbhagavatula@caviumnetworks.com> Accept-Language: en-IN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BM1PR01CA0160.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:68::30) To CY4PR1801MB1863.namprd18.prod.outlook.com (2603:10b6:910:7a::14) x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.21.0 x-originating-ip: [115.113.156.3] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1e9e1b44-69dc-41b9-7c7a-08d6aa41d83c x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600127)(711020)(4605104)(2017052603328)(7153060)(7193020); SRVR:CY4PR1801MB1879; x-ms-traffictypediagnostic: CY4PR1801MB1879: x-microsoft-antispam-prvs: x-forefront-prvs: 09781D4C35 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(136003)(396003)(346002)(39850400004)(366004)(376002)(199004)(189003)(2616005)(476003)(6512007)(6436002)(446003)(11346002)(25786009)(86362001)(106356001)(99286004)(54906003)(66066001)(36756003)(186003)(6486002)(105586002)(76176011)(316002)(486006)(4326008)(26005)(55236004)(3846002)(102836004)(386003)(97736004)(6506007)(478600001)(8676002)(71190400001)(81156014)(6116002)(53936002)(68736007)(50226002)(110136005)(81166006)(14454004)(8936002)(52116002)(107886003)(2501003)(1076003)(5660300002)(305945005)(7736002)(2906002)(256004)(14444005)(2201001)(71200400001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR1801MB1879; H:CY4PR1801MB1863.namprd18.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: marvell.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: HwPQEWpWJ72A/yExAquTQcVGu69aRQAB+9gX66XOpKx9QdW1mjO3rXUH54+ZT0JTDKnoiW6ubvtEWoqpl11bkILt2rU2UqfliCviwwVhXiVx4PF2iwXYqk6QUU+iH32r874lq1TlgwD73bZRub0E7Y3NAlMCjxzpcUSVyQHb5UVvuuRmuWXMRyLxXTIGJzNv9LDj2019O7Qj+l/C5QWPc4in3k+uzpa09LE75TIUjymKJIogwMUviLVSsfXchPYttaD582PPQQQxvB0McjzXpV77HyKy9co5xmRU+gbE6Ak0RbeYZZJo/XjL8O0ZFMb4z7qHoD03TmUn/cLo2Jym565lrudk151xkHTBtOMzRD+WHcjfoEGIWa5V4+I9BCN8IZbipH5a0KWbBZAXlTotkTka/CJxscG4f/rAAu45cVY= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 1e9e1b44-69dc-41b9-7c7a-08d6aa41d83c X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Mar 2019 19:01:50.1425 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 70e1fb47-1155-421d-87fc-2e58f638b6e0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR1801MB1879 X-OriginatorOrg: marvell.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-03-16_15:, , signatures=0 Subject: [dpdk-dev] [PATCH v3 1/2] eal: add macro to align value to the nearest multiple X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Pavan Nikhilesh Add macro to align value to the nearest multiple of the given value, resultant value might be greater than or less than the first parameter whichever difference is the lowest. Update unit test to include the new macro. Signed-off-by: Pavan Nikhilesh --- v2 Changes: - Spilt patch and add unit test for the new macro. v3 Changes: - Rebase to ToT. - Use macro instead of 1E7. app/test/test_common.c | 4 ++++ lib/librte_eal/common/include/rte_common.h | 12 ++++++++++++ 2 files changed, 16 insertions(+) -- 2.21.0 diff --git a/app/test/test_common.c b/app/test/test_common.c index 94d367471..2b856f8ba 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -199,6 +199,10 @@ test_align(void) val = RTE_ALIGN_MUL_FLOOR(i, p); if (val % p != 0 || val > i) FAIL_ALIGN("RTE_ALIGN_MUL_FLOOR", i, p); + val = RTE_ALIGN_MUL_NEAR(i, p); + if (val % p != 0 || ((val != RTE_ALIGN_MUL_CEIL(i, p)) + & (val != RTE_ALIGN_MUL_FLOOR(i, p)))) + FAIL_ALIGN("RTE_ALIGN_MUL_NEAR", i, p); } } diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h index 7178ba1e9..bcf8afd39 100644 --- a/lib/librte_eal/common/include/rte_common.h +++ b/lib/librte_eal/common/include/rte_common.h @@ -248,6 +248,18 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) #define RTE_ALIGN_MUL_FLOOR(v, mul) \ ((v / ((typeof(v))(mul))) * (typeof(v))(mul)) +/** + * Macro to align value to the nearest multiple of the given value. + * The resultant value might be greater than or less than the first parameter + * whichever difference is the lowest. + */ +#define RTE_ALIGN_MUL_NEAR(v, mul) \ + ({ \ + typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul); \ + typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul); \ + (ceil - v) > (v - floor) ? floor : ceil; \ + }) + /** * Checks if a pointer is aligned to a given power-of-two value * From patchwork Sat Mar 16 19:01:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavan Nikhilesh Bhagavatula X-Patchwork-Id: 51242 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 54F63375B; Sat, 16 Mar 2019 20:02:10 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id 379A711A4 for ; Sat, 16 Mar 2019 20:02:09 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x2GJ259p028244; Sat, 16 Mar 2019 12:02:08 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pfpt0818; bh=RcTWcY+FnuhnygYn9/i/bKo11peNc8d3axk+QG7VM3o=; b=EALbcTTz8XmWvrlUy0TEQYdxqcmIclfgOUf5YrHQZlf1UVH4Rx+huVcItnLDaMYcx+Nv YVCDfAxp3EKnfliQLuh/rrOubeeRYEUfjcYuXyvqriTj9S7PAkEujRrfTA2oLWsBHNZN C954oOycdv0Ejf7cm6iL4wZ3+5PKeLnN2INEJsyR73X+hEm+B0TJEvujX1JHUu4nJLCM H6lW1JWzRmICW2kNIWGq5znFtEgkoxM5PY1HBNYfxWONsteUFiplQ8mTdfZBmlPMaQBu fwnd++8bq7oRZWH/6R+bRbc73+OuB7kbAsKiUbElxk4F664SFE3S250I1b66iuPQWIok 7w== Received: from sc-exch02.marvell.com ([199.233.58.182]) by mx0b-0016f401.pphosted.com with ESMTP id 2r90njgrpf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sat, 16 Mar 2019 12:02:08 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sat, 16 Mar 2019 12:01:56 -0700 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (104.47.38.57) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1367.3 via Frontend Transport; Sat, 16 Mar 2019 12:01:56 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.onmicrosoft.com; s=selector1-marvell-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RcTWcY+FnuhnygYn9/i/bKo11peNc8d3axk+QG7VM3o=; b=sY4DIzLR3PE9Dz+caNZw/vIXYO5z/5mTVSD3ej0PLiv79Fkf6QLL5w85nRUJdWUen+NY0Ub4PIqGbts5J9xfF/Cb7RHVxu8RFVN7RIbtcQGTXrf2esip1zepZ5x+UsEdWUS8+XgrWuju0wTMOFpnMRpgSpIEiRBAkMPW0XNTyhA= Received: from CY4PR1801MB1863.namprd18.prod.outlook.com (10.171.255.14) by CY4PR1801MB1879.namprd18.prod.outlook.com (10.171.255.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1709.13; Sat, 16 Mar 2019 19:01:54 +0000 Received: from CY4PR1801MB1863.namprd18.prod.outlook.com ([fe80::286d:5e93:974e:8bfa]) by CY4PR1801MB1863.namprd18.prod.outlook.com ([fe80::286d:5e93:974e:8bfa%2]) with mapi id 15.20.1709.011; Sat, 16 Mar 2019 19:01:54 +0000 From: Pavan Nikhilesh Bhagavatula To: Jerin Jacob Kollanukkaran , "keith.wiles@intel.com" , "stephen@networkplumber.org" , "thomas@monjalon.net" CC: "dev@dpdk.org" , Pavan Nikhilesh Bhagavatula Thread-Topic: [dpdk-dev] [PATCH v3 2/2] eal: roundup tsc frequency when estimating Thread-Index: AQHU3Cq4h55QmGkhokGXfqu7l8ONFA== Date: Sat, 16 Mar 2019 19:01:54 +0000 Message-ID: <20190316190119.6142-2-pbhagavatula@marvell.com> References: <20181129083138.23029-1-pbhagavatula@caviumnetworks.com> <20190316190119.6142-1-pbhagavatula@marvell.com> In-Reply-To: <20190316190119.6142-1-pbhagavatula@marvell.com> Accept-Language: en-IN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BM1PR01CA0160.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:68::30) To CY4PR1801MB1863.namprd18.prod.outlook.com (2603:10b6:910:7a::14) x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.21.0 x-originating-ip: [115.113.156.3] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 864fa42b-6c10-41ee-ccc0-08d6aa41da95 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600127)(711020)(4605104)(2017052603328)(7153060)(7193020); SRVR:CY4PR1801MB1879; x-ms-traffictypediagnostic: CY4PR1801MB1879: x-microsoft-antispam-prvs: x-forefront-prvs: 09781D4C35 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(136003)(396003)(346002)(39850400004)(366004)(376002)(199004)(189003)(2616005)(476003)(6512007)(6436002)(446003)(11346002)(25786009)(86362001)(106356001)(99286004)(54906003)(66066001)(36756003)(186003)(6486002)(105586002)(76176011)(316002)(486006)(4326008)(26005)(55236004)(3846002)(102836004)(386003)(97736004)(6506007)(478600001)(8676002)(71190400001)(81156014)(6116002)(53936002)(68736007)(50226002)(110136005)(81166006)(14454004)(8936002)(52116002)(107886003)(2501003)(1076003)(5660300002)(305945005)(7736002)(2906002)(256004)(14444005)(2201001)(71200400001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR1801MB1879; H:CY4PR1801MB1863.namprd18.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: marvell.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: vgZ1rL9B3/mUyUPGmtDrWoJr3hkIj+K2M3Z1b46Ha0En7Kxch1N1OUDnI8zEm0+3/BKcGsxD65kSCmzLVV3FEdBRGyiIR/D3NgsaNJyjvKz9WU3tgTh1YVGGut3K8eJRpmWGDEE8d2NGCclxN5+Uk0Fr6lpCnXfTr7M5BMoC4EZ7yDb/fjhlpt4l3KkJg4718xzoU/JUFBpLqBU3D47AfzuPYKVsJQ4YidZn5AcKcFhlSq5oB5jFb2H3Y39sCry1NJEORppGNdNm/PHrIXs0YCB5rcvWess0o0scW4CdgLzq5095GrXt6VoiQkyHAPRutxp/AXI4Kh/h99tpvdJRlj5OPjxilAsCQHHCX4Eyzrk/Xmh1XtiR3roUAymfdgOmLzH4Lgv4smBkVumjBHImfVKL6J1uFHREQNLa5aVE1gQ= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 864fa42b-6c10-41ee-ccc0-08d6aa41da95 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Mar 2019 19:01:54.1814 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 70e1fb47-1155-421d-87fc-2e58f638b6e0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR1801MB1879 X-OriginatorOrg: marvell.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-03-16_15:, , signatures=0 Subject: [dpdk-dev] [PATCH v3 2/2] eal: roundup tsc frequency when estimating X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Pavan Nikhilesh When estimating tsc frequency using sleep/gettime round it up to the nearest multiple of 10Mhz for more accuracy. Signed-off-by: Pavan Nikhilesh Reviewed-by: Keith Wiles --- Useful in case of ARM64 if we enable RTE_ARM_EAL_RDTSC_USE_PMU, get_tsc_freq_arch() will return 0 as there is no instruction to determine the clk of PMU and eal falls back to sleep(1). lib/librte_eal/common/eal_common_timer.c | 4 +++- lib/librte_eal/linux/eal/eal_timer.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) -- 2.21.0 diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c index dcf26bfea..68d67e684 100644 --- a/lib/librte_eal/common/eal_common_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -64,12 +64,14 @@ rte_get_tsc_hz(void) static uint64_t estimate_tsc_freq(void) { +#define CYC_PER_10MHZ 1E7 RTE_LOG(WARNING, EAL, "WARNING: TSC frequency estimated roughly" " - clock timings may be less accurate.\n"); /* assume that the sleep(1) will sleep for 1 second */ uint64_t start = rte_rdtsc(); sleep(1); - return rte_rdtsc() - start; + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ + return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ); } void diff --git a/lib/librte_eal/linux/eal/eal_timer.c b/lib/librte_eal/linux/eal/eal_timer.c index bc8f05199..76ec17034 100644 --- a/lib/librte_eal/linux/eal/eal_timer.c +++ b/lib/librte_eal/linux/eal/eal_timer.c @@ -232,6 +232,7 @@ get_tsc_freq(void) { #ifdef CLOCK_MONOTONIC_RAW #define NS_PER_SEC 1E9 +#define CYC_PER_10MHZ 1E7 struct timespec sleeptime = {.tv_nsec = NS_PER_SEC / 10 }; /* 1/10 second */ @@ -248,7 +249,8 @@ get_tsc_freq(void) double secs = (double)ns/NS_PER_SEC; tsc_hz = (uint64_t)((end - start)/secs); - return tsc_hz; + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ + return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ); } #endif return 0;