get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 104144,
    "url": "https://patches.dpdk.org/api/patches/104144/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1636594425-9692-8-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-8-git-send-email-navasile@linux.microsoft.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1636594425-9692-8-git-send-email-navasile@linux.microsoft.com",
    "date": "2021-11-11T01:33:44",
    "name": "[v18,7/8] eal: implement functions for thread barrier management",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "727eb2e0568a28fd57c403486c32691a2ea07b98",
    "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-8-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/104144/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/104144/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 125D4A0C4B;\n\tThu, 11 Nov 2021 02:35:38 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BC7F841176;\n\tThu, 11 Nov 2021 02:35:03 +0100 (CET)",
            "from linux.microsoft.com (linux.microsoft.com [13.77.154.182])\n by mails.dpdk.org (Postfix) with ESMTP id 3853E40E03\n for <dev@dpdk.org>; Thu, 11 Nov 2021 02:34:54 +0100 (CET)",
            "by linux.microsoft.com (Postfix, from userid 1059)\n id E1A3620C358A; Wed, 10 Nov 2021 17:34:52 -0800 (PST)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 linux.microsoft.com E1A3620C358A",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n s=default; t=1636594492;\n bh=OV5OTvfz5TC3XDe3okd6ei0TJfKRWsYa2ZMU9T1OxA8=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=E/rD3LxHKk2zodxcvQxdYmd5bhqoUpGSTJZ8NkZWWcBSTCIsVUGoJRQ2PPVlIOQil\n 0EfCKdiKbD/uG5xJEOAhaL/zNsoj/a0GOUcuQH84Zv19ypB+3Dog/isqandB+kJlfj\n 8//OxKxT8Fmp1IiQUovMaf4OOt3sB4KIGrUGjTts=",
        "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 7/8] eal: implement functions for thread barrier\n management",
        "Date": "Wed, 10 Nov 2021 17:33:44 -0800",
        "Message-Id": "<1636594425-9692-8-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 barrier init, destroy, wait.\n\nA portable type is used to represent a barrier identifier.\nThe rte_thread_barrier_wait() function returns the same value\non all platforms.\n\nAdd unit tests to verify that the barrier correctly\nsynchronizes all threads. Verify that the threads are unblocked\nafter the required number of threads have called barrier_wait().\n\nSigned-off-by: Narcisa Vasile <navasile@microsoft.com>\n---\n app/test/test_threads.c      | 49 +++++++++++++++++++++++++++++\n lib/eal/common/rte_thread.c  | 61 ++++++++++++++++++++++++++++++++++++\n lib/eal/include/rte_thread.h | 58 ++++++++++++++++++++++++++++++++++\n lib/eal/version.map          |  3 ++\n lib/eal/windows/rte_thread.c | 56 +++++++++++++++++++++++++++++++++\n 5 files changed, 227 insertions(+)",
    "diff": "diff --git a/app/test/test_threads.c b/app/test/test_threads.c\nindex 9fcae34179..00f604ab7e 100644\n--- a/app/test/test_threads.c\n+++ b/app/test/test_threads.c\n@@ -195,6 +195,54 @@ test_thread_detach(void)\n \treturn ret;\n }\n \n+struct thread_context {\n+\trte_thread_barrier *barrier;\n+\tint barrier_result;\n+};\n+\n+static void *\n+thread_loop_barrier(void *arg)\n+{\n+\tstruct thread_context *ctx = arg;\n+\n+\tctx->barrier_result = rte_thread_barrier_wait(ctx->barrier);\n+\tif (ctx->barrier_result > 0)\n+\t\trte_log(RTE_LOG_DEBUG, threads_logtype_test, \"Failed to wait at barrier!\");\n+\n+\treturn NULL;\n+}\n+\n+static int\n+test_thread_barrier(void)\n+{\n+\trte_thread_t thread_id;\n+\tstruct thread_context ctx;\n+\trte_thread_barrier barrier;\n+\tint ret = 0;\n+\tint result = 0;\n+\n+\tret = rte_thread_barrier_init(&barrier, 2);\n+\tRTE_TEST_ASSERT(ret == 0, \"Failed to initialize barrier!\");\n+\n+\tctx.barrier = &barrier;\n+\tret = rte_thread_create(&thread_id, NULL, thread_loop_barrier, &ctx);\n+\tRTE_TEST_ASSERT(ret == 0, \"Failed to create thread!\");\n+\n+\tresult = rte_thread_barrier_wait(&barrier);\n+\tRTE_TEST_ASSERT(result <= 0, \"Failed to wait at the barrier!\");\n+\n+\tret = rte_thread_join(thread_id, NULL);\n+\tRTE_TEST_ASSERT(ret == 0, \"Failed to join threads!\");\n+\n+\tret = rte_thread_barrier_destroy(&barrier);\n+\tRTE_TEST_ASSERT(ret == 0, \"Failed to destroy barrier!\");\n+\n+\tRTE_TEST_ASSERT(ctx.barrier_result <= 0, \"Child thread failed to wait at the barrier!\");\n+\tRTE_TEST_ASSERT_NOT_EQUAL(ctx.barrier_result, result, \"Threads were not blocked at the barrier!\");\n+\n+\treturn 0;\n+}\n+\n static struct unit_test_suite threads_test_suite = {\n \t.suite_name = \"threads autotest\",\n \t.setup = NULL,\n@@ -204,6 +252,7 @@ static struct unit_test_suite threads_test_suite = {\n \t\t\tTEST_CASE(test_thread_attributes_affinity),\n \t\t\tTEST_CASE(test_thread_attributes_priority),\n \t\t\tTEST_CASE(test_thread_detach),\n+\t\t\tTEST_CASE(test_thread_barrier),\n \t\t\tTEST_CASES_END()\n \t}\n };\ndiff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c\nindex 910c39eb88..d30a8a7ca3 100644\n--- a/lib/eal/common/rte_thread.c\n+++ b/lib/eal/common/rte_thread.c\n@@ -309,6 +309,67 @@ rte_thread_detach(rte_thread_t thread_id)\n \treturn pthread_detach((pthread_t)thread_id.opaque_id);\n }\n \n+int\n+rte_thread_barrier_init(rte_thread_barrier *barrier, int count)\n+{\n+\tint ret = 0;\n+\tpthread_barrier_t *pthread_barrier = NULL;\n+\n+\tRTE_VERIFY(barrier != NULL);\n+\tRTE_VERIFY(count > 0);\n+\n+\tpthread_barrier = calloc(1, sizeof(*pthread_barrier));\n+\tif (pthread_barrier == NULL) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Unable to initialize barrier. Insufficient memory!\\n\");\n+\t\tret = ENOMEM;\n+\t\tgoto cleanup;\n+\t}\n+\tret = pthread_barrier_init(pthread_barrier, NULL, count);\n+\tif (ret != 0) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Failed to init barrier, ret = %d\\n\", ret);\n+\t\tgoto cleanup;\n+\t}\n+\n+\tbarrier->barrier_id = pthread_barrier;\n+\tpthread_barrier = NULL;\n+\n+cleanup:\n+\tfree(pthread_barrier);\n+\treturn ret;\n+}\n+\n+int\n+rte_thread_barrier_wait(rte_thread_barrier *barrier)\n+{\n+\tint ret = 0;\n+\n+\tRTE_VERIFY(barrier != NULL);\n+\tRTE_VERIFY(barrier->barrier_id != NULL);\n+\n+\tret = pthread_barrier_wait(barrier->barrier_id);\n+\tif (ret == PTHREAD_BARRIER_SERIAL_THREAD)\n+\t\tret = RTE_THREAD_BARRIER_SERIAL_THREAD;\n+\n+\treturn ret;\n+}\n+\n+int\n+rte_thread_barrier_destroy(rte_thread_barrier *barrier)\n+{\n+\tint ret = 0;\n+\n+\tRTE_VERIFY(barrier != NULL);\n+\n+\tret = pthread_barrier_destroy(barrier->barrier_id);\n+\tif (ret != 0)\n+\t\tRTE_LOG(DEBUG, EAL, \"Failed to destroy barrier: %d\\n\", ret);\n+\n+\tfree(barrier->barrier_id);\n+\tbarrier->barrier_id = NULL;\n+\n+\treturn ret;\n+}\n+\n int\n rte_thread_key_create(rte_thread_key *key, void (*destructor)(void *))\n {\ndiff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h\nindex e841321819..7c84e32988 100644\n--- a/lib/eal/include/rte_thread.h\n+++ b/lib/eal/include/rte_thread.h\n@@ -54,6 +54,18 @@ typedef struct {\n \n #endif /* RTE_HAS_CPUSET */\n \n+/**\n+ * Returned by rte_thread_barrier_wait() when call is successful.\n+ */\n+#define RTE_THREAD_BARRIER_SERIAL_THREAD -1\n+\n+/**\n+ * Thread barrier representation.\n+ */\n+typedef struct rte_thread_barrier_tag {\n+\tvoid *barrier_id;  /**< barrrier identifier */\n+} rte_thread_barrier;\n+\n /**\n  * TLS key type, an opaque pointer.\n  */\n@@ -302,6 +314,52 @@ __rte_experimental\n int rte_thread_set_priority(rte_thread_t thread_id,\n \t\tenum rte_thread_priority priority);\n \n+/**\n+ * Initializes a synchronization barrier.\n+ *\n+ * @param barrier\n+ *    A pointer that references the newly created 'barrier' object.\n+ *\n+ * @param count\n+ *    The number of threads that must enter the barrier before\n+ *    the threads can continue execution.\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_barrier_init(rte_thread_barrier *barrier, int count);\n+\n+/**\n+ * Causes the calling thread to wait at the synchronization barrier 'barrier'.\n+ *\n+ * @param barrier\n+ *    The barrier used for synchronizing the threads.\n+ *\n+ * @return\n+ *   Return RTE_THREAD_BARRIER_SERIAL_THREAD for the thread synchronized\n+ *      at the barrier.\n+ *   Return 0 for all other threads.\n+ *   Return a positive errno-style error number, in case of failure.\n+ */\n+__rte_experimental\n+int rte_thread_barrier_wait(rte_thread_barrier *barrier);\n+\n+/**\n+ * Releases all resources used by a synchronization barrier\n+ * and uninitializes it.\n+ *\n+ * @param barrier\n+ *    The barrier to be destroyed.\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_barrier_destroy(rte_thread_barrier *barrier);\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 0384a09fa2..06e5f82da2 100644\n--- a/lib/eal/version.map\n+++ b/lib/eal/version.map\n@@ -427,6 +427,9 @@ EXPERIMENTAL {\n \trte_thread_attr_get_affinity;\n \trte_thread_attr_set_affinity;\n \trte_thread_attr_set_priority;\n+\trte_thread_barrier_init;\n+\trte_thread_barrier_wait;\n+\trte_thread_barrier_destroy;\n \trte_thread_get_affinity_by_id;\n \trte_thread_set_affinity_by_id;\n \trte_thread_get_priority;\ndiff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c\nindex 669a68d6a8..3f72bbf716 100644\n--- a/lib/eal/windows/rte_thread.c\n+++ b/lib/eal/windows/rte_thread.c\n@@ -504,6 +504,62 @@ rte_thread_detach(rte_thread_t thread_id)\n \treturn 0;\n }\n \n+int\n+rte_thread_barrier_init(rte_thread_barrier *barrier, int count)\n+{\n+\tint ret = 0;\n+\tSYNCHRONIZATION_BARRIER *sync_barrier = NULL;\n+\n+\tRTE_VERIFY(barrier != NULL);\n+\tRTE_VERIFY(count > 0);\n+\n+\tsync_barrier = calloc(1, sizeof(*sync_barrier));\n+\tif (sync_barrier == NULL) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Unable to initialize barrier. Insufficient memory!\\n\");\n+\t\tret = ENOMEM;\n+\t\tgoto cleanup;\n+\t}\n+\tif (!InitializeSynchronizationBarrier(sync_barrier, count, -1)) {\n+\t\tret = thread_log_last_error(\"InitializeSynchronizationBarrier()\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\tbarrier->barrier_id = sync_barrier;\n+\tsync_barrier = NULL;\n+\n+cleanup:\n+\tfree(sync_barrier);\n+\treturn ret;\n+}\n+\n+int\n+rte_thread_barrier_wait(rte_thread_barrier *barrier)\n+{\n+\tRTE_VERIFY(barrier != NULL);\n+\tRTE_VERIFY(barrier->barrier_id != NULL);\n+\n+\tif (EnterSynchronizationBarrier(barrier->barrier_id,\n+\t\t\t\tSYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)) {\n+\n+\t\treturn RTE_THREAD_BARRIER_SERIAL_THREAD;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_barrier_destroy(rte_thread_barrier *barrier)\n+{\n+\tRTE_VERIFY(barrier != NULL);\n+\n+\tDeleteSynchronizationBarrier(barrier->barrier_id);\n+\n+\tfree(barrier->barrier_id);\n+\tbarrier->barrier_id = NULL;\n+\n+\treturn 0;\n+}\n+\n int\n rte_thread_key_create(rte_thread_key *key,\n \t\t__rte_unused void (*destructor)(void *))\n",
    "prefixes": [
        "v18",
        "7/8"
    ]
}