DPDK patches and discussions
 help / color / mirror / Atom feed
From: Anand Rawat <anand.rawat@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 3/6] eal: Add headers for compatibility with windows environment
Date: Thu, 28 Feb 2019 23:18:44 -0800	[thread overview]
Message-ID: <20190301071847.13376-4-anand.rawat@intel.com> (raw)
In-Reply-To: <20190301071847.13376-1-anand.rawat@intel.com>

Added headers to support windows environment for common source.
These headers will have windows specific implementions of the
system library apis provided in linux and freebsd.

Signed-off-by: Anand Rawat <anand.rawat@intel.com>
Signed-off-by: Kadam, Pallavi <pallavi.kadam@intel.com>
Reviewed-by: Jeffrey B Shaw <jeffrey.b.shaw@intel.com>
Reviewed-by: Ranjit Menon <ranjit.menon@intel.com>
---
 .../winapp/eal/include/exec-env/fnmatch.h     |  26 ++
 .../winapp/eal/include/exec-env/pthread.h     |  19 ++
 .../winapp/eal/include/exec-env/regex.h       |  54 +++
 .../winapp/eal/include/exec-env/sched.h       |  41 +++
 .../winapp/eal/include/exec-env/sys/queue.h   | 320 ++++++++++++++++++
 .../winapp/eal/include/exec-env/unistd.h      |   7 +
 6 files changed, 467 insertions(+)
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/fnmatch.h
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/pthread.h
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/regex.h
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/sched.h
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/sys/queue.h
 create mode 100644 lib/librte_eal/winapp/eal/include/exec-env/unistd.h

