get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/104143/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 104143,
    "url": "https://patches.dpdk.org/api/patches/104143/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1636594425-9692-6-git-send-email-navasile@linux.microsoft.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1636594425-9692-6-git-send-email-navasile@linux.microsoft.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1636594425-9692-6-git-send-email-navasile@linux.microsoft.com",
    "date": "2021-11-11T01:33:42",
    "name": "[v18,5/8] eal: implement thread priority management functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5beb792fa884b677dbb94fb99a2216dc48d0c739",
    "submitter": {
        "id": 1668,
        "url": "https://patches.dpdk.org/api/people/1668/?format=api",
        "name": "Narcisa Ana Maria Vasile",
        "email": "navasile@linux.microsoft.com"
    },
    "delegate": {
        "id": 24651,
        "url": "https://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1636594425-9692-6-git-send-email-navasile@linux.microsoft.com/mbox/",
    "series": [
        {
            "id": 20472,
            "url": "https://patches.dpdk.org/api/series/20472/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=20472",
            "date": "2021-11-11T01:33:40",
            "name": "eal: Add EAL API for threading",
            "version": 18,
            "mbox": "https://patches.dpdk.org/series/20472/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/104143/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/104143/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1CB5BA0C4B;\n\tThu, 11 Nov 2021 02:35:33 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id D746E41169;\n\tThu, 11 Nov 2021 02:35:02 +0100 (CET)",
            "from linux.microsoft.com (linux.microsoft.com [13.77.154.182])\n by mails.dpdk.org (Postfix) with ESMTP id 4805F410F7\n for <dev@dpdk.org>; Thu, 11 Nov 2021 02:34:54 +0100 (CET)",
            "by linux.microsoft.com (Postfix, from userid 1059)\n id CA9BB20C3583; Wed, 10 Nov 2021 17:34:52 -0800 (PST)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 linux.microsoft.com CA9BB20C3583",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n s=default; t=1636594492;\n bh=XNcxcpW82wsjqfdq11hwRNHJEgairwx+bA4euoiEK+4=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=UUdzpFoNO8bKvIGh7TmV5LBW6L7PMKQNTJFiG0Zc3T5F7QcLomjLzUtKq/9ieccnF\n 9U4JIkWPJVbdERBi6ZXzraUqBMzTny7Aul1E5XID7B+vHjqNgv1F1Pv6KBIA06I3s8\n m3BH6vMu7A674lr5Ch2RLvzmBAi3vIWbt/O978RI=",
        "From": "Narcisa Ana Maria Vasile <navasile@linux.microsoft.com>",
        "To": "dev@dpdk.org, thomas@monjalon.net, dmitry.kozliuk@gmail.com,\n khot@microsoft.com, navasile@microsoft.com, dmitrym@microsoft.com,\n roretzla@microsoft.com, talshn@nvidia.com, ocardona@microsoft.com",
        "Cc": "bruce.richardson@intel.com, david.marchand@redhat.com,\n pallavi.kadam@intel.com",
        "Subject": "[PATCH v18 5/8] eal: implement thread priority management functions",
        "Date": "Wed, 10 Nov 2021 17:33:42 -0800",
        "Message-Id": "<1636594425-9692-6-git-send-email-navasile@linux.microsoft.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1636594425-9692-1-git-send-email-navasile@linux.microsoft.com>",
        "References": "<1636513302-7359-1-git-send-email-navasile@linux.microsoft.com>\n <1636594425-9692-1-git-send-email-navasile@linux.microsoft.com>",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Narcisa Vasile <navasile@microsoft.com>\n\nAdd functions for setting and getting the priority of a thread.\nPriorities on multiple platforms are similarly determined by\na priority value and a priority class/policy.\n\nCurrently in DPDK most threads operate at the OS-default\npriority level but there are cases when increasing the\npriority is useful. For example, high performance applications\nmay require elevated priority levels.\n\nFor these reasons, EAL will expose two priority levels which\nare named suggestively \"normal\" and \"realtime_critical\"\nand are computed as follows:\n\nOn Linux, the following mapping is created:\nRTE_THREAD_PRIORITY_NORMAL corresponds to\n* policy SCHED_OTHER\n* priority value:   (sched_get_priority_min(SCHED_OTHER) +\n                     sched_get_priority_max(SCHED_OTHER))/2;\nRTE_THREAD_PRIORITY_REALTIME_CRITICAL corresponds to\n* policy SCHED_RR\n* priority value: sched_get_priority_max(SCHED_RR);\n\nOn Windows, the following mapping is created:\nRTE_THREAD_PRIORITY_NORMAL corresponds to\n* class NORMAL_PRIORITY_CLASS\n* priority THREAD_PRIORITY_NORMAL\nRTE_THREAD_PRIORITY_REALTIME_CRITICAL corresponds to\n* class REALTIME_PRIORITY_CLASS\n* priority THREAD_PRIORITY_TIME_CRITICAL\n\nNote that on Linux the resulting priority value will be 0,\nin accordance to the docs that mention the value\nshould be 0 for SCHED_OTHER policy.\n\nSigned-off-by: Narcisa Vasile <navasile@microsoft.com>\n---\n lib/eal/common/rte_thread.c  | 103 ++++++++++++++++++++++++++++\n lib/eal/include/rte_thread.h |  34 ++++++++++\n lib/eal/version.map          |   2 +\n lib/eal/windows/rte_thread.c | 127 +++++++++++++++++++++++++++++++++++\n 4 files changed, 266 insertions(+)",
    "diff": "diff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c\nindex 73b7b3141c..fc5d7c5b1a 100644\n--- a/lib/eal/common/rte_thread.c\n+++ b/lib/eal/common/rte_thread.c\n@@ -50,6 +50,109 @@ rte_thread_get_affinity_by_id(rte_thread_t thread_id,\n \t\tsizeof(*cpuset), cpuset);\n }\n \n+static int\n+thread_map_priority_to_os_value(enum rte_thread_priority eal_pri,\n+\t\tint *os_pri, int *pol)\n+{\n+\t/* Clear the output parameters */\n+\t*os_pri = sched_get_priority_min(SCHED_OTHER) - 1;\n+\t*pol = -1;\n+\n+\tswitch (eal_pri) {\n+\tcase RTE_THREAD_PRIORITY_NORMAL:\n+\t\t*pol = SCHED_OTHER;\n+\n+\t\t/*\n+\t\t * Choose the middle of the range to represent\n+\t\t * the priority 'normal'.\n+\t\t * On Linux, this should be 0, since both\n+\t\t * sched_get_priority_min/_max return 0 for SCHED_OTHER.\n+\t\t */\n+\t\t*os_pri = (sched_get_priority_min(SCHED_OTHER) +\n+\t\t\tsched_get_priority_max(SCHED_OTHER))/2;\n+\t\tbreak;\n+\tcase RTE_THREAD_PRIORITY_REALTIME_CRITICAL:\n+\t\t*pol = SCHED_RR;\n+\t\t*os_pri = sched_get_priority_max(SCHED_RR);\n+\t\tbreak;\n+\tdefault:\n+\t\tRTE_LOG(DEBUG, EAL, \"The requested priority value is invalid.\\n\");\n+\t\treturn EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+thread_map_os_priority_to_eal_priority(int policy, int os_pri,\n+\t\tenum rte_thread_priority *eal_pri)\n+{\n+\tswitch (policy) {\n+\tcase SCHED_OTHER:\n+\t\tif (os_pri == (sched_get_priority_min(SCHED_OTHER) +\n+\t\t\t\tsched_get_priority_max(SCHED_OTHER))/2) {\n+\t\t\t*eal_pri = RTE_THREAD_PRIORITY_NORMAL;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tbreak;\n+\tcase SCHED_RR:\n+\t\tif (os_pri == sched_get_priority_max(SCHED_RR)) {\n+\t\t\t*eal_pri = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tRTE_LOG(DEBUG, EAL, \"The OS priority value does not map to an EAL-defined priority.\\n\");\n+\t\treturn EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_get_priority(rte_thread_t thread_id,\n+\t\tenum rte_thread_priority *priority)\n+{\n+\tint ret;\n+\tint policy;\n+\tstruct sched_param param;\n+\n+\tret = pthread_getschedparam((pthread_t)thread_id.opaque_id, &policy,\n+\t\t\t&param);\n+\tif (ret != 0) {\n+\t\tRTE_LOG(DEBUG, EAL, \"pthread_getschedparam failed\\n\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\treturn thread_map_os_priority_to_eal_priority(policy,\n+\t\t\tparam.sched_priority, priority);\n+\n+cleanup:\n+\treturn ret;\n+}\n+\n+int\n+rte_thread_set_priority(rte_thread_t thread_id,\n+\t\tenum rte_thread_priority priority)\n+{\n+\tint ret;\n+\tint policy;\n+\tstruct sched_param param;\n+\n+/* Realtime priority can cause crashes on non-Windows platforms. */\n+#ifndef RTE_EXEC_ENV_WINDOWS\n+\tif (priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL)\n+\t\treturn ENOTSUP;\n+#endif\n+\n+\tret = thread_map_priority_to_os_value(priority, &param.sched_priority,\n+\t\t&policy);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\treturn pthread_setschedparam((pthread_t)thread_id.opaque_id,\n+\t\tpolicy, &param);\n+}\n+\n int\n rte_thread_attr_init(rte_thread_attr_t *attr)\n {\ndiff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h\nindex 5b100cafda..7077c9ce46 100644\n--- a/lib/eal/include/rte_thread.h\n+++ b/lib/eal/include/rte_thread.h\n@@ -213,6 +213,40 @@ void rte_thread_get_affinity(rte_cpuset_t *cpusetp);\n \n #endif /* RTE_HAS_CPUSET */\n \n+/**\n+ * Get the priority of a thread.\n+ *\n+ * @param thread_id\n+ *    Id of the thread for which to get priority.\n+ *\n+ * @param priority\n+ *   Location to store the retrieved priority.\n+ *\n+ * @return\n+ *   On success, return 0.\n+ *   On failure, return a positive errno-style error number.\n+ */\n+__rte_experimental\n+int rte_thread_get_priority(rte_thread_t thread_id,\n+\t\tenum rte_thread_priority *priority);\n+\n+/**\n+ * Set the priority of a thread.\n+ *\n+ * @param thread_id\n+ *    Id of the thread for which to set priority.\n+ *\n+ * @param priority\n+ *   Priority value to be set.\n+ *\n+ * @return\n+ *   On success, return 0.\n+ *   On failure, return a positive errno-style error number.\n+ */\n+__rte_experimental\n+int rte_thread_set_priority(rte_thread_t thread_id,\n+\t\tenum rte_thread_priority priority);\n+\n /**\n  * Create a TLS data key visible to all threads in the process.\n  * the created key is later used to get/set a value.\ndiff --git a/lib/eal/version.map b/lib/eal/version.map\nindex 193a79a4d2..5bc5a6cf76 100644\n--- a/lib/eal/version.map\n+++ b/lib/eal/version.map\n@@ -429,6 +429,8 @@ EXPERIMENTAL {\n \trte_thread_attr_set_priority;\n \trte_thread_get_affinity_by_id;\n \trte_thread_set_affinity_by_id;\n+\trte_thread_get_priority;\n+\trte_thread_set_priority;\n };\n \n INTERNAL {\ndiff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c\nindex 0127119f49..5c02a6eaff 100644\n--- a/lib/eal/windows/rte_thread.c\n+++ b/lib/eal/windows/rte_thread.c\n@@ -200,6 +200,133 @@ rte_thread_get_affinity_by_id(rte_thread_t thread_id,\n \treturn ret;\n }\n \n+static int\n+thread_map_priority_to_os_value(enum rte_thread_priority eal_pri,\n+\t\tint *os_pri, int *pri_class)\n+{\n+\t/* Clear the output parameters */\n+\t*os_pri = -1;\n+\t*pri_class = -1;\n+\n+\tswitch (eal_pri) {\n+\tcase RTE_THREAD_PRIORITY_NORMAL:\n+\t\t*pri_class = NORMAL_PRIORITY_CLASS;\n+\t\t*os_pri = THREAD_PRIORITY_NORMAL;\n+\t\tbreak;\n+\tcase RTE_THREAD_PRIORITY_REALTIME_CRITICAL:\n+\t\t*pri_class = REALTIME_PRIORITY_CLASS;\n+\t\t*os_pri = THREAD_PRIORITY_TIME_CRITICAL;\n+\t\tbreak;\n+\tdefault:\n+\t\tRTE_LOG(DEBUG, EAL, \"The requested priority value is invalid.\\n\");\n+\t\treturn EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+thread_map_os_priority_to_eal_value(int os_pri, int pri_class,\n+\t\tenum rte_thread_priority *eal_pri)\n+{\n+\tswitch (pri_class) {\n+\tcase NORMAL_PRIORITY_CLASS:\n+\t\tif (os_pri == THREAD_PRIORITY_NORMAL) {\n+\t\t\t*eal_pri = RTE_THREAD_PRIORITY_NORMAL;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tbreak;\n+\tcase REALTIME_PRIORITY_CLASS:\n+\t\tif (os_pri == THREAD_PRIORITY_TIME_CRITICAL) {\n+\t\t\t*eal_pri = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tRTE_LOG(DEBUG, EAL, \"The OS priority value does not map to an EAL-defined priority.\\n\");\n+\t\treturn EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_get_priority(rte_thread_t thread_id,\n+\t\tenum rte_thread_priority *priority)\n+{\n+\tHANDLE thread_handle = NULL;\n+\tDWORD pri_class;\n+\tint os_pri;\n+\tint ret;\n+\n+\tpri_class = GetPriorityClass(GetCurrentProcess());\n+\tif (pri_class == 0) {\n+\t\tret = thread_log_last_error(\"GetPriorityClass()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tthread_handle = OpenThread(THREAD_SET_INFORMATION |\n+\t\t\tTHREAD_QUERY_INFORMATION, FALSE, thread_id.opaque_id);\n+\tif (thread_handle == NULL) {\n+\t\tret = thread_log_last_error(\"OpenThread()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tos_pri = GetThreadPriority(thread_handle);\n+\tif (os_pri == THREAD_PRIORITY_ERROR_RETURN) {\n+\t\tret = thread_log_last_error(\"GetThreadPriority()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tret = thread_map_os_priority_to_eal_value(os_pri, pri_class, priority);\n+\tif (ret != 0)\n+\t\tgoto cleanup;\n+\n+cleanup:\n+\tif (thread_handle != NULL)\n+\t\tCloseHandle(thread_handle);\n+\n+\treturn ret;\n+}\n+\n+int\n+rte_thread_set_priority(rte_thread_t thread_id,\n+\t\t\tenum rte_thread_priority priority)\n+{\n+\tHANDLE thread_handle;\n+\tint priority_class;\n+\tint os_priority;\n+\tint ret = 0;\n+\n+\tthread_handle = OpenThread(THREAD_SET_INFORMATION |\n+\t\tTHREAD_QUERY_INFORMATION, FALSE,\n+\t\tthread_id.opaque_id);\n+\tif (thread_handle == NULL) {\n+\t\tret = thread_log_last_error(\"OpenThread()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tret = thread_map_priority_to_os_value(priority, &os_priority,\n+\t\t&priority_class);\n+\tif (ret != 0)\n+\t\tgoto cleanup;\n+\n+\tif (!SetPriorityClass(GetCurrentProcess(), priority_class)) {\n+\t\tret = thread_log_last_error(\"SetPriorityClass()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tif (!SetThreadPriority(thread_handle, os_priority)) {\n+\t\tret = thread_log_last_error(\"SetThreadPriority()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+cleanup:\n+\tif (thread_handle != NULL)\n+\t\tCloseHandle(thread_handle);\n+\n+\treturn ret;\n+}\n+\n int\n rte_thread_attr_init(rte_thread_attr_t *attr)\n {\n",
    "prefixes": [
        "v18",
        "5/8"
    ]
}