From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6FEF6A0A0F; Sat, 5 Jun 2021 01:45:09 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9D01740DDB; Sat, 5 Jun 2021 01:44:44 +0200 (CEST) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id C29F040147 for ; Sat, 5 Jun 2021 01:44:37 +0200 (CEST) Received: by linux.microsoft.com (Postfix, from userid 1059) id 76D2120B8010; Fri, 4 Jun 2021 16:44:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 76D2120B8010 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1622850276; bh=XaBfFtPpOaS0AX46LLyoag8KKodmAQC5OcDRFTS2Uo4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E6E5geelh27y3pxru1DmzQCLgxh9G2JItheSVBWOTJR/A9N1fEsJefYnLSCezNC0l noV8C7HQjhEflubnUsaNVpWU/aq2i42F3GrtWcj4MgOXkjjcF1ZHN/Iji5lkd31Y67 AC19NiTZ1RFuvq42g3z0GFS3mUii+0FKzz0NHXKQ= From: Narcisa Ana Maria Vasile To: dev@dpdk.org, thomas@monjalon.net, dmitry.kozliuk@gmail.com, khot@microsoft.com, navasile@microsoft.com, dmitrym@microsoft.com, roretzla@microsoft.com, talshn@nvidia.com, ocardona@microsoft.com Cc: bruce.richardson@intel.com, david.marchand@redhat.com, pallavi.kadam@intel.com Date: Fri, 4 Jun 2021 16:44:29 -0700 Message-Id: <1622850274-6946-6-git-send-email-navasile@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1622850274-6946-1-git-send-email-navasile@linux.microsoft.com> References: <1622849908-5710-1-git-send-email-navasile@linux.microsoft.com> <1622850274-6946-1-git-send-email-navasile@linux.microsoft.com> Subject: [dpdk-dev] [PATCH v9 05/10] eal: implement thread priority management functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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: Narcisa Vasile Add function for setting the priority for a thread. Priorities on multiple platforms are similarly determined by a priority value and a priority class/policy. On Linux, the following mapping is created: RTE_THREAD_PRIORITY_NORMAL corresponds to * policy SCHED_OTHER * priority value: (sched_get_priority_min(SCHED_OTHER) + sched_get_priority_max(SCHED_OTHER))/2; RTE_THREAD_PRIORITY_REALTIME_CRITICAL corresponds to * policy SCHED_RR * priority value: sched_get_priority_max(SCHED_RR); On Windows, the following mapping is created: RTE_THREAD_PRIORITY_NORMAL corresponds to * class NORMAL_PRIORITY_CLASS * priority THREAD_PRIORITY_NORMAL RTE_THREAD_PRIORITY_REALTIME_CRITICAL corresponds to * class REALTIME_PRIORITY_CLASS * priority THREAD_PRIORITY_TIME_CRITICAL Signed-off-by: Narcisa Vasile --- lib/eal/common/rte_thread.c | 51 ++++++++++ lib/eal/include/rte_thread.h | 17 ++++ lib/eal/include/rte_thread_types.h | 3 - .../include/rte_windows_thread_types.h | 3 - lib/eal/windows/rte_thread.c | 92 +++++++++++++++++++ 5 files changed, 160 insertions(+), 6 deletions(-) diff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c index ceb27feaa7..5cee19bb7d 100644 --- a/lib/eal/common/rte_thread.c +++ b/lib/eal/common/rte_thread.c @@ -48,6 +48,57 @@ rte_thread_get_affinity_by_id(rte_thread_t thread_id, return pthread_getaffinity_np(thread_id.opaque_id, sizeof(*cpuset), cpuset); } +static int +thread_map_priority_to_os_value(enum rte_thread_priority eal_pri, int *os_pri, int *pol) +{ + RTE_VERIFY(os_pri != NULL); + RTE_VERIFY(pol != NULL); + + /* Clear the output parameters */ + *os_pri = sched_get_priority_min(SCHED_OTHER) - 1; + *pol = -1; + + switch (eal_pri) + { + case RTE_THREAD_PRIORITY_NORMAL: + *pol = SCHED_OTHER; + + /* + * Choose the middle of the range to represent + * the priority 'normal'. + * On Linux, this should be 0, since both + * sched_get_priority_min/_max return 0 for SCHED_OTHER. + */ + *os_pri = (sched_get_priority_min(SCHED_OTHER) + + sched_get_priority_max(SCHED_OTHER))/2; + break; + case RTE_THREAD_PRIORITY_REALTIME_CRITICAL: + *pol = SCHED_RR; + *os_pri = sched_get_priority_max(SCHED_RR); + break; + default: + RTE_LOG(DEBUG, EAL, "The requested priority value is invalid.\n"); + return EINVAL; + } + return 0; +} + +int +rte_thread_set_priority(rte_thread_t thread_id, + enum rte_thread_priority priority) +{ + int ret; + int policy; + struct sched_param param; + + ret = thread_map_priority_to_os_value(priority, ¶m.sched_priority, &policy); + if (ret != 0) { + return ret; + } + + return pthread_setschedparam(thread_id.opaque_id, policy, ¶m); +} + int rte_thread_attr_init(rte_thread_attr_t *attr) { diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h index 1f02962146..5c54cd9d67 100644 --- a/lib/eal/include/rte_thread.h +++ b/lib/eal/include/rte_thread.h @@ -122,6 +122,23 @@ __rte_experimental int rte_thread_get_affinity_by_id(rte_thread_t thread_id, rte_cpuset_t *cpuset); +/** + * Set the priority of a thread. + * + * @param thread_id + * Id of the thread for which to set priority. + * + * @param priority + * Priority value to be set. + * + * @return + * On success, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_set_priority(rte_thread_t thread_id, + enum rte_thread_priority priority); + /** * Initialize the attributes of a thread. * These attributes can be passed to the rte_thread_create() function diff --git a/lib/eal/include/rte_thread_types.h b/lib/eal/include/rte_thread_types.h index 996232c636..d67b24a563 100644 --- a/lib/eal/include/rte_thread_types.h +++ b/lib/eal/include/rte_thread_types.h @@ -7,7 +7,4 @@ #include -#define EAL_THREAD_PRIORITY_NORMAL 0 -#define EAL_THREAD_PRIORITY_REALTIME_CIRTICAL 99 - #endif /* _RTE_THREAD_TYPES_H_ */ diff --git a/lib/eal/windows/include/rte_windows_thread_types.h b/lib/eal/windows/include/rte_windows_thread_types.h index 5bdeaad3d4..60e6d94553 100644 --- a/lib/eal/windows/include/rte_windows_thread_types.h +++ b/lib/eal/windows/include/rte_windows_thread_types.h @@ -7,7 +7,4 @@ #include -#define EAL_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL -#define EAL_THREAD_PRIORITY_REALTIME_CIRTICAL THREAD_PRIORITY_TIME_CRITICAL - #endif /* _RTE_THREAD_TYPES_H_ */ diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c index 9e74a538c2..6dc3d575c0 100644 --- a/lib/eal/windows/rte_thread.c +++ b/lib/eal/windows/rte_thread.c @@ -202,6 +202,98 @@ rte_thread_get_affinity_by_id(rte_thread_t thread_id, return ret; } +static HANDLE +get_process_handle_from_thread_handle(HANDLE thread_handle) +{ + DWORD process_id = 0; + + process_id = GetProcessIdOfThread(thread_handle); + if (process_id == 0) { + RTE_LOG_WIN32_ERR("GetProcessIdOfThread()"); + return NULL; + } + + return OpenProcess(PROCESS_SET_INFORMATION, FALSE, process_id); +} + +static int +thread_map_priority_to_os_value(enum rte_thread_priority eal_pri, + int *os_pri, int *pri_class) +{ + RTE_VERIFY(os_pri != NULL); + RTE_VERIFY(pri_class != NULL); + + /* Clear the output parameters */ + *os_pri = -1; + *pri_class = -1; + + switch (eal_pri) + { + case RTE_THREAD_PRIORITY_NORMAL: + *pri_class = NORMAL_PRIORITY_CLASS; + *os_pri = THREAD_PRIORITY_NORMAL; + break; + case RTE_THREAD_PRIORITY_REALTIME_CRITICAL: + *pri_class = REALTIME_PRIORITY_CLASS; + *os_pri = THREAD_PRIORITY_TIME_CRITICAL; + break; + default: + RTE_LOG(DEBUG, EAL, "The requested priority value is invalid.\n"); + return EINVAL; + } + + return 0; +} + +int +rte_thread_set_priority(rte_thread_t thread_id, + enum rte_thread_priority priority) +{ + HANDLE thread_handle = NULL; + HANDLE process_handle = NULL; + int priority_class = NORMAL_PRIORITY_CLASS; + int os_priority = THREAD_PRIORITY_NORMAL; + int ret = 0; + + thread_handle = OpenThread(THREAD_SET_INFORMATION | + THREAD_QUERY_INFORMATION, FALSE, thread_id.opaque_id); + if (thread_handle == NULL) { + ret = thread_log_last_error("OpenThread()"); + goto cleanup; + } + + ret = thread_map_priority_to_os_value(priority, &os_priority, &priority_class); + if (ret != 0) { + return ret; + } + process_handle = get_process_handle_from_thread_handle(thread_handle); + if (process_handle == NULL) { + ret = thread_log_last_error("OpenProcess()"); + goto cleanup; + } + + if (!SetPriorityClass(process_handle, priority_class)) { + ret = thread_log_last_error("SetPriorityClass()"); + goto cleanup; + } + + if (!SetThreadPriority(thread_handle, os_priority)) { + ret = thread_log_last_error("SetThreadPriority()"); + goto cleanup; + } + +cleanup: + if (thread_handle != NULL) { + CloseHandle(thread_handle); + thread_handle = NULL; + } + if (process_handle != NULL) { + CloseHandle(process_handle); + process_handle = NULL; + } + return ret; +} + int rte_thread_attr_init(rte_thread_attr_t *attr) { -- 2.31.0.vfs.0.1