Hi, Tasnim...

On 6/24/2020 4:10 PM, Tasnim Bashar wrote:
Casting thread ID to handle is not accurate way to get thread handle.
Need to use OpenThread function to get thread handle from thread ID.

pthread_setaffinity_np and pthread_getaffinity_np functions
for Windows are affected because of it.

Signed-off-by: Tasnim Bashar <tbas...@mellanox.com>
---
v3: WA to remove warning(-Wmaybe-uninitialized)
v4: Directly used function name instead of #define
---
  lib/librte_eal/windows/include/pthread.h     | 84 +++++++++++++++-----
  lib/librte_eal/windows/include/rte_windows.h |  1 +
  2 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/lib/librte_eal/windows/include/pthread.h 
b/lib/librte_eal/windows/include/pthread.h
index e2274cf4e9..2553c0890a 100644
--- a/lib/librte_eal/windows/include/pthread.h
+++ b/lib/librte_eal/windows/include/pthread.h
@@ -6,6 +6,7 @@
  #define _PTHREAD_H_
#include <stdint.h>
+#include <sched.h>
/**
   * This file is required to support the common code in eal_common_proc.c,
@@ -16,8 +17,8 @@
  extern "C" {
  #endif
-#include <windows.h>
  #include <rte_common.h>
+#include <rte_windows.h>
#define PTHREAD_BARRIER_SERIAL_THREAD TRUE @@ -40,37 +41,84 @@ typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
  /* 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, threadattr, threadfunc, args)
static inline int
-eal_set_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
+pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
+                       rte_cpuset_t *cpuset)
  {
-       SetThreadAffinityMask((HANDLE) threadid, *cpuset);
-       return 0;
+       DWORD_PTR ret;
+       HANDLE thread_handle;
+
+       if (cpuset == NULL || cpuset_size == 0)
+               return -1;
+
+       thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
+       if (thread_handle == NULL) {
+               RTE_LOG_WIN32_ERR("OpenThread()");
+               return -1;
+       }
+
+       ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
+       if (ret == 0) {
+               RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+               goto close_handle;
+       }
+
+close_handle:
+       if (CloseHandle(thread_handle) == 0) {
+               RTE_LOG_WIN32_ERR("CloseHandle()");
+               return -1;
+       }
+       return (ret == 0) ? -1 : 0;
  }
static inline int
-eal_get_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
+pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
+                       rte_cpuset_t *cpuset)
  {
        /* Workaround for the lack of a GetThreadAffinityMask()
         *API in Windows
         */
-               /* obtain previous mask by setting dummy mask */
-       DWORD dwprevaffinitymask =
-               SetThreadAffinityMask((HANDLE) threadid, 0x1);
+       DWORD_PTR prev_affinity_mask;
+       HANDLE thread_handle;
+       DWORD_PTR ret;
Initialize ret to 0 here, otherwise... (see below)
+
+       if (cpuset == NULL || cpuset_size == 0)
+               return -1;
+
+       thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
+       if (thread_handle == NULL) {
+               RTE_LOG_WIN32_ERR("OpenThread()");
+               return -1;
+       }
+
+       /* obtain previous mask by setting dummy mask */
+       prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
+       if (prev_affinity_mask == 0) {
+               RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+               goto close_handle;
...after this jump, ret is uninitialized and will produce random results at the check at the end of the function.
+       }
+
        /* set it back! */
-       SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask);
-       *cpuset = dwprevaffinitymask;
-       return 0;
+       ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
+       if (ret == 0) {
+               RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+               goto close_handle;
+       }
+
+       memset(cpuset, 0, cpuset_size);
+       *cpuset->_bits = prev_affinity_mask;
+
+close_handle:
+       if (CloseHandle(thread_handle) == 0) {
+               RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+               return -1;
+       }
+       return (ret == 0) ? -1 : 0;
  }
static inline int
-eal_create_thread(void *threadid, const void *threadattr, void *threadfunc,
+pthread_create(void *threadid, const void *threadattr, void *threadfunc,
                void *args)
  {
        RTE_SET_USED(threadattr);
diff --git a/lib/librte_eal/windows/include/rte_windows.h 
b/lib/librte_eal/windows/include/rte_windows.h
index 899ed7d874..d013b50241 100644
--- a/lib/librte_eal/windows/include/rte_windows.h
+++ b/lib/librte_eal/windows/include/rte_windows.h
@@ -31,6 +31,7 @@
  #define INITGUID
  #endif
  #include <initguid.h>
+#include <rte_log.h>
/**
   * Log GetLastError() with context, usually a Win32 API function and 
arguments.


ranjit m.

Reply via email to