get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 51025,
    "url": "https://patches.dpdk.org/api/patches/51025/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1552283564-113385-2-git-send-email-joyce.kong@arm.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": "<1552283564-113385-2-git-send-email-joyce.kong@arm.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1552283564-113385-2-git-send-email-joyce.kong@arm.com",
    "date": "2019-03-11T05:52:43",
    "name": "[v5,1/2] eal/ticketlock: ticket based to improve fairness",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "510542a87e86da1be602be4df28178889a367686",
    "submitter": {
        "id": 970,
        "url": "https://patches.dpdk.org/api/people/970/?format=api",
        "name": "Joyce Kong",
        "email": "joyce.kong@arm.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1552283564-113385-2-git-send-email-joyce.kong@arm.com/mbox/",
    "series": [
        {
            "id": 3693,
            "url": "https://patches.dpdk.org/api/series/3693/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=3693",
            "date": "2019-03-11T05:52:42",
            "name": "ticketlock: implement ticketlock and add test case",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/3693/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/51025/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/51025/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 003154C94;\n\tMon, 11 Mar 2019 06:53:51 +0100 (CET)",
            "from foss.arm.com (foss.arm.com [217.140.101.70])\n\tby dpdk.org (Postfix) with ESMTP id 4367D4C8E\n\tfor <dev@dpdk.org>; Mon, 11 Mar 2019 06:53:50 +0100 (CET)",
            "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249])\n\tby usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A5100374;\n\tSun, 10 Mar 2019 22:53:49 -0700 (PDT)",
            "from net-arm-thunderx2.shanghai.arm.com\n\t(net-arm-thunderx2.shanghai.arm.com [10.169.40.121])\n\tby usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id\n\t353DB3F575; Sun, 10 Mar 2019 22:53:48 -0700 (PDT)"
        ],
        "From": "Joyce Kong <joyce.kong@arm.com>",
        "To": "dev@dpdk.org",
        "Cc": "nd@arm.com, thomas@monjalon.net, jerin.jacob@caviumnetworks.com,\n\tstephen@networkplumber.org, honnappa.nagarahalli@arm.com,\n\tgavin.hu@arm.com, Joyce kong <joyce.kong@arm.com>",
        "Date": "Mon, 11 Mar 2019 13:52:43 +0800",
        "Message-Id": "<1552283564-113385-2-git-send-email-joyce.kong@arm.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": [
            "<1552283564-113385-1-git-send-email-joyce.kong@arm.com>",
            "<1550573288-148384-2-git-send-email-joyce.kong@arm.com>"
        ],
        "References": [
            "<1552283564-113385-1-git-send-email-joyce.kong@arm.com>",
            "<1550573288-148384-2-git-send-email-joyce.kong@arm.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH v5 1/2] eal/ticketlock: ticket based to improve\n\tfairness",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The spinlock implementation is unfair, some threads may take locks\naggressively while leaving the other threads starving for long time.\n\nThis patch introduces ticketlock which gives each waiting thread a\nticket and they can take the lock one by one. First come, first serviced.\nThis avoids starvation for too long time and is more predictable.\n\nSuggested-by: Jerin Jacob <jerinj@marvell.com>\nSigned-off-by: Joyce kong <joyce.kong@arm.com>\nReviewed-by: Gavin Hu <gavin.hu@arm.com>\nReviewed-by: Ola Liljedahl <ola.liljedahl@arm.com>\nReviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>\n---\n MAINTAINERS                                        |   4 +\n doc/api/doxy-api-index.md                          |   1 +\n lib/librte_eal/common/Makefile                     |   2 +-\n .../common/include/generic/rte_ticketlock.h        | 203 +++++++++++++++++++++\n lib/librte_eal/common/meson.build                  |   1 +\n 5 files changed, 210 insertions(+), 1 deletion(-)\n create mode 100644 lib/librte_eal/common/include/generic/rte_ticketlock.h",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 097cfb4..12a091f 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -210,6 +210,10 @@ M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n F: lib/librte_eal/common/include/rte_bitmap.h\n F: app/test/test_bitmap.c\n \n+Ticketlock\n+M: Joyce Kong <joyce.kong@arm.com>\n+F: lib/librte_eal/common/include/generic/rte_ticketlock.h\n+\n ARM v7\n M: Jan Viktorin <viktorin@rehivetech.com>\n M: Gavin Hu <gavin.hu@arm.com>\ndiff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md\nindex d95ad56..aacc66b 100644\n--- a/doc/api/doxy-api-index.md\n+++ b/doc/api/doxy-api-index.md\n@@ -65,6 +65,7 @@ The public API headers are grouped by topics:\n   [atomic]             (@ref rte_atomic.h),\n   [rwlock]             (@ref rte_rwlock.h),\n   [spinlock]           (@ref rte_spinlock.h)\n+  [ticketlock]         (@ref rte_ticketlock.h)\n \n - **CPU arch**:\n   [branch prediction]  (@ref rte_branch_prediction.h),\ndiff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile\nindex c487201..ac3305c 100644\n--- a/lib/librte_eal/common/Makefile\n+++ b/lib/librte_eal/common/Makefile\n@@ -20,7 +20,7 @@ INC += rte_bitmap.h rte_vfio.h rte_hypervisor.h rte_test.h\n INC += rte_reciprocal.h rte_fbarray.h rte_uuid.h\n \n GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h\n-GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h\n+GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h rte_ticketlock.h\n GENERIC_INC += rte_vect.h rte_pause.h rte_io.h\n \n # defined in mk/arch/$(RTE_ARCH)/rte.vars.mk\ndiff --git a/lib/librte_eal/common/include/generic/rte_ticketlock.h b/lib/librte_eal/common/include/generic/rte_ticketlock.h\nnew file mode 100644\nindex 0000000..b99737a\n--- /dev/null\n+++ b/lib/librte_eal/common/include/generic/rte_ticketlock.h\n@@ -0,0 +1,203 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Arm Limited\n+ */\n+\n+#ifndef _RTE_TICKETLOCK_H_\n+#define _RTE_TICKETLOCK_H_\n+\n+/**\n+ * @file\n+ *\n+ * RTE ticket locks\n+ *\n+ * This file defines an API for ticket locks, which give each waiting\n+ * thread a ticket and take the lock one by one, first come, first\n+ * serviced.\n+ *\n+ * All locks must be initialised before use, and only initialised once.\n+ *\n+ */\n+\n+#include <rte_lcore.h>\n+#include <rte_common.h>\n+#include <rte_pause.h>\n+\n+/**\n+ * The rte_ticketlock_t type.\n+ */\n+typedef struct {\n+\tuint16_t current;\n+\tuint16_t next;\n+} rte_ticketlock_t;\n+\n+/**\n+ * A static ticketlock initializer.\n+ */\n+#define RTE_TICKETLOCK_INITIALIZER { 0 }\n+\n+/**\n+ * Initialize the ticketlock to an unlocked state.\n+ *\n+ * @param tl\n+ *   A pointer to the ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_init(rte_ticketlock_t *tl)\n+{\n+\t__atomic_store_n(&tl->current, 0, __ATOMIC_RELAXED);\n+\t__atomic_store_n(&tl->next, 0, __ATOMIC_RELAXED);\n+}\n+\n+/**\n+ * Take the ticketlock.\n+ *\n+ * @param tl\n+ *   A pointer to the ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_lock(rte_ticketlock_t *tl)\n+{\n+\tunsigned int me = __atomic_fetch_add(&tl->next, 1, __ATOMIC_RELAXED);\n+\twhile (__atomic_load_n(&tl->current, __ATOMIC_ACQUIRE) != me)\n+\t\trte_pause();\n+}\n+\n+/**\n+ * Release the ticketlock.\n+ *\n+ * @param tl\n+ *   A pointer to the ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_unlock(rte_ticketlock_t *tl)\n+{\n+\tunsigned int i = __atomic_load_n(&tl->current, __ATOMIC_RELAXED);\n+\ti++;\n+\t__atomic_store_n(&tl->current, i, __ATOMIC_RELEASE);\n+}\n+\n+/**\n+ * Try to take the lock.\n+ *\n+ * @param tl\n+ *   A pointer to the ticketlock.\n+ * @return\n+ *   1 if the lock is successfully taken; 0 otherwise.\n+ */\n+static inline __rte_experimental int\n+rte_ticketlock_trylock(rte_ticketlock_t *tl)\n+{\n+\tunsigned int next = __atomic_load_n(&tl->next, __ATOMIC_RELAXED);\n+\tunsigned int cur = __atomic_load_n(&tl->current, __ATOMIC_RELAXED);\n+\tif (next == cur) {\n+\t\tif (__atomic_compare_exchange_n(&tl->next, &next, next+1,\n+\t\t    0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))\n+\t\t\treturn 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Test if the lock is taken.\n+ *\n+ * @param tl\n+ *   A pointer to the ticketlock.\n+ * @return\n+ *   1 if the lock icurrently taken; 0 otherwise.\n+ */\n+static inline __rte_experimental int\n+rte_ticketlock_is_locked(rte_ticketlock_t *tl)\n+{\n+\treturn (__atomic_load_n(&tl->current, __ATOMIC_ACQUIRE) !=\n+\t\t__atomic_load_n(&tl->next, __ATOMIC_ACQUIRE));\n+}\n+\n+/**\n+ * The rte_ticketlock_recursive_t type.\n+ */\n+#define TICKET_LOCK_INVALID_ID -1\n+\n+typedef struct {\n+\trte_ticketlock_t tl; /**< the actual ticketlock */\n+\tint user; /**< core id using lock, TICKET_LOCK_INVALID_ID for unused */\n+\tunsigned int count; /**< count of time this lock has been called */\n+} rte_ticketlock_recursive_t;\n+\n+/**\n+ * A static recursive ticketlock initializer.\n+ */\n+#define RTE_TICKETLOCK_RECURSIVE_INITIALIZER {RTE_TICKETLOCK_INITIALIZER, \\\n+\t\t\t\tTICKET_LOCK_INVALID_ID, 0}\n+\n+/**\n+ * Initialize the recursive ticketlock to an unlocked state.\n+ *\n+ * @param tlr\n+ *   A pointer to the recursive ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)\n+{\n+\trte_ticketlock_init(&tlr->tl);\n+\t__atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID, __ATOMIC_RELAXED);\n+\ttlr->count = 0;\n+}\n+\n+/**\n+ * Take the recursive ticketlock.\n+ *\n+ * @param tlr\n+ *   A pointer to the recursive ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)\n+{\n+\tint id = rte_gettid();\n+\n+\tif (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {\n+\t\trte_ticketlock_lock(&tlr->tl);\n+\t\t__atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);\n+\t}\n+\ttlr->count++;\n+}\n+\n+/**\n+ * Release the recursive ticketlock.\n+ *\n+ * @param tlr\n+ *   A pointer to the recursive ticketlock.\n+ */\n+static inline __rte_experimental void\n+rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)\n+{\n+\tif (--(tlr->count) == 0) {\n+\t\t__atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID,\n+\t\t\t\t __ATOMIC_RELAXED);\n+\t\trte_ticketlock_unlock(&tlr->tl);\n+\t}\n+}\n+\n+/**\n+ * Try to take the recursive lock.\n+ *\n+ * @param tlr\n+ *   A pointer to the recursive ticketlock.\n+ * @return\n+ *   1 if the lock is successfully taken; 0 otherwise.\n+ */\n+static inline __rte_experimental int\n+rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)\n+{\n+\tint id = rte_gettid();\n+\n+\tif (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {\n+\t\tif (rte_ticketlock_trylock(&tlr->tl) == 0)\n+\t\t\treturn 0;\n+\t\t__atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);\n+\t}\n+\ttlr->count++;\n+\treturn 1;\n+}\n+\n+#endif /* _RTE_TICKETLOCK_H_ */\ndiff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build\nindex 5ecae0b..0670e41 100644\n--- a/lib/librte_eal/common/meson.build\n+++ b/lib/librte_eal/common/meson.build\n@@ -99,6 +99,7 @@ generic_headers = files(\n \t'include/generic/rte_prefetch.h',\n \t'include/generic/rte_rwlock.h',\n \t'include/generic/rte_spinlock.h',\n+\t'include/generic/rte_ticketlock.h',\n \t'include/generic/rte_vect.h')\n install_headers(generic_headers, subdir: 'generic')\n \n",
    "prefixes": [
        "v5",
        "1/2"
    ]
}