get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 3487,
    "url": "http://patches.dpdk.org/api/patches/3487/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com",
    "date": "2015-02-19T12:18:42",
    "name": "[dpdk-dev,v5,1/3] librte_headroom: New library for checking core/system/app load",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0b4a411130ace78b94e0a9a71f377d1b7441e171",
    "submitter": {
        "id": 58,
        "url": "http://patches.dpdk.org/api/people/58/?format=api",
        "name": "Wodkowski, PawelX",
        "email": "pawelx.wodkowski@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/3487/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/3487/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 3A44FB5A1;\n\tThu, 19 Feb 2015 13:22:35 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 1E208B53A\n\tfor <dev@dpdk.org>; Thu, 19 Feb 2015 13:22:31 +0100 (CET)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga103.fm.intel.com with ESMTP; 19 Feb 2015 04:14:53 -0800",
            "from unknown (HELO Sent) ([10.217.248.233])\n\tby orsmga002.jf.intel.com with SMTP; 19 Feb 2015 04:22:29 -0800",
            "by Sent (sSMTP sendmail emulation); Thu, 19 Feb 2015 13:21:13 +0100"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.09,512,1418112000\"; d=\"scan'208\";a=\"687859191\"",
        "From": "Pawel Wodkowski <pawelx.wodkowski@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Thu, 19 Feb 2015 13:18:42 +0100",
        "Message-Id": "<1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1424348324-29932-1-git-send-email-pawelx.wodkowski@intel.com>",
        "References": "<1424191340-26451-1-git-send-email-pawelx.wodkowski@intel.com>\n\t<1424348324-29932-1-git-send-email-pawelx.wodkowski@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 1/3] librte_headroom: New library for checking\n\tcore/system/app load",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This library provide API to measure time spend in particular parts of\ncode and to calculate optimal polling time.\n\nTo calculate a those statistics application code need to be divided into\nparts (called jobs) that do something. It is up to application to decide\nwhat is considered a job.\n\nSeries of jobs must be surrounded with the rte_headroom_start_loop() and\nrte_headroom_finish_loop() calls. After that, jobs might be started.\nEach job must be surrounded with rte_headroom_start_job() and\nrte_headroom_finish_job() calls.\n\nAfter job finishes its execution, period in which it should be called\nagain is adjusted to minimize time wasted on unnecessary polls/calls.\nAdjustment is based on data provided by job itself (ex: number of\npackets it processed).\n\nAfter all jobs in serie are executed fallowing statistics are updated\nand might be used by application. Statistics can be reset. Some of\nprovided statistic data:\n - total/min/max execution - time spent in executing jobs.\n - total/min/max management - time spent outside execution area. This\nvalue might be used to measure overhead of scheduling jobs. This time\nalso\ncontains overhead of headroom library itself.\n - number of loops that executed at least one job\n - executed jobs\n - time when statistics were reset.\n\nEach job provide total/min/max execution time and execution count\nstatistics.\n\nSigned-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>\n---\n config/common_bsdapp                         |   5 +\n config/common_linuxapp                       |   5 +\n lib/Makefile                                 |   1 +\n lib/librte_headroom/Makefile                 |  54 +++++\n lib/librte_headroom/rte_headroom.c           | 271 ++++++++++++++++++++++\n lib/librte_headroom/rte_headroom.h           | 324 +++++++++++++++++++++++++++\n lib/librte_headroom/rte_headroom_version.map |  19 ++\n 7 files changed, 679 insertions(+)\n create mode 100644 lib/librte_headroom/Makefile\n create mode 100644 lib/librte_headroom/rte_headroom.c\n create mode 100644 lib/librte_headroom/rte_headroom.h\n create mode 100644 lib/librte_headroom/rte_headroom_version.map",
    "diff": "diff --git a/config/common_bsdapp b/config/common_bsdapp\nindex 57bacb8..aa2e5fd 100644\n--- a/config/common_bsdapp\n+++ b/config/common_bsdapp\n@@ -282,6 +282,11 @@ CONFIG_RTE_LIBRTE_HASH=y\n CONFIG_RTE_LIBRTE_HASH_DEBUG=n\n \n #\n+# Compile librte_headroom\n+#\n+CONFIG_RTE_LIBRTE_HEADROOM=y\n+\n+#\n # Compile librte_lpm\n #\n CONFIG_RTE_LIBRTE_LPM=y\ndiff --git a/config/common_linuxapp b/config/common_linuxapp\nindex d428f84..055a37b 100644\n--- a/config/common_linuxapp\n+++ b/config/common_linuxapp\n@@ -290,6 +290,11 @@ CONFIG_RTE_LIBRTE_HASH=y\n CONFIG_RTE_LIBRTE_HASH_DEBUG=n\n \n #\n+# Compile librte_headroom\n+#\n+CONFIG_RTE_LIBRTE_HEADROOM=y\n+\n+#\n # Compile librte_lpm\n #\n CONFIG_RTE_LIBRTE_LPM=y\ndiff --git a/lib/Makefile b/lib/Makefile\nindex d617d81..4fc2819 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -54,6 +54,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt\n DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost\n DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash\n+DIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += librte_headroom\n DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm\n DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl\n DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net\ndiff --git a/lib/librte_headroom/Makefile b/lib/librte_headroom/Makefile\nnew file mode 100644\nindex 0000000..faefb3b\n--- /dev/null\n+++ b/lib/librte_headroom/Makefile\n@@ -0,0 +1,54 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+#   All rights reserved.\n+#\n+#   Redistribution and use in source and binary forms, with or without\n+#   modification, are permitted provided that the following conditions\n+#   are met:\n+#\n+#     * Redistributions of source code must retain the above copyright\n+#       notice, this list of conditions and the following disclaimer.\n+#     * Redistributions in binary form must reproduce the above copyright\n+#       notice, this list of conditions and the following disclaimer in\n+#       the documentation and/or other materials provided with the\n+#       distribution.\n+#     * Neither the name of Intel Corporation nor the names of its\n+#       contributors may be used to endorse or promote products derived\n+#       from this software without specific prior written permission.\n+#\n+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# library name\n+LIB = librte_headroom.a\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)\n+\n+EXPORT_MAP := rte_headroom_version.map\n+\n+LIBABIVER := 1\n+\n+# all source are stored in SRCS-y\n+SRCS-$(CONFIG_RTE_LIBRTE_HEADROOM) := rte_headroom.c\n+\n+# install this header file\n+SYMLINK-$(CONFIG_RTE_LIBRTE_HEADROOM)-include := rte_headroom.h\n+\n+# this lib needs eal\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += lib/librte_eal\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += lib/librte_mbuf\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/lib/librte_headroom/rte_headroom.c b/lib/librte_headroom/rte_headroom.c\nnew file mode 100644\nindex 0000000..a2cc671\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom.c\n@@ -0,0 +1,271 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <string.h>\n+#include <stdlib.h>\n+\n+#include <rte_log.h>\n+#include <rte_errno.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_branch_prediction.h>\n+#include <rte_debug.h>\n+#include <rte_eal.h>\n+#include <rte_malloc.h>\n+\n+#include \"rte_headroom.h\"\n+\n+/* Those are steps used to adjust job period.\n+ * Experiments show that for forwarding apps the up step must be less than down\n+ * step to achieve optimal performance.\n+ */\n+#define JOB_UPDATE_STEP_UP    1\n+#define JOB_UPDATE_STEP_DOWN  4\n+\n+/*\n+ * Default update function that implements simple period adjustment.\n+ */\n+static void\n+default_update_function(struct rte_headroom_job *job, int64_t result)\n+{\n+\tint64_t err = job->target - result;\n+\n+\t/* Job is happy. Nothing to do */\n+\tif (err == 0)\n+\t\treturn;\n+\n+\tif (err > 0) {\n+\t\tif (job->period + JOB_UPDATE_STEP_UP < job->max_period)\n+\t\t\tjob->period += JOB_UPDATE_STEP_UP;\n+\t} else {\n+\t\tif (job->min_period + JOB_UPDATE_STEP_DOWN < job->period)\n+\t\t\tjob->period -= JOB_UPDATE_STEP_DOWN;\n+\t}\n+}\n+\n+#define HDR_ADD_TIME_MIN_MAX(obj, type, value) do {  \\\n+\ttypeof(value) tmp = (value);                     \\\n+\t(obj)->type ## _time += tmp;                     \\\n+\tif (tmp < (obj)->min_ ## type ## _time)          \\\n+\t\t(obj)->min_ ## type ## _time = tmp;          \\\n+\tif (tmp > (obj)->max_ ## type ## _time)          \\\n+\t\t(obj)->max_ ## type ## _time = tmp;          \\\n+} while (0)\n+\n+#define HDR_RESET_TIME_MIN_MAX(obj, type) do {       \\\n+\t(obj)->type ## _time = 0;                        \\\n+\t(obj)->min_ ## type ## _time = UINT64_MAX;       \\\n+\t(obj)->max_ ## type ## _time = 0;                \\\n+} while (0)\n+\n+int\n+rte_headroom_init(struct rte_headroom *hdr)\n+{\n+\tif (hdr == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Init only needed parameters. Zero out everything else. */\n+\tmemset(hdr, 0, sizeof(struct rte_headroom));\n+\n+\trte_headroom_reset_stats(hdr);\n+\n+\treturn 0;\n+}\n+\n+void\n+rte_headroom_start_loop(struct rte_headroom *hdr)\n+{\n+\tuint64_t now;\n+\n+\thdr->loop_executed_jobs = 0;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+}\n+\n+void\n+rte_headroom_finish_loop(struct rte_headroom *hdr)\n+{\n+\tuint64_t now;\n+\n+\tif (likely(hdr->loop_executed_jobs))\n+\t\thdr->loop_cnt++;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+}\n+\n+void\n+rte_headroom_set_job_target(struct rte_headroom_job *job, int64_t target)\n+{\n+\tjob->target = target;\n+}\n+\n+int\n+rte_headroom_start_job(struct rte_headroom *hdr, struct rte_headroom_job *job)\n+{\n+\tuint64_t now;\n+\n+\t/* Some sanity check. */\n+\tif (unlikely(hdr == NULL || job == NULL || job->headroom != NULL))\n+\t\treturn -EINVAL;\n+\n+\t/* Link job with headroom object. */\n+\tjob->headroom = hdr;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_headroom_finish_job(struct rte_headroom_job *job, int64_t job_value)\n+{\n+\tstruct rte_headroom *hdr;\n+\tuint64_t now, exec_time;\n+\tint need_update;\n+\n+\t/* Some sanity check. */\n+\tif (unlikely(job == NULL || job->headroom == NULL))\n+\t\treturn -EINVAL;\n+\n+\tneed_update = job->target != job_value;\n+\t/* Adjust period only if job is unhappy of its current period. */\n+\tif (need_update)\n+\t\t(*job->update_period_cb)(job, job_value);\n+\n+\thdr = job->headroom;\n+\n+\t/* Update execution time is considered as runtime so get time after it is\n+\t * executed. */\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\texec_time = now - hdr->state_time;\n+\tHDR_ADD_TIME_MIN_MAX(job, exec, exec_time);\n+\tHDR_ADD_TIME_MIN_MAX(hdr, exec, exec_time);\n+\n+\thdr->state_time = now;\n+\n+\thdr->loop_executed_jobs++;\n+\thdr->job_exec_cnt++;\n+\n+\tjob->exec_cnt++;\n+\tjob->headroom = NULL;\n+\n+\treturn need_update;\n+}\n+\n+void\n+rte_headroom_job_set_period(struct rte_headroom_job *job, uint64_t period,\n+\t\tuint8_t saturate)\n+{\n+\tif (saturate != 0) {\n+\t\tif (period < job->min_period)\n+\t\t\tperiod = job->min_period;\n+\t\telse if (period > job->max_period)\n+\t\t\tperiod = job->max_period;\n+\t}\n+\n+\tjob->period = period;\n+}\n+\n+void\n+rte_headroom_set_min_period(struct rte_headroom_job *job, uint64_t period)\n+{\n+\tjob->min_period = period;\n+\tif (job->period < period)\n+\t\tjob->period = period;\n+}\n+\n+void\n+rte_headroom_set_max_period(struct rte_headroom_job *job, uint64_t period)\n+{\n+\tjob->max_period = period;\n+\tif (job->period > period)\n+\t\tjob->period = period;\n+}\n+\n+int\n+rte_headroom_job_init(struct rte_headroom_job *job, const char *name,\n+\t\tuint64_t min_period, uint64_t max_period, uint64_t initial_period,\n+\t\tint64_t target)\n+{\n+\tif (job == NULL)\n+\t\treturn -EINVAL;\n+\n+\tjob->period = initial_period;\n+\tjob->min_period = min_period;\n+\tjob->max_period = max_period;\n+\tjob->target = target;\n+\tjob->update_period_cb = &default_update_function;\n+\trte_headroom_reset_job_stats(job);\n+\tsnprintf(job->name, RTE_DIM(job->name), \"%s\", name == NULL ? \"\" : name);\n+\tjob->headroom = NULL;\n+\n+\treturn 0;\n+}\n+\n+void\n+rte_headroom_set_update_period_function(struct rte_headroom_job *job,\n+\t\trte_headroom_update_fn_t update_period_cb)\n+{\n+\tif (update_period_cb == NULL)\n+\t\tupdate_period_cb = default_update_function;\n+\n+\tjob->update_period_cb = update_period_cb;\n+}\n+\n+void\n+rte_headroom_reset_job_stats(struct rte_headroom_job *job)\n+{\n+\tHDR_RESET_TIME_MIN_MAX(job, exec);\n+\tjob->exec_cnt = 0;\n+}\n+\n+void\n+rte_headroom_reset_stats(struct rte_headroom *hdr)\n+{\n+\tHDR_RESET_TIME_MIN_MAX(hdr, exec);\n+\tHDR_RESET_TIME_MIN_MAX(hdr, management);\n+\thdr->start_time = rte_get_timer_cycles();\n+\thdr->state_time = hdr->start_time;\n+\thdr->job_exec_cnt = 0;\n+\thdr->loop_cnt = 0;\n+}\ndiff --git a/lib/librte_headroom/rte_headroom.h b/lib/librte_headroom/rte_headroom.h\nnew file mode 100644\nindex 0000000..2232c13\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom.h\n@@ -0,0 +1,324 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef HEADROOM_H_\n+#define HEADROOM_H_\n+\n+#include <stdint.h>\n+\n+#include <rte_memory.h>\n+#include <rte_memcpy.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#define RTE_HEADROOM_JOB_NAMESIZE 32\n+#define RTE_HEADROOM_NAMESIZE 32\n+#define RTE_HEADROOM_MZ_PREFIX \"HDR_\"\n+\n+/* Forward declarations. */\n+struct rte_headroom;\n+struct rte_headroom_job;\n+\n+/**\n+ * This function should calculate new period and set it using\n+ * rte_headroom_set_period() function. Time spent in this function will be\n+ * added to job's runtime.\n+ *\n+ * @param job\n+ *  The job data structure handler.\n+ * @param job_result\n+ *  Result of calling job callback.\n+ */\n+typedef void (*rte_headroom_update_fn_t)(struct rte_headroom_job *job,\n+\t\tint64_t job_result);\n+\n+struct rte_headroom_job {\n+\tuint64_t period;\n+\t/**< Estimated period of execution. */\n+\n+\tuint64_t min_period;\n+\t/**< Minimum period. */\n+\n+\tuint64_t max_period;\n+\t/**< Maximum period. */\n+\n+\tint64_t target;\n+\t/**< Desired value for this job. */\n+\n+\trte_headroom_update_fn_t update_period_cb;\n+\t/**< Period update callback. */\n+\n+\tuint64_t exec_time;\n+\t/**< Total time (sum) that this job was executing. */\n+\n+\tuint64_t min_exec_time;\n+\t/**< Minimum execute time. */\n+\n+\tuint64_t max_exec_time;\n+\t/**< Minimum execute time. */\n+\n+\tuint64_t exec_cnt;\n+\t/**< Execute count. */\n+\n+\tchar name[RTE_HEADROOM_JOB_NAMESIZE];\n+\t/**< Name of this job */\n+\n+\tstruct rte_headroom *headroom;\n+\t/**< Headroom object that is executing this job. */\n+} __rte_cache_aligned;\n+\n+struct rte_headroom {\n+\t/** Viariable holding time at different points:\n+\t * -# loop start time if loop was started but no job executed yet.\n+\t * -# job start time if job is currently executing.\n+\t * -# job finish time if job finished its execution.\n+\t * -# loop finish time if loop finished its execution. */\n+\tuint64_t state_time;\n+\n+\tuint64_t loop_executed_jobs;\n+\t/**< Count of executed jobs in this loop. */\n+\n+\t/* Statistics start. */\n+\n+\tuint64_t exec_time;\n+\t/**< Total time taken to execute jobs, not including management time. */\n+\n+\tuint64_t min_exec_time;\n+\t/**< Minimum loop execute time. */\n+\n+\tuint64_t max_exec_time;\n+\t/**< Minimum loop execute time. */\n+\n+\t/**\n+\t * Sum of time that is not the execute time (ex: from job finish to next\n+\t * job start).\n+\t *\n+\t * This time might be considered as overhead of headroom library + job\n+\t * scheduling.\n+\t */\n+\tuint64_t management_time;\n+\n+\tuint64_t min_management_time;\n+\t/**< Minimum management time */\n+\n+\tuint64_t max_management_time;\n+\t/**< Maximum management time */\n+\n+\tuint64_t start_time;\n+\t/**< Time since last reset stats. */\n+\n+\tuint64_t job_exec_cnt;\n+\t/**< Total count of executed jobs. */\n+\n+\tuint64_t loop_cnt;\n+\t/**< Total count of executed loops with at least one executed job. */\n+} __rte_cache_aligned;\n+\n+/**\n+ * Initialize given headroom object with default values.\n+ *\n+ * @param hdr\n+ *  Headroom object to initialize.\n+ *\n+ * @return\n+ *  0 on success\n+ *  -EINVAL if *hdr* is NULL\n+ */\n+int\n+rte_headroom_init(struct rte_headroom *hdr);\n+\n+/**\n+ * Mark that new set of jobs start executing.\n+ *\n+ * @param hdr\n+ *  Headroom object.\n+ */\n+void\n+rte_headroom_start_loop(struct rte_headroom *hdr);\n+\n+/**\n+ * Mark that there is no more jobs ready to execute in this turn. Calculate\n+ * stats for this loop turn.\n+ *\n+ * @param hdr\n+ *  Headroom object.\n+ */\n+void\n+rte_headroom_finish_loop(struct rte_headroom *hdr);\n+\n+/**\n+ * Initialize given job stats object.\n+ *\n+ * @param job\n+ *  Job object.\n+ * @param name\n+ *  Optional job name.\n+ * @param min_period\n+ *  Minimum period that this job can accept.\n+ * @param max_period\n+ *  Maximum period that this job can accept.\n+ * @param initial_period\n+ *  Initial period. It will be checked against *min_period* and *max_period*.\n+ * @param target\n+ *  Target value that this job try to achieve.\n+ *\n+ * @return\n+ *  0 on success\n+ *  -EINVAL if *job* is NULL\n+ */\n+int\n+rte_headroom_job_init(struct rte_headroom_job *job, const char *name,\n+\t\tuint64_t min_period, uint64_t max_period, uint64_t initial_period,\n+\t\tint64_t target);\n+\n+/**\n+ * Set job desired target value. Difference between target and job callback\n+ * return value must be used to properly adjust job execute period value.\n+ *\n+ * @param job\n+ *  The job object.\n+ * @param target\n+ *  New target.\n+ */\n+void\n+rte_headroom_set_job_target(struct rte_headroom_job *job, int64_t target);\n+\n+/**\n+ * Mark that *job* is starting of its execution in context of *hdr* object.\n+ *\n+ * @param hdr\n+ *  Headroom object context.\n+ * @param job\n+ *  Job object.\n+ * @return\n+ *  0 on success\n+ *  -EINVAL if *hdr* or *job* is NULL or *job* is executing in another headroom\n+ *  context already,\n+ */\n+int\n+rte_headroom_start_job(struct rte_headroom *hdr, struct rte_headroom_job *job);\n+\n+/**\n+ * Mark that *job* finished its execution. Context in which it was executing will\n+ * receive stat update. After this function call *job* object is ready to be\n+ * executed in other headroom context.\n+ *\n+ * @param job\n+ *  Job object.\n+ * @param job_value\n+ *  Job value. Job should pass in this parameter a value that it try to optimize\n+ *  for example the number of packets it processed.\n+ *\n+ * @return\n+ *  0 if job's period was not updated (job target equals *job_value*)\n+ *  1 if job's period was updated\n+ *  -EINVAL if job is NULL or job was not started (it have no headroom context).\n+ */\n+int\n+rte_headroom_finish_job(struct rte_headroom_job *job, int64_t job_value);\n+\n+/**\n+ * Set execute period of given job.\n+ *\n+ * @param job\n+ *  The job object.\n+ * @param period\n+ *  New period value.\n+ * @param saturate\n+ *  If zero, skip period saturation to min, max range.\n+ */\n+void\n+rte_headroom_job_set_period(struct rte_headroom_job *job, uint64_t period,\n+\t\tuint8_t saturate);\n+/**\n+ * Set minimum execute period of given job. Current period will be checked\n+ * against new minimum value.\n+ *\n+ * @param job\n+ *  The job object.\n+ * @param period\n+ *  New minimum period value.\n+ */\n+void\n+rte_headroom_set_min_period(struct rte_headroom_job *job, uint64_t period);\n+/**\n+ * Set maximum execute period of given job. Current period will be checked\n+ * against new maximum value.\n+ *\n+ * @param job\n+ *  The job object.\n+ * @param period\n+ *  New maximum period value.\n+ */\n+void\n+rte_headroom_set_max_period(struct rte_headroom_job *job, uint64_t period);\n+\n+/**\n+ * Set update period callback that is invoked after job finish.\n+ *\n+ * If application wants to do more sophisticated calculations than default\n+ * it can provide this handler.\n+ *\n+ * @param job\n+ *  Job object.\n+ * @param update_pedriod_cb\n+ *  Callback to set. If NULL restore default update function.\n+ */\n+void\n+rte_headroom_set_update_period_function(struct rte_headroom_job *job,\n+\t\trte_headroom_update_fn_t update_period_cb);\n+\n+/**\n+ * Function resets job statistics.\n+ *\n+ * @param job\n+ *  Job which statistics will be reset.\n+ */\n+void\n+rte_headroom_reset_job_stats(struct rte_headroom_job *job);\n+/**\n+ * Function resets headroom statistics.\n+ *\n+ * @param hdr\n+ *  Headroom which statistics will be reset.\n+ */\n+void\n+rte_headroom_reset_stats(struct rte_headroom *hdr);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* HEADROOM_H_ */\ndiff --git a/lib/librte_headroom/rte_headroom_version.map b/lib/librte_headroom/rte_headroom_version.map\nnew file mode 100644\nindex 0000000..3c66812\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom_version.map\n@@ -0,0 +1,19 @@\n+DPDK_2.0 {\n+\tglobal:\n+\n+\trte_headroom_init;\n+\trte_headroom_start_loop;\n+\trte_headroom_finish_loop;\n+\trte_headroom_job_init;\n+\trte_headroom_set_job_target;\n+\trte_headroom_start_job;\n+\trte_headroom_finish_job;\n+\trte_headroom_job_set_period;\n+\trte_headroom_set_min_period;\n+\trte_headroom_set_max_period;\n+\trte_headroom_set_update_period_function;\n+\trte_headroom_reset_job_stats;\n+\trte_headroom_reset_stats;\n+\n+\tlocal: *;\n+};\n",
    "prefixes": [
        "dpdk-dev",
        "v5",
        "1/3"
    ]
}