From patchwork Thu Sep 24 11:12:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Alexander X-Patchwork-Id: 78673 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 060CAA04B1; Thu, 24 Sep 2020 13:12:44 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8B3501DDE8; Thu, 24 Sep 2020 13:12:43 +0200 (CEST) Received: from mail1.bemta25.messagelabs.com (mail1.bemta25.messagelabs.com [195.245.230.1]) by dpdk.org (Postfix) with ESMTP id 8DAED1DDE5 for ; Thu, 24 Sep 2020 13:12:42 +0200 (CEST) Received: from [100.112.194.193] (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256 bits)) by server-1.bemta.az-a.eu-west-1.aws.symcld.net id CC/E1-11775-A2F7C6F5; Thu, 24 Sep 2020 11:12:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnk+JIrShJLcpLzFFi42LJ0Oex0NWsz4k 3aD2tZvHu03YmB0aPXwuWsgYwRrFm5iXlVySwZsxrWclSMGEFY8WDJSdYGhjf9jF2MXJyMAos ZZaYdUS+i5ELyD7GInHw6392CGcPo8TNH21sIFUsAluZJXr++kEkeoAS3StYQBwhgblMEuffX WGFcB4zSqxcNYcFpIVNwERidusLZhBbREBA4nPnYrBRwgLpEnvm97BDjFWVOPliLVg9r4CDxK 0Nf8FsCQF5idUbDoD1MgtISBx8ATFHQmAyo8ScRRogtpCAlsSHJy2sEL2CEidnPoHq1ZH4u6g R6qCNTBJb7kMsQzZUQsBKYtrPxVANshJHz86Bsn2BvumEG3T4xQtWCLtA4toNkAUcQLaqRE+r OURYTuJU7zkmCFtGYuKeC+BQkRBYwixxZN4zdgjnDbPE0e0foZy/rBKvd8xng5gkLzHhmcQER s1ZSB6dheShBYxMqxgtkooy0zNKchMzc3QNDQx0DQ2NdA0tgdjYVC+xSjdRL7VUtzy1uETXUC +xvFivuDI3OSdFLy+1ZBMjMG2kFBxo38H46PUHvUOMkhxMSqK8G2py4oX4kvJTKjMSizPii0p zUosPMcpwcChJ8L6vBcoJFqWmp1akZeYAUxhMWoKDR0mEN64OKM1bXJCYW5yZDpE6xajLMeHl 3EXMQix5+XmpUuK8E0FmCIAUZZTmwY2ApdNLjLJSwryMDAwMQjwFqUW5mSWo8q8YxTkYlYR5C 0Gm8GTmlcBtegV0BBPQEaafM0COKElESEk1MAX3fgz9vTw2XWjp/85pWmy1rGyX3RNaiuY2bu mtyV7569Py5PWfV/zmilZ9vJNt51sR/WllrtO9lXTiJpS8EwlJYVzJ/fVebwxnQOAWzY9SB2u /tNUz9e2qcTT93FmwZ5JLXc3Op4xfTE5p/PjR0HMxTVPs8EbO/rlFZwu38HIqzXSK3bHMxIHp tvjETZY/GAMzp2s+DZWqMrdL/37DMaTk+/vPzHnnEjZrvebnZKo7VX+KwbH12Tlt6d4F/FylJ /P+39k3a4GJ+YwvAa8f+GUrbTjZuFJ2z4MOl2OZTCvf1F8RdqzLXPhl9fHlB7rSwrn877z8/b qv7PzPe0+Cnt9m8jp1tYnfJm3qlHSrPiWW4oxEQy3mouJEAOTmsNciBAAA X-Env-Sender: John.Alexander@datapath.co.uk X-Msg-Ref: server-36.tower-268.messagelabs.com!1600945960!1621987!1 X-Originating-IP: [104.47.12.56] X-SYMC-ESS-Client-Auth: mailfrom-relay-check=pass X-StarScan-Received: X-StarScan-Version: 9.60.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4358 invoked from network); 24 Sep 2020 11:12:41 -0000 Received: from mail-db3eur04lp2056.outbound.protection.outlook.com (HELO EUR04-DB3-obe.outbound.protection.outlook.com) (104.47.12.56) by server-36.tower-268.messagelabs.com with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 24 Sep 2020 11:12:41 -0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=H9fHeJLx20CiVkFGcvBDDoc/bwcsccHABX1CDRNrMIgSLF+8GcogH0CEdZzI5kyAYRoKCA/eLMxnYBv5UMOeiN2l3xprzeRtiXxvZrVfXCDG6VnibvKU+A5qrBTgBLRA4WHUFcFkBlwxKQnuYDixcv/Mpcvx/pmmQLFGxgEPlukCiQ3Zak1bdc3THKd6k109c7rXxP+vhbH0mU5H7a/z0V1xGM3LaLoZtgp3IrNosBax2JReJwuyZSLOk7Y4EXKvdGU1KCbZu+ogw5VqnY4ne7jlwh7Z5U/X03nMDz3hbEnLIdeKxIfZYcbAulpXAHxXkYzxxju/znPYRbl8G+mBIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/NGOZ+3HyY8vtmy9Nd9mO8OCivOLUbwihs1nf7+Covw=; b=cO03+xqAaE7scY6h6XlCHbLaXSmnnevquTnb0JN6ijKVP3sW0gGXsOaEunBuFDYSn4TVK7wLO6N9e5isEgNzmvUqdVBlJEdK+MUy1jE4GhzDqCznhoInX9s6tRg+3xeaYS65E2+hRWO4Zyp5pDIbnStRgErXLt+GkuQ2t2gRBCUvqop/Rq5jmU24VXli8NmCCOL8gVN9qlUA2T1dCGN1OCtSw04V1Vdchrfl8vd82nBHTh/FVdoPZBgsg/7Ex8SL0ZimkUSZGh1Bo0q8gnfcv95M9pSOw1v/m9yVbswigJxrM1YxOkr9i4A1hz8RHusXLJ4zX4KYmk8T88N62QRBhQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=datapath.co.uk; dmarc=pass action=none header.from=datapath.co.uk; dkim=pass header.d=datapath.co.uk; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=datapathuk.onmicrosoft.com; s=selector2-datapathuk-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/NGOZ+3HyY8vtmy9Nd9mO8OCivOLUbwihs1nf7+Covw=; b=TUUftTMSTQ+2d0MQT2UBTWrg+WI8QAofr80gPhinfIZuL+MSwI6fqISk2c2/uoVYzDVxW274ZRM5Shfc9aIlxnLVHDXxmu5Pp8Nz8CZvNbqUXHavwV2zIRJNvhHtvjVmKH88otEVHekBnJmR+cIjoQEGv/YMzIg9I/lHwOOFkVo= Received: from DB6PR0902MB2072.eurprd09.prod.outlook.com (2603:10a6:6:8::23) by DB6PR0902MB1911.eurprd09.prod.outlook.com (2603:10a6:6:f::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.20; Thu, 24 Sep 2020 11:12:39 +0000 Received: from DB6PR0902MB2072.eurprd09.prod.outlook.com ([fe80::78ee:d583:2874:a01f]) by DB6PR0902MB2072.eurprd09.prod.outlook.com ([fe80::78ee:d583:2874:a01f%3]) with mapi id 15.20.3391.027; Thu, 24 Sep 2020 11:12:39 +0000 From: John Alexander To: dev@dpdk.org Date: Thu, 24 Sep 2020 12:12:15 +0100 Message-Id: <20200924111215.118-1-john.alexander@datapath.co.uk> X-Mailer: git-send-email 2.17.1 X-ClientProxiedBy: LO2P265CA0122.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:9f::14) To DB6PR0902MB2072.eurprd09.prod.outlook.com (2603:10a6:6:8::23) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2a00:23c4:403:e001:edf5:5cec:68ea:5c63) by LO2P265CA0122.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:9f::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.20 via Frontend Transport; Thu, 24 Sep 2020 11:12:38 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [2a00:23c4:403:e001:edf5:5cec:68ea:5c63] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1e52fddd-33f1-4242-df19-08d8607abfa1 X-MS-TrafficTypeDiagnostic: DB6PR0902MB1911: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:635; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 0eb0CrLO13RJl4rPrt3+VydTNmB94nwjOd3uBWDPLFEnIuTmODq+uv5KzyWM8WcTIn5JhiAp2fBwOIJb2Z1lvVnes6tjslWbENil0atpUjLS4fA3ZQgDA2PqEE7QHYhtAxPlg77ngjPHpwZ4s7Bbm3JUUw70OnD4fbZuPFtFZQzi4wfoiibJj6UvrXdIdi4EFfj0C5eGXbMYryaK5Q4TpBvYI8+N6WnPUXrMxM6BVdaAtN8UXum5XNZ82fG/tN7sGb2KQZLk5sU0MTgdxDX3SAyfbLVIKnZzzOtzoxM384ZegJ5nylJgdKDB4qhLyIXyQCfpXX8mmKKSkkOujoTzmlNXM2QLF1WKqRMq5CbAvvPNoZ7lsJrgCGAQvs4OW/jk X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DB6PR0902MB2072.eurprd09.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(396003)(39840400004)(346002)(376002)(136003)(1076003)(186003)(316002)(30864003)(36756003)(478600001)(86362001)(6916009)(6512007)(6506007)(45080400002)(6486002)(5660300002)(66476007)(2906002)(52116002)(16526019)(83380400001)(6666004)(8676002)(69590400008)(66556008)(2616005)(66946007)(44832011)(8936002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: Xp+Ub2OO6bvnWDq35NIOGOv9dJ6NSUQvgCefetnxB34Z3soDnljZFhLEUaa+G7McvV75dKueQKjh1QXOFGn00ihMSg8k8jkxuOeW5qRcNkhKOTo7wrHR4ufN9ca4EhMmIYzzEgQEDFB2VK+GYHkXn0+zqiDbclI/0Wak+cVL9W39EBK1gYQGUQyZB7DKqMcKmSmrK41GP3fl6lFNY4dmWFVVMrsJGVZN6cQ3lroRkCYaR7kxFeMlz/9AloCdYLzUxUIJGISkIV5wUKzu1n7eGeV9TOPVdalUOvkRfKJCgS9SLyCRsPunUWA0eGYLUUXjJDQiwHqhHcn9L4nX6ysGFa4ck5cIpikaX8i4wB3mjbdWTxQWeGcAeaGRZoNjj4VUiK+9x+fVJUrh1YE8IXi1ny9U+PETwDjhdxcZAWsPgcPdFHDGE1f4piEDpsCj1RzQc2mF6pTWdB71MyiuxZgtrRj6oBU3C0/nvgIGfTLe9rdNi5KXgM5NhkZfQJHN6zA10Xu7xFqqz0w82Pd779N6sQKK8MwKsgnRKsoIz7cEfCaPO79+Jqt3KLgQ9nYFd6tF3oY4uxEfTbOP2RiET2Wn12It5S/ceq9FA2CYGf0VYWLlmGeHBILK5ZwgOFsL7Aqfesix7sYiYjbp/DObs9FYKVutigP7loJbiJYAxkjBFni/NA/Bk5nPDseW52/W+M5CPP/g/joNl0IwdvqnlbSYdQ== X-OriginatorOrg: datapath.co.uk X-MS-Exchange-CrossTenant-Network-Message-Id: 1e52fddd-33f1-4242-df19-08d8607abfa1 X-MS-Exchange-CrossTenant-AuthSource: DB6PR0902MB2072.eurprd09.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Sep 2020 11:12:39.1927 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 102e0f24-523c-4823-a9ce-5a8ebc4e32a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6D0xwpYWjZSmvwjqb//+x0WC6ulCHYHB9hGBoEqhd1rDn2F34BF6AJkXgdoLBFYSvW14ZantaSywSG6kFFGIq2Dg2skZI/0+XLfiCfe/6vs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0902MB1911 Subject: [dpdk-dev] [PATCH] eal/windows: Switched to an external pthreads library, pulled in as a meson subproject 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" The Windows EAL build now pulls in the pthreads4w project as an external subproject. The pthreads4w subproject does not currently provide a meson build so the project has been patched with one. Removed the placeholder librte_eal\windows\include\pthread.h and sched.h header files as these are superseded by the pthreads4w implementation. rte_eal_init() in the Windows EAL has been modified to use pthread_create() and pthread_setaffinity_np() to setup the secondary lcores. eal_thread_create() has been removed as it is no longer required. rte_eal_init() in the Windows EAL now calls SetPriorityClass() to set the process class to real-time in a singular location. eal_thread_loop() in the Windows EAL now calls SetThreadPriority() to set the thread priority to real-time when the thread commences execution. This function now uses pthreads functions to test and compare pthread_t handles. Added the source file librte_eal\windows\windows_eal_impl.c. This source file serves as a location for the implementation of auxillary functionality provided by the Windows EAL that would otherwise be provided by the UNIX runtime. Added the pthreads4w shared library as a dependency to EAL library builds for Windows builds only. The meson install step will install the pthreads4w.dll that is built by the meson external subproject build step. The shared library has been selected for both static and shared library builds to avoid constructior initialisation issues observed when using pthreads4w and static linkage within the DPDK project. Added the subprojects folder to the .gitignore file such that authoered content is not ignored and downloaded content is ignored (as that's where meson stores the subprojects when they are cloned). Incremented the minimum meson version number to 0.55.0. This is required to use the subproject folder patch feature. Updated MAINTAINERS to reflect new additions. --- .gitignore | 6 + MAINTAINERS | 3 + lib/librte_eal/windows/eal.c | 21 ++- lib/librte_eal/windows/eal_thread.c | 27 +--- lib/librte_eal/windows/eal_windows.h | 10 -- lib/librte_eal/windows/include/pthread.h | 146 ------------------ lib/librte_eal/windows/include/rte_os.h | 15 +- lib/librte_eal/windows/include/sched.h | 92 ----------- lib/librte_eal/windows/meson.build | 1 + lib/librte_eal/windows/windows_eal_impl.c | 56 +++++++ lib/meson.build | 14 +- meson.build | 7 +- .../packagefiles/pthreads4w-meson/VERSION | 1 + .../packagefiles/pthreads4w-meson/meson.build | 49 ++++++ subprojects/pthreads4w-code.wrap | 8 + 15 files changed, 181 insertions(+), 275 deletions(-) delete mode 100644 lib/librte_eal/windows/include/pthread.h delete mode 100644 lib/librte_eal/windows/include/sched.h create mode 100644 lib/librte_eal/windows/windows_eal_impl.c create mode 100644 subprojects/packagefiles/pthreads4w-meson/VERSION create mode 100644 subprojects/packagefiles/pthreads4w-meson/meson.build create mode 100644 subprojects/pthreads4w-code.wrap diff --git a/.gitignore b/.gitignore index f73d93ca5..3792a843b 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,9 @@ build-* # ignore other build directory patterns *-gcc* *-clang* + +# ignore sub-directories of the subprojects directory excluding wrap files and the packagefiles directory +subprojects/**/* +!subprojects/*.wrap +!subprojects/packagefiles/ +!subprojects/packagefiles/** diff --git a/MAINTAINERS b/MAINTAINERS index c0abbe0fc..c33c1bc72 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -318,10 +318,13 @@ M: Dmitry Kozlyuk M: Narcisa Ana Maria Vasile M: Dmitry Malloy M: Pallavi Kadam +M: John Alexander F: lib/librte_eal/windows/ +F: lib/librte_eal/windows/windows_eal_impl.c F: lib/librte_eal/rte_eal_exports.def F: buildtools/map_to_win.py F: doc/guides/windows_gsg/ +F: subprojects/ Windows memory allocation M: Dmitry Kozlyuk diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index bc48f27ab..86121dc6a 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -260,7 +260,7 @@ rte_eal_cleanup(void) int rte_eal_init(int argc, char **argv) { - int i, fctret, bscan; + int i, fctret, bscan, ret; const struct rte_config *config = rte_eal_get_configuration(); struct internal_config *internal_conf = eal_get_internal_configuration(); @@ -360,6 +360,15 @@ rte_eal_init(int argc, char **argv) return -1; } + /* + * We require real-time priority threads. To achieve this on Windows we must + * set the current process class to real-time. Setting the process class to + * real-time requires elevated privileges (admin user) otherwise the maximum + * achievable thread priority will still only be 15 (out of 31) even with + * real-time thread priority and real-time process class set. + */ + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + RTE_LCORE_FOREACH_SLAVE(i) { /* @@ -376,8 +385,16 @@ rte_eal_init(int argc, char **argv) lcore_config[i].state = WAIT; /* create a thread for each lcore */ - if (eal_thread_create(&lcore_config[i].thread_id) != 0) + /* create a thread for each lcore */ + ret = pthread_create(&lcore_config[i].thread_id, NULL, + eal_thread_loop, NULL); + if (ret != 0) rte_panic("Cannot create thread\n"); + + ret = pthread_setaffinity_np(lcore_config[i].thread_id, + sizeof(rte_cpuset_t), &lcore_config[i].cpuset); + if (ret != 0) + rte_panic("Cannot set affinity\n"); } /* Initialize services so drivers can register services during probe. */ diff --git a/lib/librte_eal/windows/eal_thread.c b/lib/librte_eal/windows/eal_thread.c index 20889b619..24b68d184 100644 --- a/lib/librte_eal/windows/eal_thread.c +++ b/lib/librte_eal/windows/eal_thread.c @@ -3,6 +3,7 @@ */ #include +#include #include #include @@ -66,9 +67,11 @@ eal_thread_loop(void *arg __rte_unused) thread_id = pthread_self(); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + /* retrieve our lcore_id from the configuration structure */ RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (thread_id == lcore_config[lcore_id].thread_id) + if (pthread_equal(thread_id, lcore_config[lcore_id].thread_id)) break; } if (lcore_id == RTE_MAX_LCORE) @@ -79,8 +82,8 @@ eal_thread_loop(void *arg __rte_unused) __rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset); - RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s])\n", - lcore_id, (uintptr_t)thread_id, cpuset); + RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s])\n", + lcore_id, thread_id, cpuset); /* read on our pipe to get commands */ while (1) { @@ -122,24 +125,6 @@ eal_thread_loop(void *arg __rte_unused) } } -/* function to create threads */ -int -eal_thread_create(pthread_t *thread) -{ - HANDLE th; - - th = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE)(ULONG_PTR)eal_thread_loop, - NULL, 0, (LPDWORD)thread); - if (!th) - return -1; - - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - SetThreadPriority(th, THREAD_PRIORITY_TIME_CRITICAL); - - return 0; -} - /* get current thread ID */ int rte_sys_gettid(void) diff --git a/lib/librte_eal/windows/eal_windows.h b/lib/librte_eal/windows/eal_windows.h index d48ee0a12..dfd3801ff 100644 --- a/lib/librte_eal/windows/eal_windows.h +++ b/lib/librte_eal/windows/eal_windows.h @@ -35,16 +35,6 @@ */ int eal_create_cpu_map(void); -/** - * Create a thread. - * - * @param thread - * The location to store the thread id if successful. - * @return - * 0 for success, -1 if the thread is not created. - */ -int eal_thread_create(pthread_t *thread); - /** * Get system NUMA node number for a socket ID. * diff --git a/lib/librte_eal/windows/include/pthread.h b/lib/librte_eal/windows/include/pthread.h deleted file mode 100644 index 99013dc94..000000000 --- a/lib/librte_eal/windows/include/pthread.h +++ /dev/null @@ -1,146 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019 Intel Corporation - */ - -#ifndef _PTHREAD_H_ -#define _PTHREAD_H_ - -#include -#include - -/** - * This file is required to support the common code in eal_common_proc.c, - * eal_common_thread.c and common\include\rte_per_lcore.h as Microsoft libc - * does not contain pthread.h. This may be removed in future releases. - */ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#define PTHREAD_BARRIER_SERIAL_THREAD TRUE - -/* defining pthread_t type on Windows since there is no in Microsoft libc*/ -typedef uintptr_t pthread_t; - -/* defining pthread_attr_t type on Windows since there is no in Microsoft libc*/ -typedef void *pthread_attr_t; - -typedef SYNCHRONIZATION_BARRIER pthread_barrier_t; - -#define pthread_barrier_init(barrier, attr, count) \ - InitializeSynchronizationBarrier(barrier, count, -1) -#define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier, \ - SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) -#define pthread_barrier_destroy(barrier) \ - DeleteSynchronizationBarrier(barrier) -#define pthread_cancel(thread) TerminateThread((HANDLE) thread, 0) - -/* pthread function overrides */ -#define pthread_self() \ - ((pthread_t)GetCurrentThreadId()) - -static inline int -pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size, - rte_cpuset_t *cpuset) -{ - DWORD_PTR ret = 0; - HANDLE thread_handle; - - if (cpuset == NULL || cpuset_size == 0) - return -1; - - thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid); - if (thread_handle == NULL) { - RTE_LOG_WIN32_ERR("OpenThread()"); - return -1; - } - - ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits); - if (ret == 0) { - RTE_LOG_WIN32_ERR("SetThreadAffinityMask()"); - goto close_handle; - } - -close_handle: - if (CloseHandle(thread_handle) == 0) { - RTE_LOG_WIN32_ERR("CloseHandle()"); - return -1; - } - return (ret == 0) ? -1 : 0; -} - -static inline int -pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size, - rte_cpuset_t *cpuset) -{ - /* Workaround for the lack of a GetThreadAffinityMask() - *API in Windows - */ - DWORD_PTR prev_affinity_mask; - HANDLE thread_handle; - DWORD_PTR ret = 0; - - if (cpuset == NULL || cpuset_size == 0) - return -1; - - thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid); - if (thread_handle == NULL) { - RTE_LOG_WIN32_ERR("OpenThread()"); - return -1; - } - - /* obtain previous mask by setting dummy mask */ - prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1); - if (prev_affinity_mask == 0) { - RTE_LOG_WIN32_ERR("SetThreadAffinityMask()"); - goto close_handle; - } - - /* set it back! */ - ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask); - if (ret == 0) { - RTE_LOG_WIN32_ERR("SetThreadAffinityMask()"); - goto close_handle; - } - - memset(cpuset, 0, cpuset_size); - *cpuset->_bits = prev_affinity_mask; - -close_handle: - if (CloseHandle(thread_handle) == 0) { - RTE_LOG_WIN32_ERR("SetThreadAffinityMask()"); - return -1; - } - return (ret == 0) ? -1 : 0; -} - -static inline int -pthread_create(void *threadid, const void *threadattr, void *threadfunc, - void *args) -{ - RTE_SET_USED(threadattr); - HANDLE hThread; - hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, - args, 0, (LPDWORD)threadid); - if (hThread) { - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); - } - return ((hThread != NULL) ? 0 : E_FAIL); -} - -static inline int -pthread_join(__rte_unused pthread_t thread, - __rte_unused void **value_ptr) -{ - return 0; -} - -#ifdef __cplusplus -} -#endif - -#endif /* _PTHREAD_H_ */ diff --git a/lib/librte_eal/windows/include/rte_os.h b/lib/librte_eal/windows/include/rte_os.h index 569ed92d5..1d551d9b7 100644 --- a/lib/librte_eal/windows/include/rte_os.h +++ b/lib/librte_eal/windows/include/rte_os.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -43,10 +44,22 @@ extern "C" { #define unlink _unlink /* cpu_set macros implementation */ +typedef cpu_set_t rte_cpuset_t; #define RTE_CPU_AND(dst, src1, src2) CPU_AND(dst, src1, src2) #define RTE_CPU_OR(dst, src1, src2) CPU_OR(dst, src1, src2) #define RTE_CPU_FILL(set) CPU_FILL(set) -#define RTE_CPU_NOT(dst, src) CPU_NOT(dst, src) +void RTE_CPU_ANDNOT(cpu_set_t * dst, cpu_set_t * src); +void RTE_CPU_COPY(cpu_set_t * from, cpu_set_t *to); +void RTE_CPU_FILL(cpu_set_t *pdestset); +#define RTE_CPU_NOT(dst, src) do \ +{ \ + cpu_set_t tmp; \ + RTE_CPU_FILL(&tmp); \ + RTE_CPU_ANDNOT(&tmp, src); \ + RTE_CPU_COPY(&tmp, dst); \ +} while (0) + + /* as in */ typedef long long ssize_t; diff --git a/lib/librte_eal/windows/include/sched.h b/lib/librte_eal/windows/include/sched.h deleted file mode 100644 index fbe07f742..000000000 --- a/lib/librte_eal/windows/include/sched.h +++ /dev/null @@ -1,92 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019 Intel Corporation - */ - -#ifndef _SCHED_H_ -#define _SCHED_H_ - -/** - * This file is added to support the common code in eal_common_thread.c - * as Microsoft libc does not contain sched.h. This may be removed - * in future releases. - */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CPU_SETSIZE -#define CPU_SETSIZE RTE_MAX_LCORE -#endif - -#define _BITS_PER_SET (sizeof(long long) * 8) -#define _BIT_SET_MASK (_BITS_PER_SET - 1) - -#define _NUM_SETS(b) (((b) + _BIT_SET_MASK) / _BITS_PER_SET) -#define _WHICH_SET(b) ((b) / _BITS_PER_SET) -#define _WHICH_BIT(b) ((b) & (_BITS_PER_SET - 1)) - -typedef struct _rte_cpuset_s { - long long _bits[_NUM_SETS(CPU_SETSIZE)]; -} rte_cpuset_t; - -#define CPU_SET(b, s) ((s)->_bits[_WHICH_SET(b)] |= (1LL << _WHICH_BIT(b))) - -#define CPU_ZERO(s) \ - do { \ - unsigned int _i; \ - \ - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ - (s)->_bits[_i] = 0LL; \ - } while (0) - -#define CPU_ISSET(b, s) (((s)->_bits[_WHICH_SET(b)] & \ - (1LL << _WHICH_BIT(b))) != 0LL) - -static inline int -count_cpu(rte_cpuset_t *s) -{ - unsigned int _i; - int count = 0; - - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) - if (CPU_ISSET(_i, s) != 0LL) - count++; - return count; -} -#define CPU_COUNT(s) count_cpu(s) - -#define CPU_AND(dst, src1, src2) \ -do { \ - unsigned int _i; \ - \ - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ - (dst)->_bits[_i] = (src1)->_bits[_i] & (src2)->_bits[_i]; \ -} while (0) - -#define CPU_OR(dst, src1, src2) \ -do { \ - unsigned int _i; \ - \ - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ - (dst)->_bits[_i] = (src1)->_bits[_i] | (src2)->_bits[_i]; \ -} while (0) - -#define CPU_FILL(s) \ -do { \ - unsigned int _i; \ - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ - (s)->_bits[_i] = -1LL; \ -} while (0) - -#define CPU_NOT(dst, src) \ -do { \ - unsigned int _i; \ - for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ - (dst)->_bits[_i] = (src)->_bits[_i] ^ -1LL; \ -} while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* _SCHED_H_ */ diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build index b690bc6b0..9f5b7839a 100644 --- a/lib/librte_eal/windows/meson.build +++ b/lib/librte_eal/windows/meson.build @@ -18,6 +18,7 @@ sources += files( 'eal_timer.c', 'fnmatch.c', 'getopt.c', + 'windows_eal_impl.c' ) dpdk_conf.set10('RTE_EAL_NUMA_AWARE_HUGEPAGES', true) diff --git a/lib/librte_eal/windows/windows_eal_impl.c b/lib/librte_eal/windows/windows_eal_impl.c new file mode 100644 index 000000000..a8ddd9eb6 --- /dev/null +++ b/lib/librte_eal/windows/windows_eal_impl.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Datapath Limited + */ + +#include "eal_windows.h" + +pid_t +getpid() +{ + return GetCurrentProcessId(); +} + +void +RTE_CPU_FILL(cpu_set_t *pdestset) +{ + SYSTEM_INFO system_info; + memset(&system_info, 0, sizeof(system_info)); + + GetSystemInfo(&system_info); + + int masked_so_far = 0; + int index = 0; + do + { + unsigned char mask = 0xFF; + + if ((masked_so_far + 8) > system_info.dwNumberOfProcessors) + { + int mask_shift = (masked_so_far + 8) - system_info.dwNumberOfProcessors; + mask = mask >> mask_shift; + } + + pdestset->cpuset[index] = mask; + + masked_so_far += 8; + index++; + } while (masked_so_far < system_info.dwNumberOfProcessors); +} + +void +RTE_CPU_ANDNOT(cpu_set_t *dst, cpu_set_t *src) +{ + int set_index; + for (set_index = 0; + set_index < _countof(dst->cpuset); + set_index++) + { + dst->cpuset[set_index] = ~(dst->cpuset[set_index] & src->cpuset[set_index]); + } +} + +void +RTE_CPU_COPY(cpu_set_t *from, cpu_set_t *to) +{ + memcpy(to, from, sizeof(cpu_set_t)); +} diff --git a/lib/meson.build b/lib/meson.build index d8b358e5f..fd154ec5d 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -43,6 +43,11 @@ if is_windows 'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', ] # only supported libraries for windows + + # Windows doesn't natively support pthreads so we pull down an external project + # using the meson subproject feature. + pthreads4w_proj = subproject('pthreads4w-code') + pthreads4w_shared_dep = pthreads4w_proj.get_variable('pthreads4w_shared_dep') endif default_cflags = machine_args @@ -82,6 +87,12 @@ foreach l:libraries if build shared_deps = ext_deps static_deps = ext_deps + if is_windows + # Initialisation issues with the external pthreads library when linked with + # DPDK require us to always use the shared build of the pthreads4w library. + shared_deps += pthreads4w_shared_dep + static_deps += pthreads4w_shared_dep + endif foreach d:deps if not is_variable('shared_rte_' + d) error('Missing internal dependency "@0@" for @1@ [@2@]' @@ -153,8 +164,7 @@ foreach l:libraries output: '@0@_mingw.map'.format(libname)) if is_ms_linker - lk_args = ['-Wl,/def:' + def_file.full_path(), - '-Wl,/implib:lib\\' + implib] + lk_args = ['-Wl,/def:' + def_file.full_path()] else if is_windows lk_args = ['-Wl,--version-script=' + mingw_map.full_path()] diff --git a/meson.build b/meson.build index 61d9a4f5f..9e061c73b 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project('DPDK', 'C', files('VERSION')).stdout().strip(), license: 'BSD', default_options: ['buildtype=release', 'default_library=static'], - meson_version: '>= 0.47.1' + meson_version: '>= 0.55.0' ) # set up some global vars for compiler, platform, configuration, etc. @@ -44,6 +44,11 @@ global_inc = include_directories('.', 'config', subdir('buildtools') subdir('config') +if is_windows + # Windows builds do not define this but it is required so we define it globally here. + add_global_arguments('-D_POSIX_C_SOURCE=200809L', language: 'c') +endif + # build libs and drivers subdir('buildtools/pmdinfogen') subdir('lib') diff --git a/subprojects/packagefiles/pthreads4w-meson/VERSION b/subprojects/packagefiles/pthreads4w-meson/VERSION new file mode 100644 index 000000000..4a36342fc --- /dev/null +++ b/subprojects/packagefiles/pthreads4w-meson/VERSION @@ -0,0 +1 @@ +3.0.0 diff --git a/subprojects/packagefiles/pthreads4w-meson/meson.build b/subprojects/packagefiles/pthreads4w-meson/meson.build new file mode 100644 index 000000000..738a51133 --- /dev/null +++ b/subprojects/packagefiles/pthreads4w-meson/meson.build @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2020 Datapath Limited + +project('pthreads4w', 'C', + # Fallback to "more" for Windows compatibility. + version: run_command(find_program('cat', 'more'), + files('VERSION')).stdout().strip(), + license: 'APACHE2.0', + default_options: ['buildtype=release', 'default_library=static'], + meson_version: '>= 0.55.0' +) + +sources = files( + 'pthread.c' +) + +objs = [] +cflags = ['-DHAVE_CONFIG_H'] + +# The static library is built differently to ensure the process attach/detach and thread attach/detach operate correctly. +cflags_static = cflags +cflags_static += '-D__PTW32_STATIC_LIB' +pthreads4w_static_lib = static_library('pthreads4w', + sources, + objects: objs, + c_args: cflags_static, + install: true) + +pthreads4w_shared_lib = shared_library('pthreads4w', + sources, + objects: objs, + c_args: cflags, + implib: true, + install: true) + +pthreads4w_static_dep = declare_dependency( + include_directories: '', + link_with : pthreads4w_static_lib) + +pthreads4w_shared_dep = declare_dependency( + include_directories: '', + link_with : pthreads4w_shared_lib) + +install_headers( + 'pthread.h', + '_ptw32.h', + 'sched.h', + 'semaphore.h') + diff --git a/subprojects/pthreads4w-code.wrap b/subprojects/pthreads4w-code.wrap new file mode 100644 index 000000000..d2215e5ce --- /dev/null +++ b/subprojects/pthreads4w-code.wrap @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2020 Datapath Limited + +[wrap-git] +directory=pthreads4w +url=git://git.code.sf.net/p/pthreads4w/code +revision=Version-3-0-0-release +patch_directory=pthreads4w-meson