From e8428a9d89f14c4ee31a88b46a7a785baef29bbb Mon Sep 17 00:00:00 2001 From: Pallavi Kadam Date: Thu, 6 Feb 2020 19:14:31 -0800 Subject: [PATCH] eal/windows: add some basic functions and macros Adding additional function definitions for pthread, cpuset implementation, asprintf implementation, in order to support common code. Signed-off-by: Bruce Richardson Signed-off-by: Pallavi Kadam Reviewed-by: Ranjit Menon Reviewed-by: Keith Wiles Reviewed-by: Dmitry Kozlyuk Tested-by: Narcisa Ana Maria Vasile Acked-by: Narcisa Ana Maria Vasile --- lib/librte_eal/windows/eal/include/pthread.h | 66 +++++++++++++++++++ lib/librte_eal/windows/eal/include/rte_os.h | 42 ++++++++++++ lib/librte_eal/windows/eal/include/sched.h | 46 +++++++++++++ .../windows/eal/include/sys/queue.h | 8 +++ 4 files changed, 162 insertions(+) diff --git a/lib/librte_eal/windows/eal/include/pthread.h b/lib/librte_eal/windows/eal/include/pthread.h index 5033292667..4ac24de0aa 100644 --- a/lib/librte_eal/windows/eal/include/pthread.h +++ b/lib/librte_eal/windows/eal/include/pthread.h @@ -14,12 +14,78 @@ extern "C" { #endif +#include + +#define PTHREAD_BARRIER_SERIAL_THREAD TRUE + /* defining pthread_t type on Windows since there is no in Microsoft libc*/ typedef uintptr_t pthread_t; /* defining pthread_attr_t type on Windows since there is no in Microsoft libc*/ typedef void *pthread_attr_t; +typedef SYNCHRONIZATION_BARRIER pthread_barrier_t; + +#define pthread_barrier_init(barrier, attr, count) \ + InitializeSynchronizationBarrier(barrier, count, -1) +#define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier, \ + SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) +#define pthread_barrier_destroy(barrier) \ + DeleteSynchronizationBarrier(barrier) +#define pthread_cancel(thread) TerminateThread((HANDLE) thread, 0) + +/* pthread function overrides */ +#define pthread_self() \ + ((pthread_t)GetCurrentThreadId()) +#define pthread_setaffinity_np(thread, size, cpuset) \ + eal_set_thread_affinity_mask(thread, (unsigned long *) cpuset) +#define pthread_getaffinity_np(thread, size, cpuset) \ + eal_get_thread_affinity_mask(thread, (unsigned long *) cpuset) +#define pthread_create(threadid, threadattr, threadfunc, args) \ + eal_create_thread(threadid, threadfunc, args) + +static inline int +eal_set_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset) +{ + SetThreadAffinityMask((HANDLE) threadid, *cpuset); + return 0; +} + +static inline int +eal_get_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset) +{ + /* Workaround for the lack of a GetThreadAffinityMask() + *API in Windows + */ + /* obtain previous mask by setting dummy mask */ + DWORD dwprevaffinitymask = + SetThreadAffinityMask((HANDLE) threadid, 0x1); + /* set it back! */ + SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask); + *cpuset = dwprevaffinitymask; + return 0; +} + +static inline int +eal_create_thread(void *threadid, void *threadfunc, void *args) +{ + HANDLE hThread; + hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, + args, 0, (LPDWORD)threadid); + if (hThread) { + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); + } + return ((hThread != NULL) ? 0 : E_FAIL); +} + +static inline int +pthread_join(pthread_t thread __attribute__((__unused__)), + void **value_ptr __attribute__((__unused__))) +{ + return 0; +} + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/windows/eal/include/rte_os.h b/lib/librte_eal/windows/eal/include/rte_os.h index fdeae0c8fb..9e762617b1 100644 --- a/lib/librte_eal/windows/eal/include/rte_os.h +++ b/lib/librte_eal/windows/eal/include/rte_os.h @@ -18,6 +18,13 @@ extern "C" { #include #include #include +#include + +/* limits.h replacement */ +#include +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif #define strerror_r(a, b, c) strerror_s(b, c, a) @@ -28,6 +35,11 @@ typedef SSIZE_T ssize_t; #define strtok_r(str, delim, saveptr) strtok_s(str, delim, saveptr) +#define index(a, b) strchr(a, b) +#define rindex(a, b) strrchr(a, b) + +#define strncasecmp(s1, s2, count) _strnicmp(s1, s2, count) + /** * Create a thread. * This function is private to EAL. @@ -45,6 +57,36 @@ int eal_thread_create(pthread_t *thread); */ void eal_create_cpu_map(void); +static inline int +asprintf(char **buffer, const char *format, ...) +{ + int size, ret; + va_list arg; + + va_start(arg, format); + size = vsnprintf(NULL, 0, format, arg) + 1; + va_end(arg); + + *buffer = malloc(size); + if (buffer == NULL) + printf("Cannot allocate memory"); + + va_start(arg, format); + ret = vsnprintf(*buffer, size, format, arg); + va_end(arg); + if (ret != size - 1) { + free(*buffer); + return -1; + } + return ret; +} + +/* cpu_set macros implementation */ +#define RTE_CPU_AND(dst, src1, src2) CPU_AND(dst, src1, src2) +#define RTE_CPU_OR(dst, src1, src2) CPU_OR(dst, src1, src2) +#define RTE_CPU_FILL(set) CPU_FILL(set) +#define RTE_CPU_NOT(dst, src) CPU_NOT(dst, src) + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/windows/eal/include/sched.h b/lib/librte_eal/windows/eal/include/sched.h index 29868c93d1..fbe07f742c 100644 --- a/lib/librte_eal/windows/eal/include/sched.h +++ b/lib/librte_eal/windows/eal/include/sched.h @@ -39,6 +39,52 @@ typedef struct _rte_cpuset_s { (s)->_bits[_i] = 0LL; \ } while (0) +#define CPU_ISSET(b, s) (((s)->_bits[_WHICH_SET(b)] & \ + (1LL << _WHICH_BIT(b))) != 0LL) + +static inline int +count_cpu(rte_cpuset_t *s) +{ + unsigned int _i; + int count = 0; + + for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) + if (CPU_ISSET(_i, s) != 0LL) + count++; + return count; +} +#define CPU_COUNT(s) count_cpu(s) + +#define CPU_AND(dst, src1, src2) \ +do { \ + unsigned int _i; \ + \ + for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ + (dst)->_bits[_i] = (src1)->_bits[_i] & (src2)->_bits[_i]; \ +} while (0) + +#define CPU_OR(dst, src1, src2) \ +do { \ + unsigned int _i; \ + \ + for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ + (dst)->_bits[_i] = (src1)->_bits[_i] | (src2)->_bits[_i]; \ +} while (0) + +#define CPU_FILL(s) \ +do { \ + unsigned int _i; \ + for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ + (s)->_bits[_i] = -1LL; \ +} while (0) + +#define CPU_NOT(dst, src) \ +do { \ + unsigned int _i; \ + for (_i = 0; _i < _NUM_SETS(CPU_SETSIZE); _i++) \ + (dst)->_bits[_i] = (src)->_bits[_i] ^ -1LL; \ +} while (0) + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/windows/eal/include/sys/queue.h b/lib/librte_eal/windows/eal/include/sys/queue.h index 6b9446a177..a65949a78a 100644 --- a/lib/librte_eal/windows/eal/include/sys/queue.h +++ b/lib/librte_eal/windows/eal/include/sys/queue.h @@ -59,6 +59,14 @@ extern "C" { #endif +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) #define TRACEBUF -- 2.20.1