diff --git a/lib/librte_eal/winapp/eal/include/exec-env/fnmatch.h b/lib/librte_eal/winapp/eal/include/exec-env/fnmatch.h
new file mode 100644
index 000000000..85a679aad
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/fnmatch.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _FNMATCH_H_
+#define _FNMATCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FNM_NOMATCH 1
+
+static inline int
+fnmatch(const char *pattern __rte_unused,
+		const char *string __rte_unused,
+		int flags __rte_unused)
+{
+	return FNM_NOMATCH;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FNMATCH_H_ */
diff --git a/lib/librte_eal/winapp/eal/include/exec-env/pthread.h b/lib/librte_eal/winapp/eal/include/exec-env/pthread.h
new file mode 100644
index 000000000..431550577
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/pthread.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _PTHREAD_H_
+#define _PTHREAD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uintptr_t pthread_t;
+typedef void *pthread_attr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PTHREAD_H_ */
diff --git a/lib/librte_eal/winapp/eal/include/exec-env/regex.h b/lib/librte_eal/winapp/eal/include/exec-env/regex.h
new file mode 100644
index 000000000..5a167833f
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/regex.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _REGEX_H_
+#define _REGEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REG_NOMATCH 1
+#define REG_ESPACE 12
+
+typedef void *regex_t;
+typedef void *regmatch_t;
+
+static inline int
+regcomp(regex_t *preg __rte_unused,
+		const char *regex __rte_unused, int cflags __rte_unused)
+{
+	return REG_ESPACE;
+}
+
+static inline int
+regexec(const regex_t *preg __rte_unused,
+		const char *string __rte_unused, size_t nmatch __rte_unused,
+		regmatch_t pmatch[] __rte_unused, int eflags __rte_unused)
+{
+	return REG_NOMATCH;
+}
+
+static inline size_t
+regerror(int errcode __rte_unused,
+		const regex_t *preg __rte_unused, char *errbuf,
+		size_t errbuf_size __rte_unused)
+{
+	if (errbuf) {
+		*errbuf = '\0';
+		return 1;
+	}
+	return 0;
+}
+
+static inline void
+regfree(regex_t *preg __rte_unused)
+{
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _REGEX_H_ */
diff --git a/lib/librte_eal/winapp/eal/include/exec-env/sched.h b/lib/librte_eal/winapp/eal/include/exec-env/sched.h
new file mode 100644
index 000000000..b105c43c3
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/sched.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _SCHED_H_
+#define _SCHED_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CPU_SET_SIZE
+#define CPU_SET_SIZE RTE_MAX_LCORE
+#endif
+
+#define _BITS_PER_SET (sizeof(long long) * 8)
+#define _BIT_SET_MASK (_BITS_PER_SET - 1)
+
+#define _NUM_SETS(b) (((b) + _BIT_SET_MASK) / _BITS_PER_SET)
+#define _WHICH_SET(b) ((b) / _BITS_PER_SET)
+#define _WHICH_BIT(b) ((b) & (_BITS_PER_SET - 1))
+
+typedef struct _rte_cpuset_s {
+	long long _bits[_NUM_SETS(CPU_SET_SIZE)];
+} rte_cpuset_t;
+
+#define CPU_SET(b, s) ((s)->_bits[_WHICH_SET(b)] |= (1LL << _WHICH_BIT(b)))
+
+#define CPU_ZERO(s)							\
+	do {								\
+		unsigned int _i;					\
+									\
+		for (_i = 0; _i < _NUM_SETS(CPU_SET_SIZE); _i++)	\
+			(s)->_bits[_i] = 0LL;				\
+	} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SCHED_H_ */
diff --git a/lib/librte_eal/winapp/eal/include/exec-env/sys/queue.h b/lib/librte_eal/winapp/eal/include/exec-env/sys/queue.h
new file mode 100644
index 000000000..5ee4916ad
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/sys/queue.h
@@ -0,0 +1,320 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+/*
+ * This file defines tail queues.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * Below is a summary of implemented functions where:
+ *  +  means the macro is available
+ *  -  means the macro is not available
+ *  s  means the macro is available but is slow (runs in O(n) time)
+ *
+ *				TAILQ
+ * _HEAD			+
+ * _CLASS_HEAD			+
+ * _HEAD_INITIALIZER		+
+ * _ENTRY			+
+ * _CLASS_ENTRY			+
+ * _INIT			+
+ * _EMPTY			+
+ * _FIRST			+
+ * _NEXT			+
+ * _PREV			+
+ * _LAST			+
+ * _LAST_FAST			+
+ * _FOREACH			+
+ * _FOREACH_FROM		+
+ * _FOREACH_SAFE		+
+ * _FOREACH_FROM_SAFE		+
+ * _FOREACH_REVERSE		+
+ * _FOREACH_REVERSE_FROM	+
+ * _FOREACH_REVERSE_SAFE	+
+ * _FOREACH_REVERSE_FROM_SAFE	+
+ * _INSERT_HEAD			+
+ * _INSERT_BEFORE		+
+ * _INSERT_AFTER		+
+ * _INSERT_TAIL			+
+ * _CONCAT			+
+ * _REMOVE_AFTER		-
+ * _REMOVE_HEAD			-
+ * _REMOVE			+
+ * _SWAP			+
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	QMD_TRACE_ELEM(elem)
+#define	QMD_TRACE_HEAD(head)
+#define	TRACEBUF
+#define	TRACEBUF_INITIALIZER
+
+#define	TRASHIT(x)
+#define	QMD_IS_TRASHED(x)	0
+
+#define	QMD_SAVELINK(name, link)
+
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define	QUEUE_TYPEOF(type) type
+#else
+#define	QUEUE_TYPEOF(type) struct type
+#endif
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
+#define	TAILQ_CLASS_HEAD(name, type)					\
+struct name {								\
+	class type *tqh_first;	/* first element */			\
+	class type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
+#define	TAILQ_CLASS_ENTRY(type)						\
+struct {								\
+	class type *tqe_next;	/* next element */			\
+	class type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
+/*
+ * Tail queue functions.
+ */
+#define	QMD_TAILQ_CHECK_HEAD(head, field)
+#define	QMD_TAILQ_CHECK_TAIL(head, headname)
+#define	QMD_TAILQ_CHECK_NEXT(elm, field)
+#define	QMD_TAILQ_CHECK_PREV(elm, field)
+
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+		QMD_TRACE_HEAD(head1);					\
+		QMD_TRACE_HEAD(head2);					\
+	}								\
+} while (0)
+
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_FROM(var, head, field)				\
+	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)			\
+	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)		\
+	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
+	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
+	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
+	TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field);	\
+	if (TAILQ_NEXT((listelm), field) != NULL)			\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    &TAILQ_NEXT((elm), field);				\
+	else {								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&(listelm)->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	QMD_TAILQ_CHECK_PREV(listelm, field);				\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&(listelm)->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	QMD_TAILQ_CHECK_HEAD(head, field);				\
+	TAILQ_NEXT((elm), field) = TAILQ_FIRST((head));			\
+	if (TAILQ_FIRST((head)) != NULL)				\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	QMD_TAILQ_CHECK_TAIL(head, field);				\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+/*
+ * The FAST function is fast in that it causes no data access other
+ * then the access to the head. The standard LAST function above
+ * will cause a data access of both the element you want and
+ * the previous element. FAST is very useful for instances when
+ * you may want to prefetch the last data element.
+ */
+#define	TAILQ_LAST_FAST(head, type, field)			\
+	(TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last,	\
+	QUEUE_TYPEOF(type), field.tqe_next))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
+	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
+	QMD_TAILQ_CHECK_NEXT(elm, field);				\
+	QMD_TAILQ_CHECK_PREV(elm, field);				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT(*oldnext);						\
+	TRASHIT(*oldprev);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define TAILQ_SWAP(head1, head2, type, field) do {			\
+	QUEUE_TYPEOF(type) * swap_first = (head1)->tqh_first;		\
+	QUEUE_TYPEOF(type) * *swap_last = (head1)->tqh_last;		\
+	(head1)->tqh_first = (head2)->tqh_first;			\
+	(head1)->tqh_last = (head2)->tqh_last;				\
+	(head2)->tqh_first = swap_first;				\
+	(head2)->tqh_last = swap_last;					\
+	swap_first = (head1)->tqh_first;				\
+	if (swap_first != NULL)						\
+		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
+	else								\
+		(head1)->tqh_last = &(head1)->tqh_first;		\
+	swap_first = (head2)->tqh_first;				\
+	if (swap_first != NULL)			\
+		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
+	else								\
+		(head2)->tqh_last = &(head2)->tqh_first;		\
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_QUEUE_H_ */
diff --git a/lib/librte_eal/winapp/eal/include/exec-env/unistd.h b/lib/librte_eal/winapp/eal/include/exec-env/unistd.h
new file mode 100644
index 000000000..4973fc793
--- /dev/null
+++ b/lib/librte_eal/winapp/eal/include/exec-env/unistd.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+#endif /* _UNISTD_H_ */
-- 
2.17.1.windows.2

  parent reply	other threads:[~2019-03-01  7:18 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-01  7:18 [dpdk-dev] [PATCH 0/6] HelloWorld example for Windows Anand Rawat
2019-03-01  7:18 ` [dpdk-dev] [PATCH 1/6] eal: eal stub to add windows support Anand Rawat
2019-03-01 14:03   ` Thomas Monjalon
2019-03-01 14:17     ` Bruce Richardson
2019-03-01 14:30       ` Thomas Monjalon
2019-03-01 15:19       ` Luca Boccassi
2019-03-01  7:18 ` [dpdk-dev] [PATCH 2/6] eal: Add header files to support windows Anand Rawat
2019-03-01  7:18 ` Anand Rawat [this message]
2019-03-01  7:18 ` [dpdk-dev] [PATCH 4/6] eal: add minimum viable code for eal on windows Anand Rawat
2019-03-01  7:18 ` [dpdk-dev] [PATCH 5/6] examples: Add meson changes for windows Anand Rawat
2019-03-01  7:18 ` [dpdk-dev] [PATCH 6/6] doc: add documention " Anand Rawat
2019-03-01 19:02   ` Stephen Hemminger
2019-03-02  2:41     ` Ranjit Menon
2019-03-06  8:33       ` Thomas Monjalon
2019-03-01 13:47 ` [dpdk-dev] [PATCH 0/6] HelloWorld example for Windows Bruce Richardson
2019-03-04 10:13   ` David Marchand
2019-03-04 10:14     ` David Marchand
2019-03-05 23:43     ` Anand Rawat

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190301071847.13376-4-anand.rawat@intel.com \
    --to=anand.rawat@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).