[DAPL2] sync with WinOF 2.1 branch
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 18 Sep 2009 23:19:41 +0000 (23:19 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 18 Sep 2009 23:19:41 +0000 (23:19 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2451 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

17 files changed:
ulp/dapl2/dapl/common/dapl_timer_util.c
ulp/dapl2/dapl/common/dapl_timer_util.h
ulp/dapl2/dapl/openib_cma/cm.c
ulp/dapl2/dapl/openib_cma/device.c
ulp/dapl2/dapl/openib_scm/cm.c
ulp/dapl2/dapl/openib_scm/device.c
ulp/dapl2/dapl/udapl/dapl_init.c
ulp/dapl2/dapl/udapl/windows/dapl_osd.c
ulp/dapl2/dapl/udapl/windows/dapl_osd.h
ulp/dapl2/dat/udat/windows/dat_osd.c
ulp/dapl2/dat/udat/windows/dat_osd.h
ulp/dapl2/test/dapltest/mdep/linux/dapl_mdep_user.h
ulp/dapl2/test/dapltest/mdep/solaris/dapl_mdep_user.h
ulp/dapl2/test/dapltest/mdep/windows/dapl_mdep_user.h
ulp/dapl2/test/dapltest/scripts/dt-cli.bat
ulp/dapl2/test/dapltest/scripts/dt-svr.bat
ulp/dapl2/test/dapltest/test/dapl_test_util.c

index f0d7964..a5d1cea 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * MODULE: dapl_timer_util.c
- *
- * PURPOSE: DAPL timer management
- * Description: Routines to add and cancel timer records. A timer record
- *             is put on the global timer queue. If the timer thread is
- *             not running, start it. The timer thread will sleep
- *             until a timer event or until a process wakes it up
- *             to notice a new timer is available; we use a DAPL_WAIT_OBJ
- *             for synchronization.
- *
- *             If a timer is cancelled, it is simlpy removed from the
- *             queue. The timer may wakeup and notice there is no timer
- *             record to awaken at this time, so it will reset for the
- *             next entry. When there are no timer records to manage,
- *             the timer thread just sleeps until awakened.
- *
- *             This file also contains the timer handler thread,
- *             embodied in dapls_timer_thread().
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_timer_util.h"
-
-struct timer_head {
-       DAPL_LLIST_HEAD timer_list_head;
-       DAPL_OS_LOCK lock;
-       DAPL_OS_WAIT_OBJECT wait_object;
-       DAPL_OS_THREAD timeout_thread_handle;
-} g_daplTimerHead;
-
-typedef struct timer_head DAPL_TIMER_HEAD;
-
-void dapls_timer_thread(void *arg);
-
-void dapls_timer_init()
-{
-       /*
-        * Set up the timer thread elements. The timer thread isn't
-        * started until it is actually needed
-        */
-       g_daplTimerHead.timer_list_head = NULL;
-       dapl_os_lock_init(&g_daplTimerHead.lock);
-       dapl_os_wait_object_init(&g_daplTimerHead.wait_object);
-       g_daplTimerHead.timeout_thread_handle = 0;
-}
-
-/*
- * dapls_timer_set
- *
- * Set a timer. The timer will invoke the specified function
- * after a number of useconds expires.
- *
- * Input:
- *      timer    User provided timer structure
- *      func     Function to invoke when timer expires
- *      data     Argument passed to func()
- *      expires  microseconds until timer fires
- *
- * Returns:
- *     no return value
- *
- */
-DAT_RETURN
-dapls_timer_set(IN DAPL_OS_TIMER * timer,
-               IN void (*func) (uintptr_t),
-               IN void *data, IN DAPL_OS_TIMEVAL expires)
-{
-       DAPL_OS_TIMER *list_ptr;
-       DAPL_OS_TIMEVAL cur_time;
-       DAT_BOOLEAN wakeup_tmo_thread;
-
-       /*
-        * Start the timer thread the first time we need a timer
-        */
-       if (g_daplTimerHead.timeout_thread_handle == 0) {
-               dapl_os_thread_create(dapls_timer_thread,
-                                     &g_daplTimerHead,
-                                     &g_daplTimerHead.timeout_thread_handle);
-       }
-
-       dapl_llist_init_entry(&timer->list_entry);
-       wakeup_tmo_thread = DAT_FALSE;
-       dapl_os_get_time(&cur_time);
-       timer->expires = cur_time + expires;    /* calculate future time */
-       timer->function = func;
-       timer->data = data;
-
-       /*
-        * Put the element on the queue: sorted by wakeup time, eariliest
-        * first.
-        */
-       dapl_os_lock(&g_daplTimerHead.lock);
-       /*
-        * Deal with 3 cases due to our list structure:
-        * 1) list is empty: become the list head
-        * 2) New timer is sooner than list head: become the list head
-        * 3) otherwise, sort the timer into the list, no need to wake
-        *    the timer thread up
-        */
-       if (dapl_llist_is_empty(&g_daplTimerHead.timer_list_head)) {
-               /* Case 1: add entry to head of list */
-               dapl_llist_add_head(&g_daplTimerHead.timer_list_head,
-                                   (DAPL_LLIST_ENTRY *) & timer->list_entry,
-                                   timer);
-               wakeup_tmo_thread = DAT_TRUE;
-       } else {
-               list_ptr = (DAPL_OS_TIMER *)
-                   dapl_llist_peek_head(&g_daplTimerHead.timer_list_head);
-
-               if (timer->expires < list_ptr->expires) {
-                       /* Case 2: add entry to head of list */
-                       dapl_llist_add_head(&g_daplTimerHead.timer_list_head,
-                                           (DAPL_LLIST_ENTRY *) & timer->
-                                           list_entry, timer);
-                       wakeup_tmo_thread = DAT_TRUE;
-               } else {
-                       /* Case 3: figure out where entry goes in sorted list */
-                       list_ptr =
-                           dapl_llist_next_entry(&g_daplTimerHead.
-                                                 timer_list_head,
-                                                 (DAPL_LLIST_ENTRY *) &
-                                                 list_ptr->list_entry);
-
-                       while (list_ptr != NULL) {
-                               if (timer->expires < list_ptr->expires) {
-                                       dapl_llist_add_entry(&g_daplTimerHead.
-                                                            timer_list_head,
-                                                            (DAPL_LLIST_ENTRY
-                                                             *) & list_ptr->
-                                                            list_entry,
-                                                            (DAPL_LLIST_ENTRY
-                                                             *) & timer->
-                                                            list_entry, timer);
-                                       break;
-
-                               }
-                               list_ptr =
-                                   dapl_llist_next_entry(&g_daplTimerHead.
-                                                         timer_list_head,
-                                                         (DAPL_LLIST_ENTRY *) &
-                                                         list_ptr->list_entry);
-                       }
-                       if (list_ptr == NULL) {
-                               /* entry goes to the end of the list */
-                               dapl_llist_add_tail(&g_daplTimerHead.
-                                                   timer_list_head,
-                                                   (DAPL_LLIST_ENTRY *) &
-                                                   timer->list_entry, timer);
-                       }
-               }
-
-       }
-       dapl_os_unlock(&g_daplTimerHead.lock);
-
-       if (wakeup_tmo_thread == DAT_TRUE) {
-               dapl_os_wait_object_wakeup(&g_daplTimerHead.wait_object);
-       }
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_os_timer_cancel
- *
- * Cancel a timer. Simply deletes the timer with no function invocations
- *
- * Input:
- *      timer    User provided timer structure
- *
- * Returns:
- *     no return value
- */
-void dapls_timer_cancel(IN DAPL_OS_TIMER * timer)
-{
-       dapl_os_lock(&g_daplTimerHead.lock);
-       /*
-        * make sure the entry has not been removed by another thread
-        */
-       if (!dapl_llist_is_empty(&g_daplTimerHead.timer_list_head) &&
-           timer->list_entry.list_head == &g_daplTimerHead.timer_list_head) {
-               dapl_llist_remove_entry(&g_daplTimerHead.timer_list_head,
-                                       (DAPL_LLIST_ENTRY *) & timer->
-                                       list_entry);
-       }
-       /*
-        * If this was the first entry on the queue we could awaken the
-        * thread and have it reset the list; but it will just wake up
-        * and find that the timer entry has been removed, then go back
-        * to sleep, so don't bother.
-        */
-       dapl_os_unlock(&g_daplTimerHead.lock);
-}
-
-/*
- * dapls_timer_thread
- *
- * Core worker thread dealing with all timers. Basic algorithm:
- *     - Sleep until work shows up
- *     - Take first element of sorted timer list and wake
- *       invoke the callback if expired
- *     - Sleep for the timeout period if not expired
- *
- * Input:
- *      timer_head    Timer head structure to manage timer lists
- *
- * Returns:
- *     no return value
- */
-void dapls_timer_thread(void *arg)
-{
-       DAPL_OS_TIMER *list_ptr;
-       DAPL_OS_TIMEVAL cur_time;
-       DAT_RETURN dat_status;
-       DAPL_TIMER_HEAD *timer_head;
-
-       timer_head = arg;
-
-       for (;;) {
-               if (dapl_llist_is_empty(&timer_head->timer_list_head)) {
-                       dat_status =
-                           dapl_os_wait_object_wait(&timer_head->wait_object,
-                                                    DAT_TIMEOUT_INFINITE);
-               }
-
-               /*
-                * Lock policy:
-                * While this thread is accessing the timer list, it holds the
-                * lock.  Otherwise, it doesn't.
-                */
-               dapl_os_lock(&timer_head->lock);
-               while (!dapl_llist_is_empty(&timer_head->timer_list_head)) {
-                       list_ptr = (DAPL_OS_TIMER *)
-                           dapl_llist_peek_head(&g_daplTimerHead.
-                                                timer_list_head);
-                       dapl_os_get_time(&cur_time);
-
-                       if (list_ptr->expires <= cur_time) {
-                               /*
-                                * Remove the entry from the list. Sort out how much
-                                * time we need to sleep for the next one
-                                */
-                               list_ptr =
-                                   dapl_llist_remove_head(&timer_head->
-                                                          timer_list_head);
-                               dapl_os_unlock(&timer_head->lock);
-
-                               /*
-                                * Invoke the user callback
-                                */
-                               list_ptr->function((uintptr_t) list_ptr->data);
-                               /* timer structure was allocated by caller, we don't
-                                * free it here.
-                                */
-
-                               /* reacquire the lock */
-                               dapl_os_lock(&timer_head->lock);
-                       } else {
-                               dapl_os_unlock(&timer_head->lock);
-                               dat_status =
-                                   dapl_os_wait_object_wait(&timer_head->
-                                                            wait_object,
-                                                            (DAT_TIMEOUT)
-                                                            (list_ptr->
-                                                             expires -
-                                                             cur_time));
-                               dapl_os_lock(&timer_head->lock);
-                       }
-               }
-               /*
-                * release the lock before going back to the top to sleep
-                */
-               dapl_os_unlock(&timer_head->lock);
-
-               if (dat_status == DAT_INTERNAL_ERROR) {
-                       /*
-                        * XXX What do we do here?
-                        */
-               }
-       }                       /* for (;;) */
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ *\r
+ * MODULE: dapl_timer_util.c\r
+ *\r
+ * PURPOSE: DAPL timer management\r
+ * Description: Routines to add and cancel timer records. A timer record\r
+ *             is put on the global timer queue. If the timer thread is\r
+ *             not running, start it. The timer thread will sleep\r
+ *             until a timer event or until a process wakes it up\r
+ *             to notice a new timer is available; we use a DAPL_WAIT_OBJ\r
+ *             for synchronization.\r
+ *\r
+ *             If a timer is cancelled, it is simlpy removed from the\r
+ *             queue. The timer may wakeup and notice there is no timer\r
+ *             record to awaken at this time, so it will reset for the\r
+ *             next entry. When there are no timer records to manage,\r
+ *             the timer thread just sleeps until awakened.\r
+ *\r
+ *             This file also contains the timer handler thread,\r
+ *             embodied in dapls_timer_thread().\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_timer_util.h"\r
+\r
+#define DAPL_TIMER_INIT    0\r
+#define DAPL_TIMER_RUN     1\r
+#define DAPL_TIMER_DESTROY 2\r
+#define DAPL_TIMER_EXIT    3\r
+\r
+struct timer_head {\r
+       DAPL_LLIST_HEAD timer_list_head;\r
+       DAPL_OS_LOCK lock;\r
+       DAPL_OS_WAIT_OBJECT wait_object;\r
+       DAPL_OS_THREAD timeout_thread_handle;\r
+       int state;\r
+} g_daplTimerHead;\r
+\r
+typedef struct timer_head DAPL_TIMER_HEAD;\r
+\r
+void dapls_timer_thread(void *arg);\r
+\r
+void dapls_timer_init()\r
+{\r
+       /*\r
+        * Set up the timer thread elements. The timer thread isn't\r
+        * started until it is actually needed\r
+        */\r
+       g_daplTimerHead.timer_list_head = NULL;\r
+       dapl_os_lock_init(&g_daplTimerHead.lock);\r
+       dapl_os_wait_object_init(&g_daplTimerHead.wait_object);\r
+       g_daplTimerHead.timeout_thread_handle = 0;\r
+       g_daplTimerHead.state = DAPL_TIMER_INIT;\r
+}\r
+\r
+void dapls_timer_release()\r
+{\r
+       dapl_os_lock(&g_daplTimerHead.lock);\r
+       if (g_daplTimerHead.state != DAPL_TIMER_RUN) {\r
+               dapl_os_unlock(&g_daplTimerHead.lock);\r
+               return;\r
+       }\r
+\r
+       g_daplTimerHead.state = DAPL_TIMER_DESTROY;\r
+       dapl_os_unlock(&g_daplTimerHead.lock);\r
+       while (g_daplTimerHead.state != DAPL_TIMER_EXIT) {\r
+               dapl_os_wait_object_wakeup(&g_daplTimerHead.wait_object);\r
+               dapl_os_sleep_usec(2000);\r
+       }\r
+}\r
+\r
+/*\r
+ * dapls_timer_set\r
+ *\r
+ * Set a timer. The timer will invoke the specified function\r
+ * after a number of useconds expires.\r
+ *\r
+ * Input:\r
+ *      timer    User provided timer structure\r
+ *      func     Function to invoke when timer expires\r
+ *      data     Argument passed to func()\r
+ *      expires  microseconds until timer fires\r
+ *\r
+ * Returns:\r
+ *     no return value\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_timer_set(IN DAPL_OS_TIMER * timer,\r
+               IN void (*func) (uintptr_t),\r
+               IN void *data, IN DAPL_OS_TIMEVAL expires)\r
+{\r
+       DAPL_OS_TIMER *list_ptr;\r
+       DAPL_OS_TIMEVAL cur_time;\r
+       DAT_BOOLEAN wakeup_tmo_thread;\r
+\r
+       /*\r
+        * Start the timer thread the first time we need a timer\r
+        */\r
+       if (g_daplTimerHead.timeout_thread_handle == 0) {\r
+               dapl_os_thread_create(dapls_timer_thread,\r
+                                     &g_daplTimerHead,\r
+                                     &g_daplTimerHead.timeout_thread_handle);\r
+               \r
+               while (g_daplTimerHead.state != DAPL_TIMER_RUN) \r
+                       dapl_os_sleep_usec(2000);\r
+       }\r
+\r
+       dapl_llist_init_entry(&timer->list_entry);\r
+       wakeup_tmo_thread = DAT_FALSE;\r
+       dapl_os_get_time(&cur_time);\r
+       timer->expires = cur_time + expires;    /* calculate future time */\r
+       timer->function = func;\r
+       timer->data = data;\r
+\r
+       /*\r
+        * Put the element on the queue: sorted by wakeup time, eariliest\r
+        * first.\r
+        */\r
+       dapl_os_lock(&g_daplTimerHead.lock);\r
+\r
+       if (g_daplTimerHead.state != DAPL_TIMER_RUN) {\r
+               dapl_os_unlock(&g_daplTimerHead.lock);\r
+               return DAT_INVALID_STATE;\r
+       }\r
+\r
+       /*\r
+        * Deal with 3 cases due to our list structure:\r
+        * 1) list is empty: become the list head\r
+        * 2) New timer is sooner than list head: become the list head\r
+        * 3) otherwise, sort the timer into the list, no need to wake\r
+        *    the timer thread up\r
+        */\r
+       if (dapl_llist_is_empty(&g_daplTimerHead.timer_list_head)) {\r
+               /* Case 1: add entry to head of list */\r
+               dapl_llist_add_head(&g_daplTimerHead.timer_list_head,\r
+                                   (DAPL_LLIST_ENTRY *) & timer->list_entry,\r
+                                   timer);\r
+               wakeup_tmo_thread = DAT_TRUE;\r
+       } else {\r
+               list_ptr = (DAPL_OS_TIMER *)\r
+                   dapl_llist_peek_head(&g_daplTimerHead.timer_list_head);\r
+\r
+               if (timer->expires < list_ptr->expires) {\r
+                       /* Case 2: add entry to head of list */\r
+                       dapl_llist_add_head(&g_daplTimerHead.timer_list_head,\r
+                                           (DAPL_LLIST_ENTRY *) & timer->\r
+                                           list_entry, timer);\r
+                       wakeup_tmo_thread = DAT_TRUE;\r
+               } else {\r
+                       /* Case 3: figure out where entry goes in sorted list */\r
+                       list_ptr =\r
+                           dapl_llist_next_entry(&g_daplTimerHead.\r
+                                                 timer_list_head,\r
+                                                 (DAPL_LLIST_ENTRY *) &\r
+                                                 list_ptr->list_entry);\r
+\r
+                       while (list_ptr != NULL) {\r
+                               if (timer->expires < list_ptr->expires) {\r
+                                       dapl_llist_add_entry(&g_daplTimerHead.\r
+                                                            timer_list_head,\r
+                                                            (DAPL_LLIST_ENTRY\r
+                                                             *) & list_ptr->\r
+                                                            list_entry,\r
+                                                            (DAPL_LLIST_ENTRY\r
+                                                             *) & timer->\r
+                                                            list_entry, timer);\r
+                                       break;\r
+\r
+                               }\r
+                               list_ptr =\r
+                                   dapl_llist_next_entry(&g_daplTimerHead.\r
+                                                         timer_list_head,\r
+                                                         (DAPL_LLIST_ENTRY *) &\r
+                                                         list_ptr->list_entry);\r
+                       }\r
+                       if (list_ptr == NULL) {\r
+                               /* entry goes to the end of the list */\r
+                               dapl_llist_add_tail(&g_daplTimerHead.\r
+                                                   timer_list_head,\r
+                                                   (DAPL_LLIST_ENTRY *) &\r
+                                                   timer->list_entry, timer);\r
+                       }\r
+               }\r
+\r
+       }\r
+       dapl_os_unlock(&g_daplTimerHead.lock);\r
+\r
+       if (wakeup_tmo_thread == DAT_TRUE) {\r
+               dapl_os_wait_object_wakeup(&g_daplTimerHead.wait_object);\r
+       }\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_os_timer_cancel\r
+ *\r
+ * Cancel a timer. Simply deletes the timer with no function invocations\r
+ *\r
+ * Input:\r
+ *      timer    User provided timer structure\r
+ *\r
+ * Returns:\r
+ *     no return value\r
+ */\r
+void dapls_timer_cancel(IN DAPL_OS_TIMER * timer)\r
+{\r
+       dapl_os_lock(&g_daplTimerHead.lock);\r
+       /*\r
+        * make sure the entry has not been removed by another thread\r
+        */\r
+       if (!dapl_llist_is_empty(&g_daplTimerHead.timer_list_head) &&\r
+           timer->list_entry.list_head == &g_daplTimerHead.timer_list_head) {\r
+               dapl_llist_remove_entry(&g_daplTimerHead.timer_list_head,\r
+                                       (DAPL_LLIST_ENTRY *) & timer->\r
+                                       list_entry);\r
+       }\r
+       /*\r
+        * If this was the first entry on the queue we could awaken the\r
+        * thread and have it reset the list; but it will just wake up\r
+        * and find that the timer entry has been removed, then go back\r
+        * to sleep, so don't bother.\r
+        */\r
+       dapl_os_unlock(&g_daplTimerHead.lock);\r
+}\r
+\r
+/*\r
+ * dapls_timer_thread\r
+ *\r
+ * Core worker thread dealing with all timers. Basic algorithm:\r
+ *     - Sleep until work shows up\r
+ *     - Take first element of sorted timer list and wake\r
+ *       invoke the callback if expired\r
+ *     - Sleep for the timeout period if not expired\r
+ *\r
+ * Input:\r
+ *      timer_head    Timer head structure to manage timer lists\r
+ *\r
+ * Returns:\r
+ *     no return value\r
+ */\r
+void dapls_timer_thread(void *arg)\r
+{\r
+       DAPL_OS_TIMER *list_ptr;\r
+       DAPL_OS_TIMEVAL cur_time;\r
+       DAT_RETURN dat_status;\r
+       DAPL_TIMER_HEAD *timer_head;\r
+\r
+       timer_head = arg;\r
+\r
+       dapl_os_lock(&timer_head->lock);\r
+       timer_head->state = DAPL_TIMER_RUN;\r
+       dapl_os_unlock(&timer_head->lock);\r
+\r
+       for (;;) {\r
+               if (dapl_llist_is_empty(&timer_head->timer_list_head)) {\r
+                       dat_status =\r
+                           dapl_os_wait_object_wait(&timer_head->wait_object,\r
+                                                    DAT_TIMEOUT_INFINITE);\r
+               }\r
+\r
+               /*\r
+                * Lock policy:\r
+                * While this thread is accessing the timer list, it holds the\r
+                * lock.  Otherwise, it doesn't.\r
+                */\r
+               dapl_os_lock(&timer_head->lock);\r
+               while (!dapl_llist_is_empty(&timer_head->timer_list_head)) {\r
+                       list_ptr = (DAPL_OS_TIMER *)\r
+                           dapl_llist_peek_head(&g_daplTimerHead.\r
+                                                timer_list_head);\r
+                       dapl_os_get_time(&cur_time);\r
+\r
+                       if (list_ptr->expires <= cur_time || \r
+                           timer_head->state == DAPL_TIMER_DESTROY) {\r
+\r
+                               /*\r
+                                * Remove the entry from the list. Sort out how much\r
+                                * time we need to sleep for the next one\r
+                                */\r
+                               list_ptr =\r
+                                   dapl_llist_remove_head(&timer_head->\r
+                                                          timer_list_head);\r
+                               dapl_os_unlock(&timer_head->lock);\r
+\r
+                               /*\r
+                                * Invoke the user callback\r
+                                */\r
+                               list_ptr->function((uintptr_t) list_ptr->data);\r
+                               /* timer structure was allocated by caller, we don't\r
+                                * free it here.\r
+                                */\r
+\r
+                               /* reacquire the lock */\r
+                               dapl_os_lock(&timer_head->lock);\r
+                       } else {\r
+                               dapl_os_unlock(&timer_head->lock);\r
+                               dat_status =\r
+                                   dapl_os_wait_object_wait(&timer_head->\r
+                                                            wait_object,\r
+                                                            (DAT_TIMEOUT)\r
+                                                            (list_ptr->\r
+                                                             expires -\r
+                                                             cur_time));\r
+                               dapl_os_lock(&timer_head->lock);\r
+                       }\r
+               }\r
+\r
+               /* Destroy - all timers triggered and list is empty */\r
+               if (timer_head->state == DAPL_TIMER_DESTROY) {\r
+                       timer_head->state = DAPL_TIMER_EXIT;\r
+                       dapl_os_unlock(&timer_head->lock);\r
+                       break;\r
+               }\r
+\r
+               /*\r
+                * release the lock before going back to the top to sleep\r
+                */\r
+               dapl_os_unlock(&timer_head->lock);\r
+\r
+               if (dat_status == DAT_INTERNAL_ERROR) {\r
+                       /*\r
+                        * XXX What do we do here?\r
+                        */\r
+               }\r
+       }                       /* for (;;) */\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index c24d26a..fdaa93a 100644 (file)
@@ -1,47 +1,48 @@
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * HEADER: dapl_timer_util.h
- *
- * PURPOSE: DAPL timer management
- * Description: support for dapl_timer.h
- *
- * $Id:$
- **********************************************************************/
-
-void dapls_timer_init ( void );
-
-DAT_RETURN dapls_timer_set (
-       IN  DAPL_OS_TIMER               *timer,
-       IN  void                        (*func) (uintptr_t),
-       IN  void                        *data,
-       IN  DAPL_OS_TIMEVAL             expires );
-
-void dapls_timer_cancel (
-       IN  DAPL_OS_TIMER               *timer);
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ *\r
+ * HEADER: dapl_timer_util.h\r
+ *\r
+ * PURPOSE: DAPL timer management\r
+ * Description: support for dapl_timer.h\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+void dapls_timer_init ( void );\r
+void dapls_timer_release( void );\r
+\r
+DAT_RETURN dapls_timer_set (\r
+       IN  DAPL_OS_TIMER               *timer,\r
+       IN  void                        (*func) (uintptr_t),\r
+       IN  void                        *data,\r
+       IN  DAPL_OS_TIMEVAL             expires );\r
+\r
+void dapls_timer_cancel (\r
+       IN  DAPL_OS_TIMER               *timer);\r
index 5631fe7..5c1709a 100644 (file)
@@ -644,11 +644,7 @@ dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)
                return DAT_SUCCESS;\r
 \r
        /* no graceful half-pipe disconnect option */\r
-       ret = rdma_disconnect(conn->cm_id);\r
-       if (ret)\r
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
-                            " disconnect: ID %p ret 0x%x\n",\r
-                            ep_ptr->cm_handle, ret);\r
+       rdma_disconnect(conn->cm_id);\r
 \r
        /* \r
         * DAT event notification occurs from the callback\r
index c9d5081..9266b04 100644 (file)
-/*
- * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dapl_ib_util.c
- *
- * PURPOSE: OFED provider - init, open, close, utilities, work thread
- *
- * $Id:$
- *
- **********************************************************************/
-
-#ifdef RCSID
-static const char rcsid[] = "$Id:  $";
-#endif
-
-#include "openib_osd.h"
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_ib_util.h"
-#include "dapl_osd.h"
-
-#include <stdlib.h>
-
-struct rdma_event_channel *g_cm_events = NULL;
-ib_thread_state_t g_ib_thread_state = 0;
-DAPL_OS_THREAD g_ib_thread;
-DAPL_OS_LOCK g_hca_lock;
-struct dapl_llist_entry *g_hca_list;
-
-#if defined(_WIN64) || defined(_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
-#include <rdma\winverbs.h>
-
-static COMP_SET ufds;
-
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       IWVProvider *prov;
-       WV_DEVICE_ADDRESS devaddr;
-       struct addrinfo *res, *ai;
-       HRESULT hr;
-       int index;
-
-       if (strncmp(name, "rdma_dev", 8)) {
-               return EINVAL;
-       }
-
-       index = atoi(name + 8);
-
-       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);
-       if (FAILED(hr)) {
-               return hr;
-       }
-
-       hr = getaddrinfo("..localmachine", NULL, NULL, &res);
-       if (hr) {
-               goto release;
-       }
-
-       for (ai = res; ai; ai = ai->ai_next) {
-               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);
-               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {
-                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);
-                       goto free;
-               }
-       }
-       hr = ENODEV;
-
-free:
-       freeaddrinfo(res);
-release:
-       prov->lpVtbl->Release(prov);
-       return hr;
-}
-
-static int dapls_os_init(void)
-{
-       return CompSetInit(&ufds);
-}
-
-static void dapls_os_release(void)
-{
-       CompSetCleanup(&ufds);
-}
-
-static int dapls_config_cm_channel(struct rdma_event_channel *channel)
-{
-       channel->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       verbs->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       channel->comp_channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_thread_signal(void)
-{
-       CompSetCancel(&ufds);
-       return 0;
-}
-#else                          // _WIN64 || WIN32
-int g_ib_pipe[2];
-
-static int dapls_os_init(void)
-{
-       /* create pipe for waking up work thread */
-       return pipe(g_ib_pipe);
-}
-
-static void dapls_os_release(void)
-{
-       /* close pipe? */
-}
-
-/* Get IP address using network device name */
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       struct ifreq ifr;
-       int skfd, ret, len;
-
-       /* Fill in the structure */
-       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
-       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;
-
-       /* Create a socket fd */
-       skfd = socket(PF_INET, SOCK_STREAM, 0);
-       ret = ioctl(skfd, SIOCGIFADDR, &ifr);
-       if (ret)
-               goto bail;
-
-       switch (ifr.ifr_addr.sa_family) {
-#ifdef AF_INET6
-       case AF_INET6:
-               len = sizeof(struct sockaddr_in6);
-               break;
-#endif
-       case AF_INET:
-       default:
-               len = sizeof(struct sockaddr);
-               break;
-       }
-
-       if (len <= addr_len)
-               memcpy(addr, &ifr.ifr_addr, len);
-       else
-               ret = EINVAL;
-
-      bail:
-       close(skfd);
-       return ret;
-}
-
-static int dapls_config_fd(int fd)
-{
-       int opts;
-
-       opts = fcntl(fd, F_GETFL);
-       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",
-                        fd, opts, strerror(errno));
-               return errno;
-       }
-
-       return 0;
-}
-
-static int dapls_config_cm_channel(struct rdma_event_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       return dapls_config_fd(verbs->async_fd);
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-static int dapls_thread_signal(void)
-{
-       return write(g_ib_pipe[1], "w", sizeof "w");
-}
-#endif
-
-/* Get IP address using network name, address, or device name */
-static int getipaddr(char *name, char *addr, int len)
-{
-       struct addrinfo *res;
-
-       /* assume netdev for first attempt, then network and address type */
-       if (getipaddr_netdev(name, addr, len)) {
-               if (getaddrinfo(name, NULL, NULL, &res)) {
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                " open_hca: getaddr_netdev ERROR:"
-                                " %s. Is %s configured?\n",
-                                strerror(errno), name);
-                       return 1;
-               } else {
-                       if (len >= res->ai_addrlen)
-                               memcpy(addr, res->ai_addr, res->ai_addrlen);
-                       else {
-                               freeaddrinfo(res);
-                               return 1;
-                       }
-                       freeaddrinfo(res);
-               }
-       }
-
-       dapl_dbg_log(
-               DAPL_DBG_TYPE_UTIL,
-               " getipaddr: family %d port %d addr %d.%d.%d.%d\n",
-               ((struct sockaddr_in *)addr)->sin_family,
-               ((struct sockaddr_in *)addr)->sin_port,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.
-                s_addr >> 24 & 0xff);
-
-       return 0;
-}
-
-/*
- * dapls_ib_init, dapls_ib_release
- *
- * Initialize Verb related items for device open
- *
- * Input:
- *     none
- *
- * Output:
- *     none
- *
- * Returns:
- *     0 success, -1 error
- *
- */
-int32_t dapls_ib_init(void)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_init: \n");
-
-       /* initialize hca_list lock */
-       dapl_os_lock_init(&g_hca_lock);
-
-       /* initialize hca list for CQ events */
-       dapl_llist_init_head(&g_hca_list);
-
-       if (dapls_os_init())
-               return 1;
-
-       return 0;
-}
-
-int32_t dapls_ib_release(void)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_release: \n");
-       dapli_ib_thread_destroy();
-       if (g_cm_events != NULL)
-               rdma_destroy_event_channel(g_cm_events);
-       dapls_os_release();
-       return 0;
-}
-
-/*
- * dapls_ib_open_hca
- *
- * Open HCA
- *
- * Input:
- *      *hca_name         pointer to provider device name
- *      *ib_hca_handle_p  pointer to provide HCA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *      dapl_convert_errno
- *
- */
-DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
-{
-       struct rdma_cm_id *cm_id = NULL;
-       union ibv_gid *gid;
-       int ret;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: %s - %p\n", hca_name, hca_ptr);
-
-       /* Setup the global cm event channel */
-       dapl_os_lock(&g_hca_lock);
-       if (g_cm_events == NULL) {
-               g_cm_events = rdma_create_event_channel();
-               if (g_cm_events == NULL) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                                    " open_hca: ERR - RDMA channel %s\n",
-                                    strerror(errno));
-                       dapl_os_unlock(&g_hca_lock);
-                       return DAT_INTERNAL_ERROR;
-               }
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: RDMA channel created (%p)\n", g_cm_events);
-
-       /* HCA name will be hostname or IP address */
-       if (getipaddr((char *)hca_name,
-                     (char *)&hca_ptr->hca_address, 
-                     sizeof(DAT_SOCK_ADDR6)))
-               return DAT_INVALID_ADDRESS;
-
-       /* cm_id will bind local device/GID based on IP address */
-       if (rdma_create_id(g_cm_events, &cm_id, 
-                          (void *)hca_ptr, RDMA_PS_TCP)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: rdma_create ERR %s\n", strerror(errno));
-               return DAT_INTERNAL_ERROR;
-       }
-       ret = rdma_bind_addr(cm_id, (struct sockaddr *)&hca_ptr->hca_address);
-       if ((ret) || (cm_id->verbs == NULL)) {
-               rdma_destroy_id(cm_id);
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: rdma_bind ERR %s."
-                        " Is %s configured?\n", strerror(errno), hca_name);
-               rdma_destroy_id(cm_id);
-               return DAT_INVALID_ADDRESS;
-       }
-
-       /* keep reference to IB device and cm_id */
-       hca_ptr->ib_trans.cm_id = cm_id;
-       hca_ptr->ib_hca_handle = cm_id->verbs;
-       dapls_config_verbs(cm_id->verbs);
-       hca_ptr->port_num = cm_id->port_num;
-       hca_ptr->ib_trans.ib_dev = cm_id->verbs->device;
-       hca_ptr->ib_trans.ib_ctx = cm_id->verbs;
-       gid = &cm_id->route.addr.addr.ibaddr.sgid;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: ctx=%p port=%d GID subnet %016llx"
-                    " id %016llx\n", cm_id->verbs, cm_id->port_num,
-                    (unsigned long long)ntohll(gid->global.subnet_prefix),
-                    (unsigned long long)ntohll(gid->global.interface_id));
-
-       /* support for EVD's with CNO's: one channel via thread */
-       hca_ptr->ib_trans.ib_cq =
-           ibv_create_comp_channel(hca_ptr->ib_hca_handle);
-       if (hca_ptr->ib_trans.ib_cq == NULL) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: ibv_create_comp_channel ERR %s\n",
-                        strerror(errno));
-               rdma_destroy_id(cm_id);
-               return DAT_INTERNAL_ERROR;
-       }
-       if (dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq)) {
-               rdma_destroy_id(cm_id);
-               return DAT_INTERNAL_ERROR;
-       }
-
-       /* set inline max with env or default, get local lid and gid 0 */
-       if (hca_ptr->ib_hca_handle->device->transport_type
-           == IBV_TRANSPORT_IWARP)
-               hca_ptr->ib_trans.max_inline_send =
-                   dapl_os_get_env_val("DAPL_MAX_INLINE",
-                                       INLINE_SEND_IWARP_DEFAULT);
-       else
-               hca_ptr->ib_trans.max_inline_send =
-                   dapl_os_get_env_val("DAPL_MAX_INLINE",
-                                       INLINE_SEND_IB_DEFAULT);
-
-       /* set CM timer defaults */
-       hca_ptr->ib_trans.max_cm_timeout =
-           dapl_os_get_env_val("DAPL_MAX_CM_RESPONSE_TIME",
-                               IB_CM_RESPONSE_TIMEOUT);
-       hca_ptr->ib_trans.max_cm_retries =
-           dapl_os_get_env_val("DAPL_MAX_CM_RETRIES", IB_CM_RETRIES);
-       
-       /* set default IB MTU */
-       hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048);
-
-       dat_status = dapli_ib_thread_init();
-       if (dat_status != DAT_SUCCESS)
-               return dat_status;
-       /* 
-        * Put new hca_transport on list for async and CQ event processing 
-        * Wakeup work thread to add to polling list
-        */
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry);
-       dapl_os_lock(&g_hca_lock);
-       dapl_llist_add_tail(&g_hca_list,
-                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,
-                           &hca_ptr->ib_trans.entry);
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " open_hca: thread wakeup error = %s\n",
-                        strerror(errno));
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: %s, %s %d.%d.%d.%d INLINE_MAX=%d\n", hca_name,
-                    ((struct sockaddr_in *)
-                    &hca_ptr->hca_address)->sin_family == AF_INET ?
-                    "AF_INET" : "AF_INET6", 
-                    ((struct sockaddr_in *)
-                    &hca_ptr->hca_address)->sin_addr.s_addr >> 0 & 0xff, 
-                    ((struct sockaddr_in *)
-                    &hca_ptr->hca_address)->sin_addr.s_addr >> 8 & 0xff, 
-                    ((struct sockaddr_in *)
-                    &hca_ptr->hca_address)->sin_addr.s_addr >> 16 & 0xff, 
-                    ((struct sockaddr_in *)
-                    &hca_ptr->hca_address)->sin_addr.s_addr >> 24 & 0xff, 
-                    hca_ptr->ib_trans.max_inline_send);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_close_hca
- *
- * Open HCA
- *
- * Input:
- *      DAPL_HCA   provide CA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *     dapl_convert_errno 
- *
- */
-DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p->%p\n",
-                    hca_ptr, hca_ptr->ib_hca_handle);
-
-       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {
-               if (rdma_destroy_id(hca_ptr->ib_trans.cm_id))
-                       return (dapl_convert_errno(errno, "ib_close_device"));
-               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-       }
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_os_unlock(&g_hca_lock);
-               goto bail;
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       /* 
-        * Remove hca from async event processing list
-        * Wakeup work thread to remove from polling list
-        */
-       hca_ptr->ib_trans.destroy = 1;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-
-       /* wait for thread to remove HCA references */
-       while (hca_ptr->ib_trans.destroy != 2) {
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_destroy: wait on hca %p destroy\n");
-               dapl_os_sleep_usec(1000);
-       }
-bail:
-       return (DAT_SUCCESS);
-}
-
-
-DAT_RETURN dapli_ib_thread_init(void)
-{
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_init(%d)\n", dapl_os_getpid());
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_INIT) {
-               dapl_os_unlock(&g_hca_lock);
-               return DAT_SUCCESS;
-       }
-
-       /* uCMA events non-blocking */
-       if (dapls_config_cm_channel(g_cm_events)) {
-               dapl_os_unlock(&g_hca_lock);
-               return (dapl_convert_errno(errno, "create_thread ERR: cm_fd"));
-       }
-
-       g_ib_thread_state = IB_THREAD_CREATE;
-       dapl_os_unlock(&g_hca_lock);
-
-       /* create thread to process inbound connect request */
-       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);
-       if (dat_status != DAT_SUCCESS)
-               return (dapl_convert_errno(errno,
-                                          "create_thread ERR:"
-                                          " check resource limits"));
-
-       /* wait for thread to start */
-       dapl_os_lock(&g_hca_lock);
-       while (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_init: waiting for ib_thread\n");
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(1000);
-               dapl_os_lock(&g_hca_lock);
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_init(%d) exit\n", dapl_os_getpid());
-
-       return DAT_SUCCESS;
-}
-
-void dapli_ib_thread_destroy(void)
-{
-       int retries = 10;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d)\n", dapl_os_getpid());
-       /* 
-        * wait for async thread to terminate. 
-        * pthread_join would be the correct method
-        * but some applications have some issues
-        */
-
-       /* destroy ib_thread, wait for termination, if not already */
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN)
-               goto bail;
-
-       g_ib_thread_state = IB_THREAD_CANCEL;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-       while ((g_ib_thread_state != IB_THREAD_EXIT) && (retries--)) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_destroy: waiting for ib_thread\n");
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(2000);
-               dapl_os_lock(&g_hca_lock);
-       }
-bail:
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());
-}
-
-#if defined(_WIN64) || defined(_WIN32)
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct _ib_hca_transport *hca;
-       struct _ib_hca_transport *uhca[8];
-       COMP_CHANNEL *channel;
-       int ret, idx, cnt;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",
-                    dapl_os_getpid(), g_ib_thread);
-
-       dapl_os_lock(&g_hca_lock);
-       for (g_ib_thread_state = IB_THREAD_RUN;
-            g_ib_thread_state == IB_THREAD_RUN; 
-            dapl_os_lock(&g_hca_lock)) {
-
-               CompSetZero(&ufds);
-               CompSetAdd(&g_cm_events->channel, &ufds);
-
-               idx = 0;
-               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :
-                     dapl_llist_peek_head(&g_hca_list);
-
-               while (hca) {
-                       CompSetAdd(&hca->ib_ctx->channel, &ufds);
-                       CompSetAdd(&hca->ib_cq->comp_channel, &ufds);
-                       uhca[idx++] = hca;
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *)
-                                                   &hca->entry);
-               }
-               cnt = idx;
-
-               dapl_os_unlock(&g_hca_lock);
-               ret = CompSetPoll(&ufds, INFINITE);
-
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread(%d) poll_event 0x%x\n",
-                            dapl_os_getpid(), ret);
-
-               dapli_cma_event_cb();
-
-               /* check and process ASYNC events, per device */
-               for (idx = 0; idx < cnt; idx++) {
-                       if (uhca[idx]->destroy == 1) {
-                               dapl_os_lock(&g_hca_lock);
-                               dapl_llist_remove_entry(&g_hca_list,
-                                                       (DAPL_LLIST_ENTRY *)
-                                                       &uhca[idx]->entry);
-                               dapl_os_unlock(&g_hca_lock);
-                               uhca[idx]->destroy = 2;
-                       } else {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#else                          // _WIN64 || WIN32
-
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct pollfd ufds[__FD_SETSIZE];
-       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };
-       struct _ib_hca_transport *hca;
-       int ret, idx, fds;
-       char rbuf[2];
-
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                    " ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",
-                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0],
-                    g_cm_events->fd);
-
-       /* Poll across pipe, CM, AT never changes */
-       dapl_os_lock(&g_hca_lock);
-       g_ib_thread_state = IB_THREAD_RUN;
-
-       ufds[0].fd = g_ib_pipe[0];      /* pipe */
-       ufds[0].events = POLLIN;
-       ufds[1].fd = g_cm_events->fd;   /* uCMA */
-       ufds[1].events = POLLIN;
-
-       while (g_ib_thread_state == IB_THREAD_RUN) {
-
-               /* build ufds after pipe and uCMA events */
-               ufds[0].revents = 0;
-               ufds[1].revents = 0;
-               idx = 1;
-
-               /*  Walk HCA list and setup async and CQ events */
-               if (!dapl_llist_is_empty(&g_hca_list))
-                       hca = dapl_llist_peek_head(&g_hca_list);
-               else
-                       hca = NULL;
-
-               while (hca) {
-
-                       /* uASYNC events */
-                       ufds[++idx].fd = hca->ib_ctx->async_fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       /* CQ events are non-direct with CNO's */
-                       ufds[++idx].fd = hca->ib_cq->fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"
-                                    " async=%d pipe=%d cm=%d \n",
-                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,
-                                    ufds[0].fd, ufds[1].fd);
-
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *)
-                                                   &hca->entry);
-               }
-
-               /* unlock, and setup poll */
-               fds = idx + 1;
-               dapl_os_unlock(&g_hca_lock);
-               ret = poll(ufds, fds, -1);
-               if (ret <= 0) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                                    " ib_thread(%d): ERR %s poll\n",
-                                    dapl_os_getpid(), strerror(errno));
-                       dapl_os_lock(&g_hca_lock);
-                       continue;
-               }
-
-               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                            " ib_thread(%d) poll_event: "
-                            " async=0x%x pipe=0x%x cm=0x%x \n",
-                            dapl_os_getpid(), ufds[idx].revents,
-                            ufds[0].revents, ufds[1].revents);
-
-               /* uCMA events */
-               if (ufds[1].revents == POLLIN)
-                       dapli_cma_event_cb();
-
-               /* check and process CQ and ASYNC events, per device */
-               for (idx = 2; idx < fds; idx++) {
-                       if (ufds[idx].revents == POLLIN) {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-
-               /* check and process user events, PIPE */
-               if (ufds[0].revents == POLLIN) {
-                       if (read(g_ib_pipe[0], rbuf, 2) == -1)
-                               dapl_log(DAPL_DBG_TYPE_THREAD,
-                                        " cr_thread: pipe rd err= %s\n",
-                                        strerror(errno));
-
-                       /* cleanup any device on list marked for destroy */
-                       for (idx = 3; idx < fds; idx++) {
-                               if (uhca[idx] && uhca[idx]->destroy == 1) {
-                                       dapl_os_lock(&g_hca_lock);
-                                       dapl_llist_remove_entry(
-                                               &g_hca_list,
-                                               (DAPL_LLIST_ENTRY*)
-                                               &uhca[idx]->entry);
-                                       dapl_os_unlock(&g_hca_lock);
-                                       uhca[idx]->destroy = 2;
-                               }
-                       }
-               }
-               dapl_os_lock(&g_hca_lock);
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#endif
+/*\r
+ * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_ib_util.c\r
+ *\r
+ * PURPOSE: OFED provider - init, open, close, utilities, work thread\r
+ *\r
+ * $Id:$\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifdef RCSID\r
+static const char rcsid[] = "$Id:  $";\r
+#endif\r
+\r
+#include "openib_osd.h"\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_ib_util.h"\r
+#include "dapl_osd.h"\r
+\r
+#include <stdlib.h>\r
+\r
+struct rdma_event_channel *g_cm_events = NULL;\r
+ib_thread_state_t g_ib_thread_state = 0;\r
+DAPL_OS_THREAD g_ib_thread;\r
+DAPL_OS_LOCK g_hca_lock;\r
+struct dapl_llist_entry *g_hca_list;\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"\r
+#include <rdma\winverbs.h>\r
+\r
+static COMP_SET ufds;\r
+\r
+static int getipaddr_netdev(char *name, char *addr, int addr_len)\r
+{\r
+       IWVProvider *prov;\r
+       WV_DEVICE_ADDRESS devaddr;\r
+       struct addrinfo *res, *ai;\r
+       HRESULT hr;\r
+       int index;\r
+\r
+       if (strncmp(name, "rdma_dev", 8)) {\r
+               return EINVAL;\r
+       }\r
+\r
+       index = atoi(name + 8);\r
+\r
+       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);\r
+       if (FAILED(hr)) {\r
+               return hr;\r
+       }\r
+\r
+       hr = getaddrinfo("..localmachine", NULL, NULL, &res);\r
+       if (hr) {\r
+               goto release;\r
+       }\r
+\r
+       for (ai = res; ai; ai = ai->ai_next) {\r
+               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);\r
+               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {\r
+                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);\r
+                       goto free;\r
+               }\r
+       }\r
+       hr = ENODEV;\r
+\r
+free:\r
+       freeaddrinfo(res);\r
+release:\r
+       prov->lpVtbl->Release(prov);\r
+       return hr;\r
+}\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       return CompSetInit(&ufds);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       CompSetCleanup(&ufds);\r
+}\r
+\r
+static int dapls_config_cm_channel(struct rdma_event_channel *channel)\r
+{\r
+       channel->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       verbs->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       channel->comp_channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       CompSetCancel(&ufds);\r
+       return 0;\r
+}\r
+#else                          // _WIN64 || WIN32\r
+int g_ib_pipe[2];\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       /* create pipe for waking up work thread */\r
+       return pipe(g_ib_pipe);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       /* close pipe? */\r
+}\r
+\r
+/* Get IP address using network device name */\r
+static int getipaddr_netdev(char *name, char *addr, int addr_len)\r
+{\r
+       struct ifreq ifr;\r
+       int skfd, ret, len;\r
+\r
+       /* Fill in the structure */\r
+       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);\r
+       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;\r
+\r
+       /* Create a socket fd */\r
+       skfd = socket(PF_INET, SOCK_STREAM, 0);\r
+       ret = ioctl(skfd, SIOCGIFADDR, &ifr);\r
+       if (ret)\r
+               goto bail;\r
+\r
+       switch (ifr.ifr_addr.sa_family) {\r
+#ifdef AF_INET6\r
+       case AF_INET6:\r
+               len = sizeof(struct sockaddr_in6);\r
+               break;\r
+#endif\r
+       case AF_INET:\r
+       default:\r
+               len = sizeof(struct sockaddr);\r
+               break;\r
+       }\r
+\r
+       if (len <= addr_len)\r
+               memcpy(addr, &ifr.ifr_addr, len);\r
+       else\r
+               ret = EINVAL;\r
+\r
+      bail:\r
+       close(skfd);\r
+       return ret;\r
+}\r
+\r
+static int dapls_config_fd(int fd)\r
+{\r
+       int opts;\r
+\r
+       opts = fcntl(fd, F_GETFL);\r
+       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",\r
+                        fd, opts, strerror(errno));\r
+               return errno;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_cm_channel(struct rdma_event_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       return dapls_config_fd(verbs->async_fd);\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       return write(g_ib_pipe[1], "w", sizeof "w");\r
+}\r
+#endif\r
+\r
+/* Get IP address using network name, address, or device name */\r
+static int getipaddr(char *name, char *addr, int len)\r
+{\r
+       struct addrinfo *res;\r
+\r
+       /* assume netdev for first attempt, then network and address type */\r
+       if (getipaddr_netdev(name, addr, len)) {\r
+               if (getaddrinfo(name, NULL, NULL, &res)) {\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                " open_hca: getaddr_netdev ERROR:"\r
+                                " %s. Is %s configured?\n",\r
+                                strerror(errno), name);\r
+                       return 1;\r
+               } else {\r
+                       if (len >= res->ai_addrlen)\r
+                               memcpy(addr, res->ai_addr, res->ai_addrlen);\r
+                       else {\r
+                               freeaddrinfo(res);\r
+                               return 1;\r
+                       }\r
+                       freeaddrinfo(res);\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(\r
+               DAPL_DBG_TYPE_UTIL,\r
+               " getipaddr: family %d port %d addr %d.%d.%d.%d\n",\r
+               ((struct sockaddr_in *)addr)->sin_family,\r
+               ((struct sockaddr_in *)addr)->sin_port,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.\r
+                s_addr >> 24 & 0xff);\r
+\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * dapls_ib_init, dapls_ib_release\r
+ *\r
+ * Initialize Verb related items for device open\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     0 success, -1 error\r
+ *\r
+ */\r
+int32_t dapls_ib_init(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_init: \n");\r
+\r
+       /* initialize hca_list lock */\r
+       dapl_os_lock_init(&g_hca_lock);\r
+\r
+       /* initialize hca list for CQ events */\r
+       dapl_llist_init_head(&g_hca_list);\r
+\r
+       if (dapls_os_init())\r
+               return 1;\r
+\r
+       return 0;\r
+}\r
+\r
+int32_t dapls_ib_release(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_release: \n");\r
+       dapli_ib_thread_destroy();\r
+       if (g_cm_events != NULL)\r
+               rdma_destroy_event_channel(g_cm_events);\r
+       dapls_os_release();\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * dapls_ib_open_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      *hca_name         pointer to provider device name\r
+ *      *ib_hca_handle_p  pointer to provide HCA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *      dapl_convert_errno\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)\r
+{\r
+       struct rdma_cm_id *cm_id = NULL;\r
+       union ibv_gid *gid;\r
+       int ret;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: %s - %p\n", hca_name, hca_ptr);\r
+\r
+       /* Setup the global cm event channel */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_cm_events == NULL) {\r
+               g_cm_events = rdma_create_event_channel();\r
+               if (g_cm_events == NULL) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                                    " open_hca: ERR - RDMA channel %s\n",\r
+                                    strerror(errno));\r
+                       dapl_os_unlock(&g_hca_lock);\r
+                       return DAT_INTERNAL_ERROR;\r
+               }\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: RDMA channel created (%p)\n", g_cm_events);\r
+\r
+       /* HCA name will be hostname or IP address */\r
+       if (getipaddr((char *)hca_name,\r
+                     (char *)&hca_ptr->hca_address, \r
+                     sizeof(DAT_SOCK_ADDR6)))\r
+               return DAT_INVALID_ADDRESS;\r
+\r
+       /* cm_id will bind local device/GID based on IP address */\r
+       if (rdma_create_id(g_cm_events, &cm_id, \r
+                          (void *)hca_ptr, RDMA_PS_TCP)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: rdma_create ERR %s\n", strerror(errno));\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+       ret = rdma_bind_addr(cm_id, (struct sockaddr *)&hca_ptr->hca_address);\r
+       if ((ret) || (cm_id->verbs == NULL)) {\r
+               rdma_destroy_id(cm_id);\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: rdma_bind ERR %s."\r
+                        " Is %s configured?\n", strerror(errno), hca_name);\r
+               rdma_destroy_id(cm_id);\r
+               return DAT_INVALID_ADDRESS;\r
+       }\r
+\r
+       /* keep reference to IB device and cm_id */\r
+       hca_ptr->ib_trans.cm_id = cm_id;\r
+       hca_ptr->ib_hca_handle = cm_id->verbs;\r
+       dapls_config_verbs(cm_id->verbs);\r
+       hca_ptr->port_num = cm_id->port_num;\r
+       hca_ptr->ib_trans.ib_dev = cm_id->verbs->device;\r
+       hca_ptr->ib_trans.ib_ctx = cm_id->verbs;\r
+       gid = &cm_id->route.addr.addr.ibaddr.sgid;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: ctx=%p port=%d GID subnet %016llx"\r
+                    " id %016llx\n", cm_id->verbs, cm_id->port_num,\r
+                    (unsigned long long)ntohll(gid->global.subnet_prefix),\r
+                    (unsigned long long)ntohll(gid->global.interface_id));\r
+\r
+       /* support for EVD's with CNO's: one channel via thread */\r
+       hca_ptr->ib_trans.ib_cq =\r
+           ibv_create_comp_channel(hca_ptr->ib_hca_handle);\r
+       if (hca_ptr->ib_trans.ib_cq == NULL) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: ibv_create_comp_channel ERR %s\n",\r
+                        strerror(errno));\r
+               rdma_destroy_id(cm_id);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+       if (dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq)) {\r
+               rdma_destroy_id(cm_id);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
+       /* set inline max with env or default, get local lid and gid 0 */\r
+       if (hca_ptr->ib_hca_handle->device->transport_type\r
+           == IBV_TRANSPORT_IWARP)\r
+               hca_ptr->ib_trans.max_inline_send =\r
+                   dapl_os_get_env_val("DAPL_MAX_INLINE",\r
+                                       INLINE_SEND_IWARP_DEFAULT);\r
+       else\r
+               hca_ptr->ib_trans.max_inline_send =\r
+                   dapl_os_get_env_val("DAPL_MAX_INLINE",\r
+                                       INLINE_SEND_IB_DEFAULT);\r
+\r
+       /* set CM timer defaults */\r
+       hca_ptr->ib_trans.max_cm_timeout =\r
+           dapl_os_get_env_val("DAPL_MAX_CM_RESPONSE_TIME",\r
+                               IB_CM_RESPONSE_TIMEOUT);\r
+       hca_ptr->ib_trans.max_cm_retries =\r
+           dapl_os_get_env_val("DAPL_MAX_CM_RETRIES", IB_CM_RETRIES);\r
+       \r
+       /* set default IB MTU */\r
+       hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048);\r
+\r
+       dat_status = dapli_ib_thread_init();\r
+       if (dat_status != DAT_SUCCESS)\r
+               return dat_status;\r
+       /* \r
+        * Put new hca_transport on list for async and CQ event processing \r
+        * Wakeup work thread to add to polling list\r
+        */\r
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry);\r
+       dapl_os_lock(&g_hca_lock);\r
+       dapl_llist_add_tail(&g_hca_list,\r
+                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,\r
+                           &hca_ptr->ib_trans.entry);\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " open_hca: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: %s, %s %d.%d.%d.%d INLINE_MAX=%d\n", hca_name,\r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_family == AF_INET ?\r
+                    "AF_INET" : "AF_INET6", \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 0 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 8 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 16 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 24 & 0xff, \r
+                    hca_ptr->ib_trans.max_inline_send);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_close_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      DAPL_HCA   provide CA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *     dapl_convert_errno \r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p->%p\n",\r
+                    hca_ptr, hca_ptr->ib_hca_handle);\r
+\r
+       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
+               if (rdma_destroy_id(hca_ptr->ib_trans.cm_id))\r
+                       return (dapl_convert_errno(errno, "ib_close_device"));\r
+               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+       }\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               goto bail;\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* \r
+        * Remove hca from async event processing list\r
+        * Wakeup work thread to remove from polling list\r
+        */\r
+       hca_ptr->ib_trans.destroy = 1;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+\r
+       /* wait for thread to remove HCA references */\r
+       while (hca_ptr->ib_trans.destroy != 2) {\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: wait on hca %p destroy\n");\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+bail:\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+DAT_RETURN dapli_ib_thread_init(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_init(%d)\n", dapl_os_getpid());\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_INIT) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return DAT_SUCCESS;\r
+       }\r
+\r
+       /* uCMA events non-blocking */\r
+       if (dapls_config_cm_channel(g_cm_events)) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return (dapl_convert_errno(errno, "create_thread ERR: cm_fd"));\r
+       }\r
+\r
+       g_ib_thread_state = IB_THREAD_CREATE;\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* create thread to process inbound connect request */\r
+       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);\r
+       if (dat_status != DAT_SUCCESS)\r
+               return (dapl_convert_errno(errno,\r
+                                          "create_thread ERR:"\r
+                                          " check resource limits"));\r
+\r
+       /* wait for thread to start */\r
+       dapl_os_lock(&g_hca_lock);\r
+       while (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_init: waiting for ib_thread\n");\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(1000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_init(%d) exit\n", dapl_os_getpid());\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+void dapli_ib_thread_destroy(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d)\n", dapl_os_getpid());\r
+       /* \r
+        * wait for async thread to terminate. \r
+        * pthread_join would be the correct method\r
+        * but some applications have some issues\r
+        */\r
+\r
+       /* destroy ib_thread, wait for termination, if not already */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN)\r
+               goto bail;\r
+\r
+       g_ib_thread_state = IB_THREAD_CANCEL;\r
+       while ((g_ib_thread_state != IB_THREAD_EXIT)) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: waiting for ib_thread\n");\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(2000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+bail:\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());\r
+}\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct _ib_hca_transport *hca;\r
+       struct _ib_hca_transport *uhca[8];\r
+       COMP_CHANNEL *channel;\r
+       int ret, idx, cnt;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",\r
+                    dapl_os_getpid(), g_ib_thread);\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       for (g_ib_thread_state = IB_THREAD_RUN;\r
+            g_ib_thread_state == IB_THREAD_RUN; \r
+            dapl_os_lock(&g_hca_lock)) {\r
+\r
+               CompSetZero(&ufds);\r
+               CompSetAdd(&g_cm_events->channel, &ufds);\r
+\r
+               idx = 0;\r
+               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :\r
+                     dapl_llist_peek_head(&g_hca_list);\r
+\r
+               while (hca) {\r
+                       CompSetAdd(&hca->ib_ctx->channel, &ufds);\r
+                       CompSetAdd(&hca->ib_cq->comp_channel, &ufds);\r
+                       uhca[idx++] = hca;\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+               cnt = idx;\r
+\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = CompSetPoll(&ufds, INFINITE);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread(%d) poll_event 0x%x\n",\r
+                            dapl_os_getpid(), ret);\r
+\r
+               dapli_cma_event_cb();\r
+\r
+               /* check and process ASYNC events, per device */\r
+               for (idx = 0; idx < cnt; idx++) {\r
+                       if (uhca[idx]->destroy == 1) {\r
+                               dapl_os_lock(&g_hca_lock);\r
+                               dapl_llist_remove_entry(&g_hca_list,\r
+                                                       (DAPL_LLIST_ENTRY *)\r
+                                                       &uhca[idx]->entry);\r
+                               dapl_os_unlock(&g_hca_lock);\r
+                               uhca[idx]->destroy = 2;\r
+                       } else {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#else                          // _WIN64 || WIN32\r
+\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct pollfd ufds[__FD_SETSIZE];\r
+       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };\r
+       struct _ib_hca_transport *hca;\r
+       int ret, idx, fds;\r
+       char rbuf[2];\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                    " ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",\r
+                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0],\r
+                    g_cm_events->fd);\r
+\r
+       /* Poll across pipe, CM, AT never changes */\r
+       dapl_os_lock(&g_hca_lock);\r
+       g_ib_thread_state = IB_THREAD_RUN;\r
+\r
+       ufds[0].fd = g_ib_pipe[0];      /* pipe */\r
+       ufds[0].events = POLLIN;\r
+       ufds[1].fd = g_cm_events->fd;   /* uCMA */\r
+       ufds[1].events = POLLIN;\r
+\r
+       while (g_ib_thread_state == IB_THREAD_RUN) {\r
+\r
+               /* build ufds after pipe and uCMA events */\r
+               ufds[0].revents = 0;\r
+               ufds[1].revents = 0;\r
+               idx = 1;\r
+\r
+               /*  Walk HCA list and setup async and CQ events */\r
+               if (!dapl_llist_is_empty(&g_hca_list))\r
+                       hca = dapl_llist_peek_head(&g_hca_list);\r
+               else\r
+                       hca = NULL;\r
+\r
+               while (hca) {\r
+\r
+                       /* uASYNC events */\r
+                       ufds[++idx].fd = hca->ib_ctx->async_fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       /* CQ events are non-direct with CNO's */\r
+                       ufds[++idx].fd = hca->ib_cq->fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"\r
+                                    " async=%d pipe=%d cm=%d \n",\r
+                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,\r
+                                    ufds[0].fd, ufds[1].fd);\r
+\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+\r
+               /* unlock, and setup poll */\r
+               fds = idx + 1;\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = poll(ufds, fds, -1);\r
+               if (ret <= 0) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d): ERR %s poll\n",\r
+                                    dapl_os_getpid(), strerror(errno));\r
+                       dapl_os_lock(&g_hca_lock);\r
+                       continue;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                            " ib_thread(%d) poll_event: "\r
+                            " async=0x%x pipe=0x%x cm=0x%x \n",\r
+                            dapl_os_getpid(), ufds[idx].revents,\r
+                            ufds[0].revents, ufds[1].revents);\r
+\r
+               /* uCMA events */\r
+               if (ufds[1].revents == POLLIN)\r
+                       dapli_cma_event_cb();\r
+\r
+               /* check and process CQ and ASYNC events, per device */\r
+               for (idx = 2; idx < fds; idx++) {\r
+                       if (ufds[idx].revents == POLLIN) {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+\r
+               /* check and process user events, PIPE */\r
+               if (ufds[0].revents == POLLIN) {\r
+                       if (read(g_ib_pipe[0], rbuf, 2) == -1)\r
+                               dapl_log(DAPL_DBG_TYPE_THREAD,\r
+                                        " cr_thread: pipe rd err= %s\n",\r
+                                        strerror(errno));\r
+\r
+                       /* cleanup any device on list marked for destroy */\r
+                       for (idx = 3; idx < fds; idx++) {\r
+                               if (uhca[idx] && uhca[idx]->destroy == 1) {\r
+                                       dapl_os_lock(&g_hca_lock);\r
+                                       dapl_llist_remove_entry(\r
+                                               &g_hca_list,\r
+                                               (DAPL_LLIST_ENTRY*)\r
+                                               &uhca[idx]->entry);\r
+                                       dapl_os_unlock(&g_hca_lock);\r
+                                       uhca[idx]->destroy = 2;\r
+                               }\r
+                       }\r
+               }\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#endif\r
index 2a7ace8..8e45d82 100644 (file)
@@ -151,6 +151,20 @@ static int dapl_select(struct dapl_fd_set *set)
 \r
        return ret;\r
 }\r
+\r
+static int dapl_socket_errno(void)\r
+{\r
+       int err;\r
+\r
+       err = WSAGetLastError();\r
+       switch (err) {\r
+       case WSAEACCES:\r
+       case WSAEADDRINUSE:\r
+               return EADDRINUSE;\r
+       default:\r
+               return err;\r
+       }\r
+}\r
 #else                          // _WIN32 || _WIN64\r
 enum DAPL_FD_EVENTS {\r
        DAPL_FD_READ = POLLIN,\r
@@ -238,6 +252,8 @@ static int dapl_select(struct dapl_fd_set *set)
        dapl_dbg_log(DAPL_DBG_TYPE_CM, " dapl_select: wakeup, ret=0x%x\n", ret);\r
        return ret;\r
 }\r
+\r
+#define dapl_socket_errno() errno\r
 #endif\r
 \r
 dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep)\r
@@ -822,7 +838,7 @@ dapli_socket_listen(DAPL_IA * ia_ptr, DAT_CONN_QUAL serviceID, DAPL_SP * sp_ptr)
                dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
                             " listen: ERROR %s on conn_qual 0x%x\n",\r
                             strerror(errno), serviceID);\r
-               if (errno == EADDRINUSE)\r
+               if (dapl_socket_errno() == EADDRINUSE)\r
                        dat_status = DAT_CONN_QUAL_IN_USE;\r
                else\r
                        dat_status = DAT_CONN_QUAL_UNAVAILABLE;\r
@@ -1775,7 +1791,7 @@ void cr_thread(void *arg)
                                if (!ret)\r
                                        dapli_socket_connected(cr, opt);\r
                                else\r
-                                       dapli_socket_connected(cr, errno);\r
+                                       dapli_socket_connected(cr, dapl_socket_errno());\r
                         \r
                        /* POLLUP, ERR, NVAL, or poll error - DISC */\r
                        } else if (ret < 0 || ret == DAPL_FD_ERROR) {\r
@@ -1814,7 +1830,7 @@ void cr_thread(void *arg)
        }\r
 \r
        dapl_os_unlock(&hca_ptr->ib_trans.lock);\r
-       free(set);\r
+       dapl_os_free(set, sizeof(struct dapl_fd_set));\r
       out:\r
        hca_ptr->ib_trans.cr_state = IB_THREAD_EXIT;\r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cr_thread(hca %p) exit\n", hca_ptr);\r
index 1479f93..1b358e2 100644 (file)
-/*
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/***************************************************************************
- *
- *   Module:            uDAPL
- *
- *   Filename:          dapl_ib_util.c
- *
- *   Author:            Arlin Davis
- *
- *   Created:           3/10/2005
- *
- *   Description: 
- *
- *   The uDAPL openib provider - init, open, close, utilities
- *
- ****************************************************************************
- *                Source Control System Information
- *
- *    $Id: $
- *
- *     Copyright (c) 2005 Intel Corporation.  All rights reserved.
- *
- **************************************************************************/
-#ifdef RCSID
-static const char rcsid[] = "$Id:  $";
-#endif
-
-#include "openib_osd.h"
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_ib_util.h"
-#include "dapl_osd.h"
-
-#include <stdlib.h>
-
-ib_thread_state_t g_ib_thread_state = 0;
-DAPL_OS_THREAD g_ib_thread;
-DAPL_OS_LOCK g_hca_lock;
-struct dapl_llist_entry *g_hca_list;
-
-void dapli_thread(void *arg);
-DAT_RETURN  dapli_ib_thread_init(void);
-void dapli_ib_thread_destroy(void);
-
-#if defined(_WIN64) || defined(_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
-#include <rdma\winverbs.h>
-
-static COMP_SET ufds;
-
-static int dapls_os_init(void)
-{
-       return CompSetInit(&ufds);
-}
-
-static void dapls_os_release(void)
-{
-       CompSetCleanup(&ufds);
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       verbs->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       channel->comp_channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_thread_signal(void)
-{
-       CompSetCancel(&ufds);
-       return 0;
-}
-#else                          // _WIN64 || WIN32
-int g_ib_pipe[2];
-
-static int dapls_os_init(void)
-{
-       /* create pipe for waking up work thread */
-       return pipe(g_ib_pipe);
-}
-
-static void dapls_os_release(void)
-{
-       /* close pipe? */
-}
-
-static int dapls_config_fd(int fd)
-{
-       int opts;
-
-       opts = fcntl(fd, F_GETFL);
-       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",
-                        fd, opts, strerror(errno));
-               return errno;
-       }
-
-       return 0;
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       return dapls_config_fd(verbs->async_fd);
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-static int dapls_thread_signal(void)
-{
-       return write(g_ib_pipe[1], "w", sizeof "w");
-}
-#endif
-
-
-static int32_t create_cr_pipe(IN DAPL_HCA * hca_ptr)
-{
-       DAPL_SOCKET listen_socket;
-       struct sockaddr_in addr;
-       socklen_t addrlen = sizeof(addr);
-       int ret;
-
-       listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (listen_socket == DAPL_INVALID_SOCKET)
-               return 1;
-
-       memset(&addr, 0, sizeof addr);
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(0x7f000001);
-       ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof addr);
-       if (ret)
-               goto err1;
-
-       ret = getsockname(listen_socket, (struct sockaddr *)&addr, &addrlen);
-       if (ret)
-               goto err1;
-
-       ret = listen(listen_socket, 0);
-       if (ret)
-               goto err1;
-
-       hca_ptr->ib_trans.scm[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (hca_ptr->ib_trans.scm[1] == DAPL_INVALID_SOCKET)
-               goto err1;
-
-       ret = connect(hca_ptr->ib_trans.scm[1], 
-                     (struct sockaddr *)&addr, sizeof(addr));
-       if (ret)
-               goto err2;
-
-       hca_ptr->ib_trans.scm[0] = accept(listen_socket, NULL, NULL);
-       if (hca_ptr->ib_trans.scm[0] == DAPL_INVALID_SOCKET)
-               goto err2;
-
-       closesocket(listen_socket);
-       return 0;
-
-      err2:
-       closesocket(hca_ptr->ib_trans.scm[1]);
-      err1:
-       closesocket(listen_socket);
-       return 1;
-}
-
-static void destroy_cr_pipe(IN DAPL_HCA * hca_ptr)
-{
-       closesocket(hca_ptr->ib_trans.scm[0]);
-       closesocket(hca_ptr->ib_trans.scm[1]);
-}
-
-
-/*
- * dapls_ib_init, dapls_ib_release
- *
- * Initialize Verb related items for device open
- *
- * Input:
- *     none
- *
- * Output:
- *     none
- *
- * Returns:
- *     0 success, -1 error
- *
- */
-int32_t dapls_ib_init(void)
-{
-       /* initialize hca_list */
-       dapl_os_lock_init(&g_hca_lock);
-       dapl_llist_init_head(&g_hca_list);
-
-       if (dapls_os_init())
-               return 1;
-
-       return 0;
-}
-
-int32_t dapls_ib_release(void)
-{
-       dapli_ib_thread_destroy();
-       dapls_os_release();
-       return 0;
-}
-
-/*
- * dapls_ib_open_hca
- *
- * Open HCA
- *
- * Input:
- *      *hca_name         pointer to provider device name
- *      *ib_hca_handle_p  pointer to provide HCA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *      dapl_convert_errno
- *
- */
-DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
-{
-       struct ibv_device **dev_list;
-       struct ibv_port_attr port_attr;
-       int i;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: %s - %p\n", hca_name, hca_ptr);
-
-       /* get the IP address of the device */
-       dat_status = getlocalipaddr((DAT_SOCK_ADDR *) &hca_ptr->hca_address,
-                                   sizeof(DAT_SOCK_ADDR6));
-       if (dat_status != DAT_SUCCESS)
-               return dat_status;
-
-       /* Get list of all IB devices, find match, open */
-       dev_list = ibv_get_device_list(NULL);
-       if (!dev_list) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " open_hca: ibv_get_device_list() failed\n",
-                            hca_name);
-               return DAT_INTERNAL_ERROR;
-       }
-
-       for (i = 0; dev_list[i]; ++i) {
-               hca_ptr->ib_trans.ib_dev = dev_list[i];
-               if (!strcmp(ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                           hca_name))
-                       goto found;
-       }
-
-       dapl_log(DAPL_DBG_TYPE_ERR,
-                " open_hca: device %s not found\n", hca_name);
-       goto err;
-
-found:
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: Found dev %s %016llx\n",
-                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                    (unsigned long long)
-                    ntohll(ibv_get_device_guid(hca_ptr->ib_trans.ib_dev)));
-
-       hca_ptr->ib_hca_handle = ibv_open_device(hca_ptr->ib_trans.ib_dev);
-       if (!hca_ptr->ib_hca_handle) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: dev open failed for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       }
-       hca_ptr->ib_trans.ib_ctx = hca_ptr->ib_hca_handle;
-       dapls_config_verbs(hca_ptr->ib_hca_handle);
-
-       /* get lid for this hca-port, network order */
-       if (ibv_query_port(hca_ptr->ib_hca_handle,
-                          (uint8_t) hca_ptr->port_num, &port_attr)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: get lid ERR for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       } else {
-               hca_ptr->ib_trans.lid = htons(port_attr.lid);
-       }
-
-       /* get gid for this hca-port, network order */
-       if (ibv_query_gid(hca_ptr->ib_hca_handle,
-                         (uint8_t) hca_ptr->port_num,
-                         0, &hca_ptr->ib_trans.gid)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: query GID ERR for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       }
-
-       /* set RC tunables via enviroment or default */
-       hca_ptr->ib_trans.max_inline_send =
-           dapl_os_get_env_val("DAPL_MAX_INLINE", INLINE_SEND_DEFAULT);
-       hca_ptr->ib_trans.ack_retry =
-           dapl_os_get_env_val("DAPL_ACK_RETRY", SCM_ACK_RETRY);
-       hca_ptr->ib_trans.ack_timer =
-           dapl_os_get_env_val("DAPL_ACK_TIMER", SCM_ACK_TIMER);
-       hca_ptr->ib_trans.rnr_retry =
-           dapl_os_get_env_val("DAPL_RNR_RETRY", SCM_RNR_RETRY);
-       hca_ptr->ib_trans.rnr_timer =
-           dapl_os_get_env_val("DAPL_RNR_TIMER", SCM_RNR_TIMER);
-       hca_ptr->ib_trans.global =
-           dapl_os_get_env_val("DAPL_GLOBAL_ROUTING", SCM_GLOBAL);
-       hca_ptr->ib_trans.hop_limit =
-           dapl_os_get_env_val("DAPL_HOP_LIMIT", SCM_HOP_LIMIT);
-       hca_ptr->ib_trans.tclass =
-           dapl_os_get_env_val("DAPL_TCLASS", SCM_TCLASS);
-       hca_ptr->ib_trans.mtu =
-           dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", SCM_IB_MTU));
-
-
-       /* EVD events without direct CQ channels, CNO support */
-       hca_ptr->ib_trans.ib_cq =
-           ibv_create_comp_channel(hca_ptr->ib_hca_handle);
-       if (hca_ptr->ib_trans.ib_cq == NULL) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: ibv_create_comp_channel ERR %s\n",
-                        strerror(errno));
-               goto bail;
-       }
-       dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq);
-       
-       dat_status = dapli_ib_thread_init();
-       if (dat_status != DAT_SUCCESS) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to init cq thread lock\n");
-               goto bail;
-       }
-       /* 
-        * Put new hca_transport on list for async and CQ event processing 
-        * Wakeup work thread to add to polling list
-        */
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&hca_ptr->ib_trans.entry);
-       dapl_os_lock(&g_hca_lock);
-       dapl_llist_add_tail(&g_hca_list,
-                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,
-                           &hca_ptr->ib_trans.entry);
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " open_hca: thread wakeup error = %s\n",
-                        strerror(errno));
-       dapl_os_unlock(&g_hca_lock);
-
-       /* initialize cr_list lock */
-       dat_status = dapl_os_lock_init(&hca_ptr->ib_trans.lock);
-       if (dat_status != DAT_SUCCESS) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to init cr_list lock\n");
-               goto bail;
-       }
-
-       /* initialize CM list for listens on this HCA */
-       dapl_llist_init_head(&hca_ptr->ib_trans.list);
-
-       /* initialize pipe, user level wakeup on select */
-       if (create_cr_pipe(hca_ptr)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to init cr pipe - %s\n",
-                        strerror(errno));
-               goto bail;
-       }
-
-       /* create thread to process inbound connect request */
-       hca_ptr->ib_trans.cr_state = IB_THREAD_INIT;
-       dat_status = dapl_os_thread_create(cr_thread,
-                                          (void *)hca_ptr,
-                                          &hca_ptr->ib_trans.thread);
-       if (dat_status != DAT_SUCCESS) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to create thread\n");
-               goto bail;
-       }
-
-       /* wait for thread */
-       while (hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) {
-               dapl_os_sleep_usec(1000);
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: devname %s, port %d, hostname_IP %s\n",
-                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                    hca_ptr->port_num, inet_ntoa(((struct sockaddr_in *)
-                                                  &hca_ptr->hca_address)->
-                                                 sin_addr));
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: LID 0x%x GID Subnet 0x" F64x " ID 0x" F64x
-                    "\n", ntohs(hca_ptr->ib_trans.lid), (unsigned long long)
-                    htonll(hca_ptr->ib_trans.gid.global.subnet_prefix),
-                    (unsigned long long)htonll(hca_ptr->ib_trans.gid.global.
-                                               interface_id));
-
-       ibv_free_device_list(dev_list);
-       return dat_status;
-
-      bail:
-       ibv_close_device(hca_ptr->ib_hca_handle);
-       hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-      err:
-       ibv_free_device_list(dev_list);
-       return DAT_INTERNAL_ERROR;
-}
-
-/*
- * dapls_ib_close_hca
- *
- * Open HCA
- *
- * Input:
- *      DAPL_HCA   provide CA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *     dapl_convert_errno 
- *
- */
-DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr);
-
-       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {
-               if (ibv_close_device(hca_ptr->ib_hca_handle))
-                       return (dapl_convert_errno(errno, "ib_close_device"));
-               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-       }
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_os_unlock(&g_hca_lock);
-               return (DAT_SUCCESS);
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       /* destroy cr_thread and lock */
-       hca_ptr->ib_trans.cr_state = IB_THREAD_CANCEL;
-       send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);
-       while (hca_ptr->ib_trans.cr_state != IB_THREAD_EXIT) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " close_hca: waiting for cr_thread\n");
-               send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);
-               dapl_os_sleep_usec(1000);
-       }
-       dapl_os_lock_destroy(&hca_ptr->ib_trans.lock);
-       destroy_cr_pipe(hca_ptr); /* no longer need pipe */
-       
-       /* 
-        * Remove hca from async event processing list
-        * Wakeup work thread to remove from polling list
-        */
-       hca_ptr->ib_trans.destroy = 1;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-
-       /* wait for thread to remove HCA references */
-       while (hca_ptr->ib_trans.destroy != 2) {
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_os_sleep_usec(1000);
-       }
-
-       return (DAT_SUCCESS);
-}
-
-DAT_RETURN dapli_ib_thread_init(void)
-{
-       DAT_RETURN dat_status;
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_INIT) {
-               dapl_os_unlock(&g_hca_lock);
-               return DAT_SUCCESS;
-       }
-
-       g_ib_thread_state = IB_THREAD_CREATE;
-       dapl_os_unlock(&g_hca_lock);
-
-       /* create thread to process inbound connect request */
-       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);
-       if (dat_status != DAT_SUCCESS)
-               return (dapl_convert_errno(errno,
-                                          "create_thread ERR:"
-                                          " check resource limits"));
-
-       /* wait for thread to start */
-       dapl_os_lock(&g_hca_lock);
-       while (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_init: waiting for ib_thread\n");
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(1000);
-               dapl_os_lock(&g_hca_lock);
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       return DAT_SUCCESS;
-}
-
-void dapli_ib_thread_destroy(void)
-{
-       int retries = 10;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d)\n", dapl_os_getpid());
-       /* 
-        * wait for async thread to terminate. 
-        * pthread_join would be the correct method
-        * but some applications have some issues
-        */
-
-       /* destroy ib_thread, wait for termination, if not already */
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN)
-               goto bail;
-
-       g_ib_thread_state = IB_THREAD_CANCEL;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-       while ((g_ib_thread_state != IB_THREAD_EXIT) && (retries--)) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_destroy: waiting for ib_thread\n");
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(2000);
-               dapl_os_lock(&g_hca_lock);
-       }
-bail:
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());
-}
-
-
-#if defined(_WIN64) || defined(_WIN32)
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct _ib_hca_transport *hca;
-       struct _ib_hca_transport *uhca[8];
-       int ret, idx, cnt;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",
-                    dapl_os_getpid(), g_ib_thread);
-
-       dapl_os_lock(&g_hca_lock);
-       for (g_ib_thread_state = IB_THREAD_RUN;
-            g_ib_thread_state == IB_THREAD_RUN; 
-            dapl_os_lock(&g_hca_lock)) {
-
-               CompSetZero(&ufds);
-               idx = 0;
-               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :
-                     dapl_llist_peek_head(&g_hca_list);
-
-               while (hca) {
-                       CompSetAdd(&hca->ib_ctx->channel, &ufds);
-                       CompSetAdd(&hca->ib_cq->comp_channel, &ufds);
-                       uhca[idx++] = hca;
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *)
-                                                   &hca->entry);
-               }
-               cnt = idx;
-
-               dapl_os_unlock(&g_hca_lock);
-               ret = CompSetPoll(&ufds, INFINITE);
-
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread(%d) poll_event 0x%x\n",
-                            dapl_os_getpid(), ret);
-
-
-               /* check and process ASYNC events, per device */
-               for (idx = 0; idx < cnt; idx++) {
-                       if (uhca[idx]->destroy == 1) {
-                               dapl_os_lock(&g_hca_lock);
-                               dapl_llist_remove_entry(&g_hca_list,
-                                                       (DAPL_LLIST_ENTRY *)
-                                                       &uhca[idx]->entry);
-                               dapl_os_unlock(&g_hca_lock);
-                               uhca[idx]->destroy = 2;
-                       } else {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#else                          // _WIN64 || WIN32
-
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct pollfd ufds[__FD_SETSIZE];
-       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };
-       struct _ib_hca_transport *hca;
-       int ret, idx, fds;
-       char rbuf[2];
-
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                    " ib_thread(%d,0x%x): ENTER: pipe %d \n",
-                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0]);
-
-       /* Poll across pipe, CM, AT never changes */
-       dapl_os_lock(&g_hca_lock);
-       g_ib_thread_state = IB_THREAD_RUN;
-
-       ufds[0].fd = g_ib_pipe[0];      /* pipe */
-       ufds[0].events = POLLIN;
-
-       while (g_ib_thread_state == IB_THREAD_RUN) {
-
-               /* build ufds after pipe and uCMA events */
-               ufds[0].revents = 0;
-               idx = 0;
-
-               /*  Walk HCA list and setup async and CQ events */
-               if (!dapl_llist_is_empty(&g_hca_list))
-                       hca = dapl_llist_peek_head(&g_hca_list);
-               else
-                       hca = NULL;
-
-               while (hca) {
-
-                       /* uASYNC events */
-                       ufds[++idx].fd = hca->ib_ctx->async_fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       /* CQ events are non-direct with CNO's */
-                       ufds[++idx].fd = hca->ib_cq->fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"
-                                    " async=%d pipe=%d \n",
-                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,
-                                    ufds[0].fd);
-
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *)
-                                                   &hca->entry);
-               }
-
-               /* unlock, and setup poll */
-               fds = idx + 1;
-               dapl_os_unlock(&g_hca_lock);
-               ret = poll(ufds, fds, -1);
-               if (ret <= 0) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                                    " ib_thread(%d): ERR %s poll\n",
-                                    dapl_os_getpid(), strerror(errno));
-                       dapl_os_lock(&g_hca_lock);
-                       continue;
-               }
-
-               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
-                            " ib_thread(%d) poll_event: "
-                            " async=0x%x pipe=0x%x \n",
-                            dapl_os_getpid(), ufds[idx].revents,
-                            ufds[0].revents);
-
-               /* check and process CQ and ASYNC events, per device */
-               for (idx = 1; idx < fds; idx++) {
-                       if (ufds[idx].revents == POLLIN) {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-
-               /* check and process user events, PIPE */
-               if (ufds[0].revents == POLLIN) {
-                       if (read(g_ib_pipe[0], rbuf, 2) == -1)
-                               dapl_log(DAPL_DBG_TYPE_THREAD,
-                                        " cr_thread: pipe rd err= %s\n",
-                                        strerror(errno));
-
-                       /* cleanup any device on list marked for destroy */
-                       for (idx = 1; idx < fds; idx++) {
-                               if (uhca[idx] && uhca[idx]->destroy == 1) {
-                                       dapl_os_lock(&g_hca_lock);
-                                       dapl_llist_remove_entry(
-                                               &g_hca_list,
-                                               (DAPL_LLIST_ENTRY*)
-                                               &uhca[idx]->entry);
-                                       dapl_os_unlock(&g_hca_lock);
-                                       uhca[idx]->destroy = 2;
-                               }
-                       }
-               }
-               dapl_os_lock(&g_hca_lock);
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#endif
+/*\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/***************************************************************************\r
+ *\r
+ *   Module:            uDAPL\r
+ *\r
+ *   Filename:          dapl_ib_util.c\r
+ *\r
+ *   Author:            Arlin Davis\r
+ *\r
+ *   Created:           3/10/2005\r
+ *\r
+ *   Description: \r
+ *\r
+ *   The uDAPL openib provider - init, open, close, utilities\r
+ *\r
+ ****************************************************************************\r
+ *                Source Control System Information\r
+ *\r
+ *    $Id: $\r
+ *\r
+ *     Copyright (c) 2005 Intel Corporation.  All rights reserved.\r
+ *\r
+ **************************************************************************/\r
+#ifdef RCSID\r
+static const char rcsid[] = "$Id:  $";\r
+#endif\r
+\r
+#include "openib_osd.h"\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_ib_util.h"\r
+#include "dapl_osd.h"\r
+\r
+#include <stdlib.h>\r
+\r
+ib_thread_state_t g_ib_thread_state = 0;\r
+DAPL_OS_THREAD g_ib_thread;\r
+DAPL_OS_LOCK g_hca_lock;\r
+struct dapl_llist_entry *g_hca_list;\r
+\r
+void dapli_thread(void *arg);\r
+DAT_RETURN  dapli_ib_thread_init(void);\r
+void dapli_ib_thread_destroy(void);\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"\r
+#include <rdma\winverbs.h>\r
+\r
+static COMP_SET ufds;\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       return CompSetInit(&ufds);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       CompSetCleanup(&ufds);\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       verbs->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       channel->comp_channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       CompSetCancel(&ufds);\r
+       return 0;\r
+}\r
+#else                          // _WIN64 || WIN32\r
+int g_ib_pipe[2];\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       /* create pipe for waking up work thread */\r
+       return pipe(g_ib_pipe);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       /* close pipe? */\r
+}\r
+\r
+static int dapls_config_fd(int fd)\r
+{\r
+       int opts;\r
+\r
+       opts = fcntl(fd, F_GETFL);\r
+       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",\r
+                        fd, opts, strerror(errno));\r
+               return errno;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       return dapls_config_fd(verbs->async_fd);\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       return write(g_ib_pipe[1], "w", sizeof "w");\r
+}\r
+#endif\r
+\r
+\r
+static int32_t create_cr_pipe(IN DAPL_HCA * hca_ptr)\r
+{\r
+       DAPL_SOCKET listen_socket;\r
+       struct sockaddr_in addr;\r
+       socklen_t addrlen = sizeof(addr);\r
+       int ret;\r
+\r
+       listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+       if (listen_socket == DAPL_INVALID_SOCKET)\r
+               return 1;\r
+\r
+       memset(&addr, 0, sizeof addr);\r
+       addr.sin_family = AF_INET;\r
+       addr.sin_addr.s_addr = htonl(0x7f000001);\r
+       ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof addr);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       ret = getsockname(listen_socket, (struct sockaddr *)&addr, &addrlen);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       ret = listen(listen_socket, 0);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       hca_ptr->ib_trans.scm[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+       if (hca_ptr->ib_trans.scm[1] == DAPL_INVALID_SOCKET)\r
+               goto err1;\r
+\r
+       ret = connect(hca_ptr->ib_trans.scm[1], \r
+                     (struct sockaddr *)&addr, sizeof(addr));\r
+       if (ret)\r
+               goto err2;\r
+\r
+       hca_ptr->ib_trans.scm[0] = accept(listen_socket, NULL, NULL);\r
+       if (hca_ptr->ib_trans.scm[0] == DAPL_INVALID_SOCKET)\r
+               goto err2;\r
+\r
+       closesocket(listen_socket);\r
+       return 0;\r
+\r
+      err2:\r
+       closesocket(hca_ptr->ib_trans.scm[1]);\r
+      err1:\r
+       closesocket(listen_socket);\r
+       return 1;\r
+}\r
+\r
+static void destroy_cr_pipe(IN DAPL_HCA * hca_ptr)\r
+{\r
+       closesocket(hca_ptr->ib_trans.scm[0]);\r
+       closesocket(hca_ptr->ib_trans.scm[1]);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_init, dapls_ib_release\r
+ *\r
+ * Initialize Verb related items for device open\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     0 success, -1 error\r
+ *\r
+ */\r
+int32_t dapls_ib_init(void)\r
+{\r
+       /* initialize hca_list */\r
+       dapl_os_lock_init(&g_hca_lock);\r
+       dapl_llist_init_head(&g_hca_list);\r
+\r
+       if (dapls_os_init())\r
+               return 1;\r
+\r
+       return 0;\r
+}\r
+\r
+int32_t dapls_ib_release(void)\r
+{\r
+       dapli_ib_thread_destroy();\r
+       dapls_os_release();\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * dapls_ib_open_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      *hca_name         pointer to provider device name\r
+ *      *ib_hca_handle_p  pointer to provide HCA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *      dapl_convert_errno\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)\r
+{\r
+       struct ibv_device **dev_list;\r
+       struct ibv_port_attr port_attr;\r
+       int i;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: %s - %p\n", hca_name, hca_ptr);\r
+\r
+       /* get the IP address of the device */\r
+       dat_status = getlocalipaddr((DAT_SOCK_ADDR *) &hca_ptr->hca_address,\r
+                                   sizeof(DAT_SOCK_ADDR6));\r
+       if (dat_status != DAT_SUCCESS)\r
+               return dat_status;\r
+\r
+       /* Get list of all IB devices, find match, open */\r
+       dev_list = ibv_get_device_list(NULL);\r
+       if (!dev_list) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " open_hca: ibv_get_device_list() failed\n",\r
+                            hca_name);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
+       for (i = 0; dev_list[i]; ++i) {\r
+               hca_ptr->ib_trans.ib_dev = dev_list[i];\r
+               if (!strcmp(ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                           hca_name))\r
+                       goto found;\r
+       }\r
+\r
+       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                " open_hca: device %s not found\n", hca_name);\r
+       goto err;\r
+\r
+found:\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: Found dev %s %016llx\n",\r
+                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                    (unsigned long long)\r
+                    ntohll(ibv_get_device_guid(hca_ptr->ib_trans.ib_dev)));\r
+\r
+       hca_ptr->ib_hca_handle = ibv_open_device(hca_ptr->ib_trans.ib_dev);\r
+       if (!hca_ptr->ib_hca_handle) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: dev open failed for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       }\r
+       hca_ptr->ib_trans.ib_ctx = hca_ptr->ib_hca_handle;\r
+       dapls_config_verbs(hca_ptr->ib_hca_handle);\r
+\r
+       /* get lid for this hca-port, network order */\r
+       if (ibv_query_port(hca_ptr->ib_hca_handle,\r
+                          (uint8_t) hca_ptr->port_num, &port_attr)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: get lid ERR for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       } else {\r
+               hca_ptr->ib_trans.lid = htons(port_attr.lid);\r
+       }\r
+\r
+       /* get gid for this hca-port, network order */\r
+       if (ibv_query_gid(hca_ptr->ib_hca_handle,\r
+                         (uint8_t) hca_ptr->port_num,\r
+                         0, &hca_ptr->ib_trans.gid)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: query GID ERR for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       }\r
+\r
+       /* set RC tunables via enviroment or default */\r
+       hca_ptr->ib_trans.max_inline_send =\r
+           dapl_os_get_env_val("DAPL_MAX_INLINE", INLINE_SEND_DEFAULT);\r
+       hca_ptr->ib_trans.ack_retry =\r
+           dapl_os_get_env_val("DAPL_ACK_RETRY", SCM_ACK_RETRY);\r
+       hca_ptr->ib_trans.ack_timer =\r
+           dapl_os_get_env_val("DAPL_ACK_TIMER", SCM_ACK_TIMER);\r
+       hca_ptr->ib_trans.rnr_retry =\r
+           dapl_os_get_env_val("DAPL_RNR_RETRY", SCM_RNR_RETRY);\r
+       hca_ptr->ib_trans.rnr_timer =\r
+           dapl_os_get_env_val("DAPL_RNR_TIMER", SCM_RNR_TIMER);\r
+       hca_ptr->ib_trans.global =\r
+           dapl_os_get_env_val("DAPL_GLOBAL_ROUTING", SCM_GLOBAL);\r
+       hca_ptr->ib_trans.hop_limit =\r
+           dapl_os_get_env_val("DAPL_HOP_LIMIT", SCM_HOP_LIMIT);\r
+       hca_ptr->ib_trans.tclass =\r
+           dapl_os_get_env_val("DAPL_TCLASS", SCM_TCLASS);\r
+       hca_ptr->ib_trans.mtu =\r
+           dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", SCM_IB_MTU));\r
+\r
+\r
+       /* EVD events without direct CQ channels, CNO support */\r
+       hca_ptr->ib_trans.ib_cq =\r
+           ibv_create_comp_channel(hca_ptr->ib_hca_handle);\r
+       if (hca_ptr->ib_trans.ib_cq == NULL) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: ibv_create_comp_channel ERR %s\n",\r
+                        strerror(errno));\r
+               goto bail;\r
+       }\r
+       dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+       \r
+       dat_status = dapli_ib_thread_init();\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to init cq thread lock\n");\r
+               goto bail;\r
+       }\r
+       /* \r
+        * Put new hca_transport on list for async and CQ event processing \r
+        * Wakeup work thread to add to polling list\r
+        */\r
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&hca_ptr->ib_trans.entry);\r
+       dapl_os_lock(&g_hca_lock);\r
+       dapl_llist_add_tail(&g_hca_list,\r
+                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,\r
+                           &hca_ptr->ib_trans.entry);\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " open_hca: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* initialize cr_list lock */\r
+       dat_status = dapl_os_lock_init(&hca_ptr->ib_trans.lock);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to init cr_list lock\n");\r
+               goto bail;\r
+       }\r
+\r
+       /* initialize CM list for listens on this HCA */\r
+       dapl_llist_init_head(&hca_ptr->ib_trans.list);\r
+\r
+       /* initialize pipe, user level wakeup on select */\r
+       if (create_cr_pipe(hca_ptr)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to init cr pipe - %s\n",\r
+                        strerror(errno));\r
+               goto bail;\r
+       }\r
+\r
+       /* create thread to process inbound connect request */\r
+       hca_ptr->ib_trans.cr_state = IB_THREAD_INIT;\r
+       dat_status = dapl_os_thread_create(cr_thread,\r
+                                          (void *)hca_ptr,\r
+                                          &hca_ptr->ib_trans.thread);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to create thread\n");\r
+               goto bail;\r
+       }\r
+\r
+       /* wait for thread */\r
+       while (hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) {\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: devname %s, port %d, hostname_IP %s\n",\r
+                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                    hca_ptr->port_num, inet_ntoa(((struct sockaddr_in *)\r
+                                                  &hca_ptr->hca_address)->\r
+                                                 sin_addr));\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: LID 0x%x GID Subnet 0x" F64x " ID 0x" F64x\r
+                    "\n", ntohs(hca_ptr->ib_trans.lid), (unsigned long long)\r
+                    htonll(hca_ptr->ib_trans.gid.global.subnet_prefix),\r
+                    (unsigned long long)htonll(hca_ptr->ib_trans.gid.global.\r
+                                               interface_id));\r
+\r
+       ibv_free_device_list(dev_list);\r
+       return dat_status;\r
+\r
+      bail:\r
+       ibv_close_device(hca_ptr->ib_hca_handle);\r
+       hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+      err:\r
+       ibv_free_device_list(dev_list);\r
+       return DAT_INTERNAL_ERROR;\r
+}\r
+\r
+/*\r
+ * dapls_ib_close_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      DAPL_HCA   provide CA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *     dapl_convert_errno \r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr);\r
+\r
+       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
+               if (ibv_close_device(hca_ptr->ib_hca_handle))\r
+                       return (dapl_convert_errno(errno, "ib_close_device"));\r
+               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+       }\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return (DAT_SUCCESS);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* destroy cr_thread and lock */\r
+       hca_ptr->ib_trans.cr_state = IB_THREAD_CANCEL;\r
+       send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);\r
+       while (hca_ptr->ib_trans.cr_state != IB_THREAD_EXIT) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " close_hca: waiting for cr_thread\n");\r
+               send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+       dapl_os_lock_destroy(&hca_ptr->ib_trans.lock);\r
+       destroy_cr_pipe(hca_ptr); /* no longer need pipe */\r
+       \r
+       /* \r
+        * Remove hca from async event processing list\r
+        * Wakeup work thread to remove from polling list\r
+        */\r
+       hca_ptr->ib_trans.destroy = 1;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+\r
+       /* wait for thread to remove HCA references */\r
+       while (hca_ptr->ib_trans.destroy != 2) {\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+DAT_RETURN dapli_ib_thread_init(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_INIT) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return DAT_SUCCESS;\r
+       }\r
+\r
+       g_ib_thread_state = IB_THREAD_CREATE;\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* create thread to process inbound connect request */\r
+       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);\r
+       if (dat_status != DAT_SUCCESS)\r
+               return (dapl_convert_errno(errno,\r
+                                          "create_thread ERR:"\r
+                                          " check resource limits"));\r
+\r
+       /* wait for thread to start */\r
+       dapl_os_lock(&g_hca_lock);\r
+       while (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_init: waiting for ib_thread\n");\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(1000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+void dapli_ib_thread_destroy(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d)\n", dapl_os_getpid());\r
+       /* \r
+        * wait for async thread to terminate. \r
+        * pthread_join would be the correct method\r
+        * but some applications have some issues\r
+        */\r
+\r
+       /* destroy ib_thread, wait for termination, if not already */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN)\r
+               goto bail;\r
+\r
+       g_ib_thread_state = IB_THREAD_CANCEL;\r
+       while (g_ib_thread_state != IB_THREAD_EXIT) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: waiting for ib_thread\n");\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(2000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+bail:\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());\r
+}\r
+\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct _ib_hca_transport *hca;\r
+       struct _ib_hca_transport *uhca[8];\r
+       int ret, idx, cnt;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",\r
+                    dapl_os_getpid(), g_ib_thread);\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       for (g_ib_thread_state = IB_THREAD_RUN;\r
+            g_ib_thread_state == IB_THREAD_RUN; \r
+            dapl_os_lock(&g_hca_lock)) {\r
+\r
+               CompSetZero(&ufds);\r
+               idx = 0;\r
+               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :\r
+                     dapl_llist_peek_head(&g_hca_list);\r
+\r
+               while (hca) {\r
+                       CompSetAdd(&hca->ib_ctx->channel, &ufds);\r
+                       CompSetAdd(&hca->ib_cq->comp_channel, &ufds);\r
+                       uhca[idx++] = hca;\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+               cnt = idx;\r
+\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = CompSetPoll(&ufds, INFINITE);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread(%d) poll_event 0x%x\n",\r
+                            dapl_os_getpid(), ret);\r
+\r
+\r
+               /* check and process ASYNC events, per device */\r
+               for (idx = 0; idx < cnt; idx++) {\r
+                       if (uhca[idx]->destroy == 1) {\r
+                               dapl_os_lock(&g_hca_lock);\r
+                               dapl_llist_remove_entry(&g_hca_list,\r
+                                                       (DAPL_LLIST_ENTRY *)\r
+                                                       &uhca[idx]->entry);\r
+                               dapl_os_unlock(&g_hca_lock);\r
+                               uhca[idx]->destroy = 2;\r
+                       } else {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#else                          // _WIN64 || WIN32\r
+\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct pollfd ufds[__FD_SETSIZE];\r
+       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };\r
+       struct _ib_hca_transport *hca;\r
+       int ret, idx, fds;\r
+       char rbuf[2];\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                    " ib_thread(%d,0x%x): ENTER: pipe %d \n",\r
+                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0]);\r
+\r
+       /* Poll across pipe, CM, AT never changes */\r
+       dapl_os_lock(&g_hca_lock);\r
+       g_ib_thread_state = IB_THREAD_RUN;\r
+\r
+       ufds[0].fd = g_ib_pipe[0];      /* pipe */\r
+       ufds[0].events = POLLIN;\r
+\r
+       while (g_ib_thread_state == IB_THREAD_RUN) {\r
+\r
+               /* build ufds after pipe and uCMA events */\r
+               ufds[0].revents = 0;\r
+               idx = 0;\r
+\r
+               /*  Walk HCA list and setup async and CQ events */\r
+               if (!dapl_llist_is_empty(&g_hca_list))\r
+                       hca = dapl_llist_peek_head(&g_hca_list);\r
+               else\r
+                       hca = NULL;\r
+\r
+               while (hca) {\r
+\r
+                       /* uASYNC events */\r
+                       ufds[++idx].fd = hca->ib_ctx->async_fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       /* CQ events are non-direct with CNO's */\r
+                       ufds[++idx].fd = hca->ib_cq->fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"\r
+                                    " async=%d pipe=%d \n",\r
+                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,\r
+                                    ufds[0].fd);\r
+\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+\r
+               /* unlock, and setup poll */\r
+               fds = idx + 1;\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = poll(ufds, fds, -1);\r
+               if (ret <= 0) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d): ERR %s poll\n",\r
+                                    dapl_os_getpid(), strerror(errno));\r
+                       dapl_os_lock(&g_hca_lock);\r
+                       continue;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                            " ib_thread(%d) poll_event: "\r
+                            " async=0x%x pipe=0x%x \n",\r
+                            dapl_os_getpid(), ufds[idx].revents,\r
+                            ufds[0].revents);\r
+\r
+               /* check and process CQ and ASYNC events, per device */\r
+               for (idx = 1; idx < fds; idx++) {\r
+                       if (ufds[idx].revents == POLLIN) {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+\r
+               /* check and process user events, PIPE */\r
+               if (ufds[0].revents == POLLIN) {\r
+                       if (read(g_ib_pipe[0], rbuf, 2) == -1)\r
+                               dapl_log(DAPL_DBG_TYPE_THREAD,\r
+                                        " cr_thread: pipe rd err= %s\n",\r
+                                        strerror(errno));\r
+\r
+                       /* cleanup any device on list marked for destroy */\r
+                       for (idx = 1; idx < fds; idx++) {\r
+                               if (uhca[idx] && uhca[idx]->destroy == 1) {\r
+                                       dapl_os_lock(&g_hca_lock);\r
+                                       dapl_llist_remove_entry(\r
+                                               &g_hca_list,\r
+                                               (DAPL_LLIST_ENTRY*)\r
+                                               &uhca[idx]->entry);\r
+                                       dapl_os_unlock(&g_hca_lock);\r
+                                       uhca[idx]->destroy = 2;\r
+                               }\r
+                       }\r
+               }\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#endif\r
index e0af8f7..cb08837 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dapl_init.c
- *
- * PURPOSE: Interface Adapter management
- * Description: Interfaces in this file are completely described in
- *             the DAPL 1.1 API, Chapter 6, section 2
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include <dat2/dat_registry.h> /* Provider API function prototypes */
-#include "dapl_hca_util.h"
-#include "dapl_init.h"
-#include "dapl_provider.h"
-#include "dapl_mr_util.h"
-#include "dapl_osd.h"
-#include "dapl_adapter_util.h"
-#include "dapl_name_service.h"
-#include "dapl_timer_util.h"
-#include "dapl_vendor.h"
-
-/*
- * dapl_init
- *
- * initialize this provider
- * includes initialization of all global variables
- * as well as registering all supported IAs with the dat registry
- *
- * This function needs to be called once when the provider is loaded.
- *
- * Input:
- *     none
- *
- * Output:
- *     none
- *
- * Return Values:
- */
-void dapl_init(void)
-{
-       DAT_RETURN dat_status;
-
-       /* set up debug type */
-       g_dapl_dbg_type = dapl_os_get_env_val("DAPL_DBG_TYPE",
-                                             DAPL_DBG_TYPE_ERR);
-       /* set up debug destination */
-       g_dapl_dbg_dest = dapl_os_get_env_val("DAPL_DBG_DEST",
-                                             DAPL_DBG_DEST_STDOUT);
-
-       /* open log file on first logging call if necessary */
-       if (g_dapl_dbg_dest & DAPL_DBG_DEST_SYSLOG)
-               openlog("libdapl", LOG_ODELAY | LOG_PID | LOG_CONS, LOG_USER);
-
-       dapl_log(DAPL_DBG_TYPE_UTIL, "dapl_init: dbg_type=0x%x,dbg_dest=0x%x\n",
-                g_dapl_dbg_type, g_dapl_dbg_dest);
-
-       /* See if the user is on a loopback setup */
-       g_dapl_loopback_connection = dapl_os_get_env_bool("DAPL_LOOPBACK");
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: %s Setting Loopback\n",
-                    g_dapl_loopback_connection ? "" : "NOT");
-
-       /* initialize verbs library */
-       dapls_ib_init();
-
-       /* initialize the timer */
-       dapls_timer_init();
-
-       /* Set up name services */
-       dat_status = dapls_ns_init();
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dapls_ns_init failed %d\n", dat_status);
-               goto bail;
-       }
-
-       /* initialize the provider list */
-       dat_status = dapl_provider_list_create();
-
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dapl_provider_list_create failed %d\n",
-                            dat_status);
-               goto bail;
-       }
-
-       return;
-
-      bail:
-       dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ERROR: dapl_init failed\n");
-       return;
-}
-
-/*
- * dapl_fini
- *
- * finalize this provider
- * includes freeing of all global variables
- * as well as deregistering all supported IAs from the dat registry
- *
- * This function needs to be called once when the provider is loaded.
- *
- * Input:
- *     none
- *
- * Output:
- *     none
- *
- * Return Values:
- */
-void dapl_fini(void)
-{
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: ENTER (dapl_fini)\n");
-
-       dat_status = dapl_provider_list_destroy();
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dapl_provider_list_destroy failed %d\n",
-                            dat_status);
-       }
-
-       dapls_ib_release();
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: Exit (dapl_fini)\n");
-
-       if (g_dapl_dbg_dest & DAPL_DBG_DEST_SYSLOG)
-               closelog();
-
-       return;
-}
-
-/*
- *
- * This function is called by the registry to initialize a provider
- *
- * The instance data string is expected to have the following form:
- *
- * <hca name> <port number>
- *
- */
-void DAT_API
-DAT_PROVIDER_INIT_FUNC_NAME(IN const DAT_PROVIDER_INFO * provider_info,
-                           IN const char *instance_data)
-{
-       DAT_PROVIDER *provider;
-       DAPL_HCA *hca_ptr;
-       DAT_RETURN dat_status;
-       char *data;
-       char *name;
-       char *port;
-       unsigned int len;
-       unsigned int i;
-
-       data = NULL;
-       provider = NULL;
-       hca_ptr = NULL;
-
-#if defined(_WIN32) || defined(_WIN64)
-       /* initialize DAPL library here as when called from DLL context in DLLmain()
-        * the IB (ibal) call hangs.
-        */
-       dapl_init();
-#endif
-
-       dat_status =
-           dapl_provider_list_insert(provider_info->ia_name, &provider);
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dat_provider_list_insert failed: %x\n",
-                            dat_status);
-               goto bail;
-       }
-
-       data = dapl_os_strdup(instance_data);
-       if (NULL == data) {
-               goto bail;
-       }
-
-       len = dapl_os_strlen(data);
-
-       for (i = 0; i < len; i++) {
-               if (' ' == data[i]) {
-                       data[i] = '\0';
-                       break;
-               }
-       }
-
-       /* if the instance data did not have a valid format */
-       if (i == len) {
-               goto bail;
-       }
-
-       name = data;
-       port = data + (i + 1);
-
-       hca_ptr = dapl_hca_alloc(name, port);
-       if (NULL == hca_ptr) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "%s() dapl_hca_alloc failed?\n");
-               goto bail;
-       }
-
-       provider->extension = hca_ptr;
-       dat_status = dat_registry_add_provider(provider, provider_info);
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dat_registry_add_provider failed: %x\n",
-                            dat_status);
-       }
-
-      bail:
-       if (NULL != data) {
-               dapl_os_free(data, len + 1);
-       }
-
-       if (DAT_SUCCESS != dat_status) {
-               if (NULL != provider) {
-                       (void)dapl_provider_list_remove(provider_info->ia_name);
-               }
-
-               if (NULL != hca_ptr) {
-                       dapl_hca_free(hca_ptr);
-               }
-       }
-}
-
-/*
- *
- * This function is called by the registry to de-initialize a provider
- *
- */
-void DAT_API
-DAT_PROVIDER_FINI_FUNC_NAME(IN const DAT_PROVIDER_INFO * provider_info)
-{
-       DAT_PROVIDER *provider;
-       DAT_RETURN dat_status;
-
-       dat_status =
-           dapl_provider_list_search(provider_info->ia_name, &provider);
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dat_registry_add_provider failed: %x\n",
-                            dat_status);
-               return;
-       }
-
-       dat_status = dat_registry_remove_provider(provider, provider_info);
-       if (DAT_SUCCESS != dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "dat_registry_add_provider failed: %x\n",
-                            dat_status);
-       }
-
-       /*
-        * free HCA memory
-        */
-       dapl_hca_free(provider->extension);
-
-       (void)dapl_provider_list_remove(provider_info->ia_name);
-
-#if defined(_WIN32) || defined(_WIN64)
-       /* cleanup DAPL library - relocated here from OSD DLL context as the IBAL
-        * calls hung in the DLL context?
-        */
-       dapl_fini();
-#endif
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_init.c\r
+ *\r
+ * PURPOSE: Interface Adapter management\r
+ * Description: Interfaces in this file are completely described in\r
+ *             the DAPL 1.1 API, Chapter 6, section 2\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include <dat2/dat_registry.h> /* Provider API function prototypes */\r
+#include "dapl_hca_util.h"\r
+#include "dapl_init.h"\r
+#include "dapl_provider.h"\r
+#include "dapl_mr_util.h"\r
+#include "dapl_osd.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_name_service.h"\r
+#include "dapl_timer_util.h"\r
+#include "dapl_vendor.h"\r
+\r
+/*\r
+ * dapl_init\r
+ *\r
+ * initialize this provider\r
+ * includes initialization of all global variables\r
+ * as well as registering all supported IAs with the dat registry\r
+ *\r
+ * This function needs to be called once when the provider is loaded.\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Return Values:\r
+ */\r
+void dapl_init(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       /* set up debug type */\r
+       g_dapl_dbg_type = dapl_os_get_env_val("DAPL_DBG_TYPE",\r
+                                             DAPL_DBG_TYPE_ERR);\r
+       /* set up debug destination */\r
+       g_dapl_dbg_dest = dapl_os_get_env_val("DAPL_DBG_DEST",\r
+                                             DAPL_DBG_DEST_STDOUT);\r
+\r
+       /* open log file on first logging call if necessary */\r
+       if (g_dapl_dbg_dest & DAPL_DBG_DEST_SYSLOG)\r
+               openlog("libdapl", LOG_ODELAY | LOG_PID | LOG_CONS, LOG_USER);\r
+\r
+       dapl_log(DAPL_DBG_TYPE_UTIL, "dapl_init: dbg_type=0x%x,dbg_dest=0x%x\n",\r
+                g_dapl_dbg_type, g_dapl_dbg_dest);\r
+\r
+       /* See if the user is on a loopback setup */\r
+       g_dapl_loopback_connection = dapl_os_get_env_bool("DAPL_LOOPBACK");\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: %s Setting Loopback\n",\r
+                    g_dapl_loopback_connection ? "" : "NOT");\r
+\r
+       /* initialize verbs library */\r
+       dapls_ib_init();\r
+\r
+       /* initialize the timer */\r
+       dapls_timer_init();\r
+\r
+       /* Set up name services */\r
+       dat_status = dapls_ns_init();\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dapls_ns_init failed %d\n", dat_status);\r
+               goto bail;\r
+       }\r
+\r
+       /* initialize the provider list */\r
+       dat_status = dapl_provider_list_create();\r
+\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dapl_provider_list_create failed %d\n",\r
+                            dat_status);\r
+               goto bail;\r
+       }\r
+\r
+       return;\r
+\r
+      bail:\r
+       dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ERROR: dapl_init failed\n");\r
+       return;\r
+}\r
+\r
+/*\r
+ * dapl_fini\r
+ *\r
+ * finalize this provider\r
+ * includes freeing of all global variables\r
+ * as well as deregistering all supported IAs from the dat registry\r
+ *\r
+ * This function needs to be called once when the provider is loaded.\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Return Values:\r
+ */\r
+void dapl_fini(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: ENTER (dapl_fini)\n");\r
+\r
+       dat_status = dapl_provider_list_destroy();\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dapl_provider_list_destroy failed %d\n",\r
+                            dat_status);\r
+       }\r
+\r
+       dapls_ib_release();\r
+       dapls_timer_release();\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: Exit (dapl_fini)\n");\r
+\r
+       if (g_dapl_dbg_dest & DAPL_DBG_DEST_SYSLOG)\r
+               closelog();\r
+\r
+       return;\r
+}\r
+\r
+/*\r
+ *\r
+ * This function is called by the registry to initialize a provider\r
+ *\r
+ * The instance data string is expected to have the following form:\r
+ *\r
+ * <hca name> <port number>\r
+ *\r
+ */\r
+void DAT_API\r
+DAT_PROVIDER_INIT_FUNC_NAME(IN const DAT_PROVIDER_INFO * provider_info,\r
+                           IN const char *instance_data)\r
+{\r
+       DAT_PROVIDER *provider;\r
+       DAPL_HCA *hca_ptr;\r
+       DAT_RETURN dat_status;\r
+       char *data;\r
+       char *name;\r
+       char *port;\r
+       unsigned int len;\r
+       unsigned int i;\r
+\r
+       data = NULL;\r
+       provider = NULL;\r
+       hca_ptr = NULL;\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       /* initialize DAPL library here as when called from DLL context in DLLmain()\r
+        * the IB (ibal) call hangs.\r
+        */\r
+       dapl_init();\r
+#endif\r
+\r
+       dat_status =\r
+           dapl_provider_list_insert(provider_info->ia_name, &provider);\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dat_provider_list_insert failed: %x\n",\r
+                            dat_status);\r
+               goto bail;\r
+       }\r
+\r
+       data = dapl_os_strdup(instance_data);\r
+       if (NULL == data) {\r
+               goto bail;\r
+       }\r
+\r
+       len = dapl_os_strlen(data);\r
+\r
+       for (i = 0; i < len; i++) {\r
+               if (' ' == data[i]) {\r
+                       data[i] = '\0';\r
+                       break;\r
+               }\r
+       }\r
+\r
+       /* if the instance data did not have a valid format */\r
+       if (i == len) {\r
+               goto bail;\r
+       }\r
+\r
+       name = data;\r
+       port = data + (i + 1);\r
+\r
+       hca_ptr = dapl_hca_alloc(name, port);\r
+       if (NULL == hca_ptr) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "%s() dapl_hca_alloc failed?\n");\r
+               goto bail;\r
+       }\r
+\r
+       provider->extension = hca_ptr;\r
+       dat_status = dat_registry_add_provider(provider, provider_info);\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dat_registry_add_provider failed: %x\n",\r
+                            dat_status);\r
+       }\r
+\r
+      bail:\r
+       if (NULL != data) {\r
+               dapl_os_free(data, len + 1);\r
+       }\r
+\r
+       if (DAT_SUCCESS != dat_status) {\r
+               if (NULL != provider) {\r
+                       (void)dapl_provider_list_remove(provider_info->ia_name);\r
+               }\r
+\r
+               if (NULL != hca_ptr) {\r
+                       dapl_hca_free(hca_ptr);\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ *\r
+ * This function is called by the registry to de-initialize a provider\r
+ *\r
+ */\r
+void DAT_API\r
+DAT_PROVIDER_FINI_FUNC_NAME(IN const DAT_PROVIDER_INFO * provider_info)\r
+{\r
+       DAT_PROVIDER *provider;\r
+       DAT_RETURN dat_status;\r
+\r
+       dat_status =\r
+           dapl_provider_list_search(provider_info->ia_name, &provider);\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dat_registry_add_provider failed: %x\n",\r
+                            dat_status);\r
+               return;\r
+       }\r
+\r
+       dat_status = dat_registry_remove_provider(provider, provider_info);\r
+       if (DAT_SUCCESS != dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            "dat_registry_add_provider failed: %x\n",\r
+                            dat_status);\r
+       }\r
+\r
+       /*\r
+        * free HCA memory\r
+        */\r
+       dapl_hca_free(provider->extension);\r
+\r
+       (void)dapl_provider_list_remove(provider_info->ia_name);\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       /* cleanup DAPL library - relocated here from OSD DLL context as the IBAL\r
+        * calls hung in the DLL context?\r
+        */\r
+       dapl_fini();\r
+#endif\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 8097560..9b616d8 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under either one of the following two licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- * OR
- *
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * Licensee has the right to choose either one of the above two licenses.
- *
- * Redistributions of source code must retain both the above copyright
- * notice and either one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, either one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dapl_osd.c
- *
- * PURPOSE: Operating System Dependent layer
- * Description: 
- *     Provide OS dependent functions with a canonical DAPL
- *     interface. Designed to be portable and hide OS specific quirks
- *     of common functions.
- *             
- *
- * $Id: dapl_osd.c 33 2005-07-11 19:51:17Z ftillier $
- **********************************************************************/
-
-/*
- * MUST have the Microsoft Platform SDK installed for Windows to build
- * and work properly
- */
-#include "dapl.h"
-#include "dapl_init.h"
-#include "dapl_osd.h"
-#include <sys/timeb.h>
-#include <stdlib.h>                    /* needed for getenv() */
-
-
-
-/*
- * DllMain
- *
- * Primary Windows entry point
- *
- * Input:
- *      hDllHandle     handle to DLL module
- *      fdwReason      reason for calling function
- *      lpReserved     reserved
- *
- * Returns:
- *     DAT_SUCCESS
- */
-
-BOOL WINAPI
-DllMain (
-        IN  HINSTANCE          hDllHandle,
-        IN  DWORD              fdwReason,
-        IN  LPVOID             lpReserved )
-{
-    UNREFERENCED_PARAMETER(lpReserved);
-
-    switch( fdwReason ) 
-    { 
-        case DLL_PROCESS_ATTACH:
-           /*
-            * We don't attach/detach threads that need any sort
-            * of initialization, so disable this ability to optimize
-            * the working set size of the DLL. Also allows us to
-            * remove two case statemens:
-            * DLL_THREAD_DETACH and DLL_THREAD_ATTACH
-            */
-           if ( (DisableThreadLibraryCalls( hDllHandle )) != 0)
-            {
-#if 0
-            /*
-             * Relocated to [dapl_init.c] ..._PROVIDER_INIT() as when called
-             * from here calls to dapl_init/dapls_ib_init/ib_open_al() hang
-             * in the DLL call context.
-             */
-                dapl_init ();
-#endif
-            }
-            else
-            {
-                DWORD err = GetLastError();
-                dapl_os_printf("DAPL Init Failed with code %u\n", err);
-            }
-            break;
-
-        case DLL_PROCESS_DETACH:
-            /* 
-            * Do library cleanup
-            */
-#if 0
-            /*
-             * Relocated to [dapl_init.c] ..._PROVIDER_FINI() as the call to
-             * dapl_fini/dapls_ib_release/ib_close_al() hangs in this DLL call
-             * context.
-             */
-            dapl_fini ();
-#endif
-            break;
-    }
-    return TRUE;  
-}
-
-
-#ifdef NOT_USED
-/*
- * dapl_osd_init
- *
- * Do Windows specific initialization:
- *     - nothing at this time
- *
- * Input:
- *      none
- *
- * Returns:
- *     none
- */
-void
-dapl_osd_init ( )
-{
-    return;
-}
-#endif
-
-/*
- * dapl_os_get_time
- *
- * Return 64 bit value of current time in microseconds.
- *
- * Input:
- *      loc       User location to place current time
- *
- * Returns:
- *     DAT_SUCCESS
- */
-
-DAT_RETURN
-dapl_os_get_time (
-    OUT DAPL_OS_TIMEVAL * loc)
-{
-    struct _timeb      tb;
-    
-    _ftime ( &tb );
-
-    *loc = ((DAT_UINT64) (tb.time * 1000000L) + (DAT_UINT64) tb.millitm * 1000);
-    
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapl_os_get_bool_env
- *
- * Return boolean value of passed in environment variable: 1 if present,
- * 0 if not
- *
- * Input:
- *      
- *
- * Returns:
- *     TRUE or FALSE
- */
-int
-dapl_os_get_env_bool (
-       char            *env_str )
-{
-    char               *env_var;
-
-    env_var = getenv (env_str);
-    if (env_var != NULL)
-    {
-       return 1;
-    }
-    return 0;
-}
-
-
-/*
- * dapl_os_get_val_env
- *
- * Update val to  value of passed in environment variable if present
- *
- * Input:
- *      env_str
- *     def_val         default value if environment variable does not exist
- *
- * Returns:
- *     TRUE or FALSE
- */
-int
-dapl_os_get_env_val (
-       char            *env_str,
-       int             def_val )
-{
-    char               *env_var;
-
-    env_var = getenv (env_str);
-    if ( env_var != NULL )
-    {
-       def_val = strtol (env_var, NULL, 0);
-    }
-
-    return  def_val;
-}
-
-
-/*
- * dapls_os_thread_create
- *
- * Create a thread for dapl
- *
- * Input:
- *     func            function to invoke thread
- *     data            argument to pass to function
- *
- * Output
- *     thread_id       handle for thread
- *
- * Returns:
- *     DAT_SUCCESS
- */
-DAT_RETURN 
-dapl_os_thread_create (
-       IN  void                        (*func) (void *),
-       IN  void                        *data,
-       OUT DAPL_OS_THREAD              *thread_id )
-{
-
-    *thread_id = CreateThread(
-                           NULL,        /* &thread security attrs    */
-                           8 * 1024,    /* initial thread stack size */
-                           (LPTHREAD_START_ROUTINE)func, /* &thread function */
-                           data,        /* argument for new thread   */
-                           0,           /* creation flags            */
-                           NULL);       /* thread ID (ignore)        */
-
-    if ( *thread_id == NULL )
-    {
-       return DAT_ERROR (DAT_INSUFFICIENT_RESOURCES, 0);
-    }
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under either one of the following two licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    in the file LICENSE.txt in the root directory. The license is also\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ * OR\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is in the file\r
+ *    LICENSE2.txt in the root directory. The license is also available from\r
+ *    the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * Licensee has the right to choose either one of the above two licenses.\r
+ *\r
+ * Redistributions of source code must retain both the above copyright\r
+ * notice and either one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, either one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_osd.c\r
+ *\r
+ * PURPOSE: Operating System Dependent layer\r
+ * Description: \r
+ *     Provide OS dependent functions with a canonical DAPL\r
+ *     interface. Designed to be portable and hide OS specific quirks\r
+ *     of common functions.\r
+ *             \r
+ *\r
+ * $Id: dapl_osd.c 33 2005-07-11 19:51:17Z ftillier $\r
+ **********************************************************************/\r
+\r
+/*\r
+ * MUST have the Microsoft Platform SDK installed for Windows to build\r
+ * and work properly\r
+ */\r
+#include "dapl.h"\r
+#include "dapl_init.h"\r
+#include "dapl_osd.h"\r
+#include <sys/timeb.h>\r
+#include <stdlib.h>                    /* needed for getenv() */\r
+\r
+HANDLE heap;\r
+\r
+/*\r
+ * DllMain\r
+ *\r
+ * Primary Windows entry point\r
+ *\r
+ * Input:\r
+ *      hDllHandle     handle to DLL module\r
+ *      fdwReason      reason for calling function\r
+ *      lpReserved     reserved\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ */\r
+\r
+BOOL WINAPI\r
+DllMain (\r
+        IN  HINSTANCE          hDllHandle,\r
+        IN  DWORD              fdwReason,\r
+        IN  LPVOID             lpReserved )\r
+{\r
+    UNREFERENCED_PARAMETER(lpReserved);\r
+\r
+    switch( fdwReason ) \r
+    { \r
+        case DLL_PROCESS_ATTACH:\r
+               heap = HeapCreate(0, 0, 0);\r
+               if (heap == NULL) {\r
+                       return FALSE;\r
+               }\r
+           /*\r
+            * We don't attach/detach threads that need any sort\r
+            * of initialization, so disable this ability to optimize\r
+            * the working set size of the DLL. Also allows us to\r
+            * remove two case statemens:\r
+            * DLL_THREAD_DETACH and DLL_THREAD_ATTACH\r
+            */\r
+           if ( (DisableThreadLibraryCalls( hDllHandle )) != 0)\r
+            {\r
+#if 0\r
+            /*\r
+             * Relocated to [dapl_init.c] ..._PROVIDER_INIT() as when called\r
+             * from here calls to dapl_init/dapls_ib_init/ib_open_al() hang\r
+             * in the DLL call context.\r
+             */\r
+                dapl_init ();\r
+#endif\r
+            }\r
+            else\r
+            {\r
+                DWORD err = GetLastError();\r
+                dapl_os_printf("DAPL Init Failed with code %u\n", err);\r
+            }\r
+            break;\r
+\r
+        case DLL_PROCESS_DETACH:\r
+            /* \r
+            * Do library cleanup\r
+            */\r
+#if 0\r
+            /*\r
+             * Relocated to [dapl_init.c] ..._PROVIDER_FINI() as the call to\r
+             * dapl_fini/dapls_ib_release/ib_close_al() hangs in this DLL call\r
+             * context.\r
+             */\r
+            dapl_fini ();\r
+#endif\r
+                       HeapDestroy(heap);\r
+            break;\r
+    }\r
+    return TRUE;  \r
+}\r
+\r
+\r
+#ifdef NOT_USED\r
+/*\r
+ * dapl_osd_init\r
+ *\r
+ * Do Windows specific initialization:\r
+ *     - nothing at this time\r
+ *\r
+ * Input:\r
+ *      none\r
+ *\r
+ * Returns:\r
+ *     none\r
+ */\r
+void\r
+dapl_osd_init ( )\r
+{\r
+    return;\r
+}\r
+#endif\r
+\r
+/*\r
+ * dapl_os_get_time\r
+ *\r
+ * Return 64 bit value of current time in microseconds.\r
+ *\r
+ * Input:\r
+ *      loc       User location to place current time\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ */\r
+\r
+DAT_RETURN\r
+dapl_os_get_time (\r
+    OUT DAPL_OS_TIMEVAL * loc)\r
+{\r
+    struct _timeb      tb;\r
+    \r
+    _ftime ( &tb );\r
+\r
+    *loc = ((DAT_UINT64) (tb.time * 1000000L) + (DAT_UINT64) tb.millitm * 1000);\r
+    \r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * dapl_os_get_bool_env\r
+ *\r
+ * Return boolean value of passed in environment variable: 1 if present,\r
+ * 0 if not\r
+ *\r
+ * Input:\r
+ *      \r
+ *\r
+ * Returns:\r
+ *     TRUE or FALSE\r
+ */\r
+int\r
+dapl_os_get_env_bool (\r
+       char            *env_str )\r
+{\r
+    char               *env_var;\r
+\r
+    env_var = getenv (env_str);\r
+    if (env_var != NULL)\r
+    {\r
+       return 1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * dapl_os_get_val_env\r
+ *\r
+ * Update val to  value of passed in environment variable if present\r
+ *\r
+ * Input:\r
+ *      env_str\r
+ *     def_val         default value if environment variable does not exist\r
+ *\r
+ * Returns:\r
+ *     TRUE or FALSE\r
+ */\r
+int\r
+dapl_os_get_env_val (\r
+       char            *env_str,\r
+       int             def_val )\r
+{\r
+    char               *env_var;\r
+\r
+    env_var = getenv (env_str);\r
+    if ( env_var != NULL )\r
+    {\r
+       def_val = strtol (env_var, NULL, 0);\r
+    }\r
+\r
+    return  def_val;\r
+}\r
+\r
+\r
+/*\r
+ * dapls_os_thread_create\r
+ *\r
+ * Create a thread for dapl\r
+ *\r
+ * Input:\r
+ *     func            function to invoke thread\r
+ *     data            argument to pass to function\r
+ *\r
+ * Output\r
+ *     thread_id       handle for thread\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ */\r
+DAT_RETURN \r
+dapl_os_thread_create (\r
+       IN  void                        (*func) (void *),\r
+       IN  void                        *data,\r
+       OUT DAPL_OS_THREAD              *thread_id )\r
+{\r
+\r
+    *thread_id = CreateThread(\r
+                           NULL,        /* &thread security attrs    */\r
+                           8 * 1024,    /* initial thread stack size */\r
+                           (LPTHREAD_START_ROUTINE)func, /* &thread function */\r
+                           data,        /* argument for new thread   */\r
+                           0,           /* creation flags            */\r
+                           NULL);       /* thread ID (ignore)        */\r
+\r
+    if ( *thread_id == NULL )\r
+    {\r
+       return DAT_ERROR (DAT_INSUFFICIENT_RESOURCES, 0);\r
+    }\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 6266f1f..541e4c2 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under either one of the following two licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- * OR
- *
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * Licensee has the right to choose either one of the above two licenses.
- *
- * Redistributions of source code must retain both the above copyright
- * notice and either one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, either one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * HEADER: dapl_osd.h
- *
- * PURPOSE: Operating System Dependent layer
- * Description:
- *     Provide OS dependent data structures & functions with
- *     a canonical DAPL interface. Designed to be portable
- *     and hide OS specific quirks of common functions.
- *
- * $Id: dapl_osd.h 33 2005-07-11 19:51:17Z ftillier $
- **********************************************************************/
-
-#ifndef _DAPL_OSD_H_
-#define _DAPL_OSD_H_
-
-/*
- * This file is defined for Windows systems only, including it on any
- * other build will cause an error
- */
-#if !defined(_WIN32) && !defined(_WIN64)
-#error UNDEFINED OS TYPE
-#endif /* WIN32 */
-
-#include <stddef.h>
-#include <complib/cl_types.h>
-#pragma warning ( push, 3 )
-#include <winioctl.h>
-#include <stdio.h>
-#include <string.h>
-#include <winsock2.h>
-#include <Ws2tcpip.h>
-#include <process.h>
-#include <stdlib.h>
-#pragma warning ( pop )
-
-#include "dapl_debug.h"
-
-/* Export Header */
-#ifdef EXPORT_DAPL_SYMBOLS     /* 1 when building DAPL DLL, 0 for clients */
-#define DAPL_EXPORT __declspec( dllexport )
-#else
-#define DAPL_EXPORT __declspec( dllimport )
-#endif
-
-/* Useful debug definitions */
-#ifndef STATIC
-#define STATIC static
-#endif /* STATIC */
-
-#ifndef _INLINE_
-#define _INLINE_ __inline
-#endif /* _INLINE_ */
-
-#define dapl_os_panic(str)                     \
-       {                                       \
-            fprintf(stderr, "PANIC in %s:%i:%s\n", __FILE__, __LINE__); \
-            fprintf(stderr, str);      \
-             exit(1);                          \
-       }
-
-#define openlog(...)
-#define closelog(...)
-
-/*
- * Atomic operations
- */
-
-typedef volatile DAT_COUNT DAPL_ATOMIC;
-
-/* atomic function prototypes */
-STATIC __inline DAT_COUNT
-dapl_os_atomic_inc (
-       INOUT   DAPL_ATOMIC *v);
-
-STATIC __inline DAT_COUNT
-dapl_os_atomic_dec ( 
-       INOUT   DAPL_ATOMIC *v);
-
-STATIC __inline DAT_COUNT
-dapl_os_atomic_assign (
-    INOUT DAPL_ATOMIC *v,
-    IN DAT_COUNT match_value,
-    IN DAT_COUNT new_value );
-
-#define dapl_os_atomic_read(v) (*v)
-#define dapl_os_atomic_set(v,i)        (*v = i)
-
-int dapl_os_get_env_bool (
-       char            *env_str );
-
-int dapl_os_get_env_val (
-       char            *env_str,
-       int             def_val );
-
-
-/* atomic functions */
-
-/* dapl_os_atomic_inc
- *
- * get the current value of '*v', and then increment it.
- *
- * This is equivalent to an IB atomic fetch and add of 1,
- * except that a DAT_COUNT might be 32 bits, rather than 64
- * and it occurs in local memory.
- */
-
-STATIC __inline DAT_COUNT
-dapl_os_atomic_inc (
-       INOUT   DAPL_ATOMIC *v)
-{
-       return InterlockedIncrement( v );
-}
-
-
-/* dapl_os_atomic_dec
- *
- * decrement the current value of '*v'. No return value is required.
- */
-
-STATIC __inline DAT_COUNT
-dapl_os_atomic_dec ( 
-       INOUT   DAPL_ATOMIC *v)
-{
-       return InterlockedDecrement( v );
-}
-
-
-/* dapl_os_atomic_assign
- *
- * assign 'new_value' to '*v' if the current value
- * matches the provided 'match_value'.
- *
- * Make no assignment if there is no match.
- *
- * Return the current value in any case.
- *
- * This matches the IBTA atomic operation compare & swap
- * except that it is for local memory and a DAT_COUNT may
- * be only 32 bits, rather than 64.
- */
-
-STATIC __inline DAT_COUNT
-dapl_os_atomic_assign (
-    INOUT DAPL_ATOMIC *v,
-    IN DAT_COUNT match_value,
-    IN DAT_COUNT new_value )
-{
-       return InterlockedCompareExchange((LPLONG)v, 
-                                                         new_value,
-                                                         match_value);
-}
-
-
-/*
- * Thread Functions
- */
-typedef HANDLE  DAPL_OS_THREAD;
-
-DAT_RETURN 
-dapl_os_thread_create (
-       IN  void                        (*func) (void *),
-       IN  void                        *data,
-       OUT DAPL_OS_THREAD              *thread_id );
-
-
-/*
- * Lock Functions
- */
-typedef HANDLE  DAPL_OS_LOCK;
-
-/* function prototypes */
-/* lock functions */
-STATIC __inline DAT_RETURN 
-dapl_os_lock_init (
-    IN DAPL_OS_LOCK *m)
-{
-    *m = CreateMutex (0, FALSE, 0);
-
-    return *m ? DAT_SUCCESS : (DAT_CLASS_ERROR | DAT_INSUFFICIENT_RESOURCES);
-}
-
-STATIC __inline DAT_RETURN 
-dapl_os_lock (
-    IN DAPL_OS_LOCK *m)
-{
-    WaitForSingleObject (*m, INFINITE);
-
-    return DAT_SUCCESS;
-}
-
-STATIC __inline DAT_RETURN 
-dapl_os_unlock (
-    IN DAPL_OS_LOCK *m)
-{
-    ReleaseMutex (*m);
-
-    return DAT_SUCCESS;
-}
-
-STATIC __inline DAT_RETURN 
-dapl_os_lock_destroy (
-    IN DAPL_OS_LOCK *m)
-{
-    CloseHandle (*m);
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * Wait Objects
- */
-
-/*
- * The wait object invariant: Presuming a call to dapl_os_wait_object_wait
- * occurs at some point, there will be at least one wakeup after each call
- * to dapl_os_wait_object_signal.  I.e. Signals are not ignored, though
- * they may be coallesced.
- */
-
-/* wait_object functions */
-
-typedef HANDLE DAPL_OS_WAIT_OBJECT;
-
-/* Initialize a wait object to an empty state
- */
-
-STATIC __inline DAT_RETURN 
-dapl_os_wait_object_init (
-    IN DAPL_OS_WAIT_OBJECT *wait_obj)
-{
-    *wait_obj = CreateEvent(NULL,FALSE,FALSE,NULL);
-
-    if ( *wait_obj == NULL )
-    {
-       return DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;
-    }
-
-    return DAT_SUCCESS;
-}
-
-
-/* Wait on the supplied wait object, up to the specified time_out,
- * and reacquiring it after the wait ends.
- * A timeout of DAT_TIMEOUT_INFINITE will wait indefinitely.
- * Timeout should be specified in micro seconds.
- *
- * Functional returns:
- *     DAT_SUCCESS -- another thread invoked dapl_os_wait object_wakeup
- *     DAT_INVALID_STATE -- someone else is already waiting in this wait
- *     object.
- *                          only one waiter is allowed at a time.
- *     DAT_ABORT -- another thread invoked dapl_os_wait_object_destroy
- *     DAT_TIMEOUT -- the specified time limit was reached.
- */
-
-STATIC __inline DAT_RETURN 
-dapl_os_wait_object_wait (
-    IN DAPL_OS_WAIT_OBJECT *wait_obj, 
-    IN  DAT_TIMEOUT timeout_val)
-{
-    DAT_RETURN                 status;
-    DWORD              op_status;
-
-    status = DAT_SUCCESS;
-
-    if ( DAT_TIMEOUT_INFINITE == timeout_val )
-    {
-       op_status = WaitForSingleObject(*wait_obj, INFINITE);
-    }
-    else
-    {
-       /* convert to milliseconds */
-       op_status = WaitForSingleObject(*wait_obj, timeout_val/1000);
-    }
-
-    if (op_status == WAIT_TIMEOUT)
-    {
-       status = DAT_CLASS_ERROR | DAT_TIMEOUT_EXPIRED;
-    }
-    else if ( op_status  == WAIT_FAILED)
-    {
-       status = DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;
-    }
-
-    return status;
-}
-
-STATIC __inline DAT_RETURN 
-dapl_os_wait_object_wakeup (
-    IN DAPL_OS_WAIT_OBJECT *wait_obj)
-{
-    DWORD              op_status;
-
-    op_status = SetEvent(*wait_obj);
-    if ( op_status == 0 )
-    {
-       return DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;
-    }
-
-    return DAT_SUCCESS;
-}
-
-STATIC __inline DAT_RETURN 
-dapl_os_wait_object_destroy (
-    IN DAPL_OS_WAIT_OBJECT *wait_obj)
-{
-    DWORD              op_status;
-    DAT_RETURN         status = DAT_SUCCESS;
-
-    op_status = CloseHandle(*wait_obj);
-
-    if ( op_status == 0 )
-    {
-       status = DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;
-    }
-
-    return status;
-}
-
-
-/*
- * Memory Functions
- */
-
-/* function prototypes */
-STATIC __inline void *dapl_os_alloc (int size);
-
-STATIC __inline void *dapl_os_realloc (void *ptr, int size);
-
-STATIC __inline void dapl_os_free (void *ptr, int size);
-
-STATIC __inline void * dapl_os_memzero (void *loc, int size);
-
-STATIC __inline void * dapl_os_memcpy (void *dest, const void *src, int len);
-
-STATIC __inline int dapl_os_memcmp (const void *mem1, const void *mem2, int len);
-
-/*
- * Memory coherency functions
- * For i386/x86_64 Windows, there are no coherency issues - just return success.
- */
-STATIC __inline  DAT_RETURN
-dapl_os_sync_rdma_read (
-    IN      const DAT_LMR_TRIPLET      *local_segments,
-    IN      DAT_VLEN                   num_segments)
-{
-    return DAT_SUCCESS;
-}
-
-STATIC __inline  DAT_RETURN
-dapl_os_sync_rdma_write (
-    IN      const DAT_LMR_TRIPLET      *local_segments,
-    IN      DAT_VLEN                   num_segments)
-{
-    return DAT_SUCCESS;
-}
-
-
-/* memory functions */
-
-
-STATIC __inline void *dapl_os_alloc (int size)
-{
-    return malloc (size);
-}
-
-STATIC __inline void *dapl_os_realloc (void *ptr, int size)
-{
-    return realloc(ptr, size);
-}
-
-STATIC __inline void dapl_os_free (void *ptr, int size)
-{
-    size = size;
-    free (ptr);
-    ptr = NULL;
-}
-
-STATIC __inline void * dapl_os_memzero (void *loc, int size)
-{
-    return memset (loc, 0, size);
-}
-
-STATIC __inline void * dapl_os_memcpy (void *dest, const void *src, int len)
-{
-    return memcpy (dest, src, len);
-}
-
-STATIC __inline int dapl_os_memcmp (const void *mem1, const void *mem2, int len)
-{
-    return memcmp (mem1, mem2, len);
-}
-
-
-STATIC __inline unsigned int dapl_os_strlen(const char *str)
-{
-    return ((unsigned int)strlen(str));
-}
-
-STATIC __inline char * dapl_os_strdup(const char *str)
-{
-    return _strdup(str);
-}
-
-
-/*
- * Timer Functions
- */
-
-typedef DAT_UINT64             DAPL_OS_TIMEVAL;
-typedef struct dapl_timer_entry                DAPL_OS_TIMER;
-typedef unsigned long          DAPL_OS_TICKS;
-
-/* function prototypes */
-
-/*
- * Sleep for the number of micro seconds specified by the invoking
- * function
- */
-STATIC __inline void dapl_os_sleep_usec (int sleep_time)
-{
-    Sleep(sleep_time/1000); // convert to milliseconds
-}
-
-STATIC __inline DAPL_OS_TICKS dapl_os_get_ticks (void);
-
-STATIC __inline int dapl_os_ticks_to_seconds (DAPL_OS_TICKS ticks);
-
-DAT_RETURN dapl_os_get_time (DAPL_OS_TIMEVAL *);
-/* timer functions */
-
-STATIC __inline DAPL_OS_TICKS dapl_os_get_ticks (void)
-{
-    return GetTickCount ();
-}
-
-STATIC __inline int dapl_os_ticks_to_seconds (DAPL_OS_TICKS ticks)
-{
-    ticks = ticks;
-    /* NOT YET IMPLEMENTED IN USER-SPACE */
-    return 0;
-}
-
-
-/*
- *
- * Name Service Helper functions
- *
- */
-#ifdef IBHOSTS_NAMING
-#define dapls_osd_getaddrinfo(name, addr_ptr) getaddrinfo(name,NULL,NULL,addr_ptr)
-#define dapls_osd_freeaddrinfo(addr) freeaddrinfo (addr)
-
-#endif /* IBHOSTS_NAMING */
-
-/*
- * *printf format helpers. We use the C string constant concatenation
- * ability to define 64 bit formats, which unfortunatly are non standard
- * in the C compiler world. E.g. %llx for gcc, %I64x for Windows
- */
-#define F64d   "%I64d"
-#define F64u   "%I64u"
-#define F64x   "%I64x"
-#define F64X   "%I64X"
-
-/*
- *  Conversion Functions
- */
-
-STATIC __inline long int
-dapl_os_strtol(const char *nptr, char **endptr, int base)
-{
-    return strtol(nptr, endptr, base);
-}
-
-#define dapl_os_getpid (DAT_UINT32)GetCurrentProcessId
-#define dapl_os_gettid (DAT_UINT32)GetCurrentThreadId
-
-/*
- *  Debug Helper Functions
- */
-
-#define dapl_os_assert(expression)     CL_ASSERT(expression)
-
-#define dapl_os_printf                         printf
-#define dapl_os_vprintf(fmt,args)      vprintf(fmt,args)
-#define dapl_os_syslog(fmt,args)       /* XXX Need log routine call */
-
-#endif /*  _DAPL_OSD_H_ */
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under either one of the following two licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    in the file LICENSE.txt in the root directory. The license is also\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ * OR\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is in the file\r
+ *    LICENSE2.txt in the root directory. The license is also available from\r
+ *    the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * Licensee has the right to choose either one of the above two licenses.\r
+ *\r
+ * Redistributions of source code must retain both the above copyright\r
+ * notice and either one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, either one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * HEADER: dapl_osd.h\r
+ *\r
+ * PURPOSE: Operating System Dependent layer\r
+ * Description:\r
+ *     Provide OS dependent data structures & functions with\r
+ *     a canonical DAPL interface. Designed to be portable\r
+ *     and hide OS specific quirks of common functions.\r
+ *\r
+ * $Id: dapl_osd.h 33 2005-07-11 19:51:17Z ftillier $\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_OSD_H_\r
+#define _DAPL_OSD_H_\r
+\r
+/*\r
+ * This file is defined for Windows systems only, including it on any\r
+ * other build will cause an error\r
+ */\r
+#if !defined(_WIN32) && !defined(_WIN64)\r
+#error UNDEFINED OS TYPE\r
+#endif /* WIN32 */\r
+\r
+#include <stddef.h>\r
+#include <complib/cl_types.h>\r
+#pragma warning ( push, 3 )\r
+#include <winioctl.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <winsock2.h>\r
+#include <Ws2tcpip.h>\r
+#include <process.h>\r
+#include <stdlib.h>\r
+#pragma warning ( pop )\r
+\r
+#include "dapl_debug.h"\r
+\r
+/* Export Header */\r
+#ifdef EXPORT_DAPL_SYMBOLS     /* 1 when building DAPL DLL, 0 for clients */\r
+#define DAPL_EXPORT __declspec( dllexport )\r
+#else\r
+#define DAPL_EXPORT __declspec( dllimport )\r
+#endif\r
+\r
+/* Useful debug definitions */\r
+#ifndef STATIC\r
+#define STATIC static\r
+#endif /* STATIC */\r
+\r
+#ifndef _INLINE_\r
+#define _INLINE_ __inline\r
+#endif /* _INLINE_ */\r
+\r
+#define dapl_os_panic(str)                     \\r
+       {                                       \\r
+            fprintf(stderr, "PANIC in %s:%i:%s\n", __FILE__, __LINE__); \\r
+            fprintf(stderr, str);      \\r
+             exit(1);                          \\r
+       }\r
+\r
+#define openlog(...)\r
+#define closelog(...)\r
+\r
+/*\r
+ * Atomic operations\r
+ */\r
+\r
+typedef volatile DAT_COUNT DAPL_ATOMIC;\r
+\r
+/* atomic function prototypes */\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_inc (\r
+       INOUT   DAPL_ATOMIC *v);\r
+\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_dec ( \r
+       INOUT   DAPL_ATOMIC *v);\r
+\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_assign (\r
+    INOUT DAPL_ATOMIC *v,\r
+    IN DAT_COUNT match_value,\r
+    IN DAT_COUNT new_value );\r
+\r
+#define dapl_os_atomic_read(v) (*v)\r
+#define dapl_os_atomic_set(v,i)        (*v = i)\r
+\r
+int dapl_os_get_env_bool (\r
+       char            *env_str );\r
+\r
+int dapl_os_get_env_val (\r
+       char            *env_str,\r
+       int             def_val );\r
+\r
+\r
+/* atomic functions */\r
+\r
+/* dapl_os_atomic_inc\r
+ *\r
+ * get the current value of '*v', and then increment it.\r
+ *\r
+ * This is equivalent to an IB atomic fetch and add of 1,\r
+ * except that a DAT_COUNT might be 32 bits, rather than 64\r
+ * and it occurs in local memory.\r
+ */\r
+\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_inc (\r
+       INOUT   DAPL_ATOMIC *v)\r
+{\r
+       return InterlockedIncrement( v );\r
+}\r
+\r
+\r
+/* dapl_os_atomic_dec\r
+ *\r
+ * decrement the current value of '*v'. No return value is required.\r
+ */\r
+\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_dec ( \r
+       INOUT   DAPL_ATOMIC *v)\r
+{\r
+       return InterlockedDecrement( v );\r
+}\r
+\r
+\r
+/* dapl_os_atomic_assign\r
+ *\r
+ * assign 'new_value' to '*v' if the current value\r
+ * matches the provided 'match_value'.\r
+ *\r
+ * Make no assignment if there is no match.\r
+ *\r
+ * Return the current value in any case.\r
+ *\r
+ * This matches the IBTA atomic operation compare & swap\r
+ * except that it is for local memory and a DAT_COUNT may\r
+ * be only 32 bits, rather than 64.\r
+ */\r
+\r
+STATIC __inline DAT_COUNT\r
+dapl_os_atomic_assign (\r
+    INOUT DAPL_ATOMIC *v,\r
+    IN DAT_COUNT match_value,\r
+    IN DAT_COUNT new_value )\r
+{\r
+       return InterlockedCompareExchange((LPLONG)v, \r
+                                                         new_value,\r
+                                                         match_value);\r
+}\r
+\r
+\r
+/*\r
+ * Thread Functions\r
+ */\r
+typedef HANDLE  DAPL_OS_THREAD;\r
+\r
+DAT_RETURN \r
+dapl_os_thread_create (\r
+       IN  void                        (*func) (void *),\r
+       IN  void                        *data,\r
+       OUT DAPL_OS_THREAD              *thread_id );\r
+\r
+\r
+/*\r
+ * Lock Functions\r
+ */\r
+typedef HANDLE  DAPL_OS_LOCK;\r
+\r
+/* function prototypes */\r
+/* lock functions */\r
+STATIC __inline DAT_RETURN \r
+dapl_os_lock_init (\r
+    IN DAPL_OS_LOCK *m)\r
+{\r
+    *m = CreateMutex (0, FALSE, 0);\r
+\r
+    return *m ? DAT_SUCCESS : (DAT_CLASS_ERROR | DAT_INSUFFICIENT_RESOURCES);\r
+}\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_lock (\r
+    IN DAPL_OS_LOCK *m)\r
+{\r
+    WaitForSingleObject (*m, INFINITE);\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_unlock (\r
+    IN DAPL_OS_LOCK *m)\r
+{\r
+    ReleaseMutex (*m);\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_lock_destroy (\r
+    IN DAPL_OS_LOCK *m)\r
+{\r
+    CloseHandle (*m);\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * Wait Objects\r
+ */\r
+\r
+/*\r
+ * The wait object invariant: Presuming a call to dapl_os_wait_object_wait\r
+ * occurs at some point, there will be at least one wakeup after each call\r
+ * to dapl_os_wait_object_signal.  I.e. Signals are not ignored, though\r
+ * they may be coallesced.\r
+ */\r
+\r
+/* wait_object functions */\r
+\r
+typedef HANDLE DAPL_OS_WAIT_OBJECT;\r
+\r
+/* Initialize a wait object to an empty state\r
+ */\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_wait_object_init (\r
+    IN DAPL_OS_WAIT_OBJECT *wait_obj)\r
+{\r
+    *wait_obj = CreateEvent(NULL,FALSE,FALSE,NULL);\r
+\r
+    if ( *wait_obj == NULL )\r
+    {\r
+       return DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;\r
+    }\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/* Wait on the supplied wait object, up to the specified time_out,\r
+ * and reacquiring it after the wait ends.\r
+ * A timeout of DAT_TIMEOUT_INFINITE will wait indefinitely.\r
+ * Timeout should be specified in micro seconds.\r
+ *\r
+ * Functional returns:\r
+ *     DAT_SUCCESS -- another thread invoked dapl_os_wait object_wakeup\r
+ *     DAT_INVALID_STATE -- someone else is already waiting in this wait\r
+ *     object.\r
+ *                          only one waiter is allowed at a time.\r
+ *     DAT_ABORT -- another thread invoked dapl_os_wait_object_destroy\r
+ *     DAT_TIMEOUT -- the specified time limit was reached.\r
+ */\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_wait_object_wait (\r
+    IN DAPL_OS_WAIT_OBJECT *wait_obj, \r
+    IN  DAT_TIMEOUT timeout_val)\r
+{\r
+    DAT_RETURN                 status;\r
+    DWORD              op_status;\r
+\r
+    status = DAT_SUCCESS;\r
+\r
+    if ( DAT_TIMEOUT_INFINITE == timeout_val )\r
+    {\r
+       op_status = WaitForSingleObject(*wait_obj, INFINITE);\r
+    }\r
+    else\r
+    {\r
+       /* convert to milliseconds */\r
+       op_status = WaitForSingleObject(*wait_obj, timeout_val/1000);\r
+    }\r
+\r
+    if (op_status == WAIT_TIMEOUT)\r
+    {\r
+       status = DAT_CLASS_ERROR | DAT_TIMEOUT_EXPIRED;\r
+    }\r
+    else if ( op_status  == WAIT_FAILED)\r
+    {\r
+       status = DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_wait_object_wakeup (\r
+    IN DAPL_OS_WAIT_OBJECT *wait_obj)\r
+{\r
+    DWORD              op_status;\r
+\r
+    op_status = SetEvent(*wait_obj);\r
+    if ( op_status == 0 )\r
+    {\r
+       return DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;\r
+    }\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+STATIC __inline DAT_RETURN \r
+dapl_os_wait_object_destroy (\r
+    IN DAPL_OS_WAIT_OBJECT *wait_obj)\r
+{\r
+    DWORD              op_status;\r
+    DAT_RETURN         status = DAT_SUCCESS;\r
+\r
+    op_status = CloseHandle(*wait_obj);\r
+\r
+    if ( op_status == 0 )\r
+    {\r
+       status = DAT_CLASS_ERROR | DAT_INTERNAL_ERROR;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+\r
+/*\r
+ * Memory Functions\r
+ */\r
+\r
+extern HANDLE heap;\r
+\r
+/* function prototypes */\r
+STATIC __inline void *dapl_os_alloc (int size);\r
+\r
+STATIC __inline void *dapl_os_realloc (void *ptr, int size);\r
+\r
+STATIC __inline void dapl_os_free (void *ptr, int size);\r
+\r
+STATIC __inline void * dapl_os_memzero (void *loc, int size);\r
+\r
+STATIC __inline void * dapl_os_memcpy (void *dest, const void *src, int len);\r
+\r
+STATIC __inline int dapl_os_memcmp (const void *mem1, const void *mem2, int len);\r
+\r
+/*\r
+ * Memory coherency functions\r
+ * For i386/x86_64 Windows, there are no coherency issues - just return success.\r
+ */\r
+STATIC __inline  DAT_RETURN\r
+dapl_os_sync_rdma_read (\r
+    IN      const DAT_LMR_TRIPLET      *local_segments,\r
+    IN      DAT_VLEN                   num_segments)\r
+{\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+STATIC __inline  DAT_RETURN\r
+dapl_os_sync_rdma_write (\r
+    IN      const DAT_LMR_TRIPLET      *local_segments,\r
+    IN      DAT_VLEN                   num_segments)\r
+{\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/* memory functions */\r
+\r
+\r
+STATIC __inline void *dapl_os_alloc (int size)\r
+{\r
+       return HeapAlloc(heap, 0, size);\r
+}\r
+\r
+STATIC __inline void *dapl_os_realloc (void *ptr, int size)\r
+{\r
+    return HeapReAlloc(heap, 0, ptr, size);\r
+}\r
+\r
+STATIC __inline void dapl_os_free (void *ptr, int size)\r
+{\r
+       UNREFERENCED_PARAMETER(size);\r
+       HeapFree(heap, 0, ptr);\r
+}\r
+\r
+STATIC __inline void * dapl_os_memzero (void *loc, int size)\r
+{\r
+    return memset (loc, 0, size);\r
+}\r
+\r
+STATIC __inline void * dapl_os_memcpy (void *dest, const void *src, int len)\r
+{\r
+    return memcpy (dest, src, len);\r
+}\r
+\r
+STATIC __inline int dapl_os_memcmp (const void *mem1, const void *mem2, int len)\r
+{\r
+    return memcmp (mem1, mem2, len);\r
+}\r
+\r
+\r
+STATIC __inline unsigned int dapl_os_strlen(const char *str)\r
+{\r
+    return ((unsigned int)strlen(str));\r
+}\r
+\r
+STATIC __inline char * dapl_os_strdup(const char *str)\r
+{\r
+       char *dup;\r
+\r
+       dup = dapl_os_alloc(strlen(str) + 1);\r
+       if (!dup)\r
+               return NULL;\r
+       strcpy(dup, str);\r
+    return dup;\r
+}\r
+\r
+\r
+/*\r
+ * Timer Functions\r
+ */\r
+\r
+typedef DAT_UINT64             DAPL_OS_TIMEVAL;\r
+typedef struct dapl_timer_entry                DAPL_OS_TIMER;\r
+typedef unsigned long          DAPL_OS_TICKS;\r
+\r
+/* function prototypes */\r
+\r
+/*\r
+ * Sleep for the number of micro seconds specified by the invoking\r
+ * function\r
+ */\r
+STATIC __inline void dapl_os_sleep_usec (int sleep_time)\r
+{\r
+    Sleep(sleep_time/1000); // convert to milliseconds\r
+}\r
+\r
+STATIC __inline DAPL_OS_TICKS dapl_os_get_ticks (void);\r
+\r
+STATIC __inline int dapl_os_ticks_to_seconds (DAPL_OS_TICKS ticks);\r
+\r
+DAT_RETURN dapl_os_get_time (DAPL_OS_TIMEVAL *);\r
+/* timer functions */\r
+\r
+STATIC __inline DAPL_OS_TICKS dapl_os_get_ticks (void)\r
+{\r
+    return GetTickCount ();\r
+}\r
+\r
+STATIC __inline int dapl_os_ticks_to_seconds (DAPL_OS_TICKS ticks)\r
+{\r
+    ticks = ticks;\r
+    /* NOT YET IMPLEMENTED IN USER-SPACE */\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ *\r
+ * Name Service Helper functions\r
+ *\r
+ */\r
+#ifdef IBHOSTS_NAMING\r
+#define dapls_osd_getaddrinfo(name, addr_ptr) getaddrinfo(name,NULL,NULL,addr_ptr)\r
+#define dapls_osd_freeaddrinfo(addr) freeaddrinfo (addr)\r
+\r
+#endif /* IBHOSTS_NAMING */\r
+\r
+/*\r
+ * *printf format helpers. We use the C string constant concatenation\r
+ * ability to define 64 bit formats, which unfortunatly are non standard\r
+ * in the C compiler world. E.g. %llx for gcc, %I64x for Windows\r
+ */\r
+#define F64d   "%I64d"\r
+#define F64u   "%I64u"\r
+#define F64x   "%I64x"\r
+#define F64X   "%I64X"\r
+\r
+/*\r
+ *  Conversion Functions\r
+ */\r
+\r
+STATIC __inline long int\r
+dapl_os_strtol(const char *nptr, char **endptr, int base)\r
+{\r
+    return strtol(nptr, endptr, base);\r
+}\r
+\r
+#define dapl_os_getpid (DAT_UINT32)GetCurrentProcessId\r
+#define dapl_os_gettid (DAT_UINT32)GetCurrentThreadId\r
+\r
+/*\r
+ *  Debug Helper Functions\r
+ */\r
+\r
+#define dapl_os_assert(expression)     CL_ASSERT(expression)\r
+\r
+#define dapl_os_printf                         printf\r
+#define dapl_os_vprintf(fmt,args)      vprintf(fmt,args)\r
+#define dapl_os_syslog(fmt,args)       /* XXX Need log routine call */\r
+\r
+#endif /*  _DAPL_OSD_H_ */\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 5b57f43..2dac8df 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under either one of the following two licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- * OR
- *
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * Licensee has the right to choose either one of the above two licenses.
- *
- * Redistributions of source code must retain both the above copyright
- * notice and either one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, either one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dat_osd.c
- *
- * PURPOSE: Operating System Dependent layer
- * Description: 
- *     Provide OS dependent functions with a canonical DAPL
- *     interface. Designed to be portable and hide OS specific quirks
- *     of common functions.
- *
- * $Id: dat_osd.c 33 2005-07-11 19:51:17Z ftillier $
- **********************************************************************/
-
-#include "dat_osd.h"
-#include "dat_init.h"
-
-
-/*********************************************************************
- *                                                                   *
- * Constants                                                         *
- *                                                                   *
- *********************************************************************/
-
-#define DAT_DBG_LEVEL_ENV      "DAT_DBG_LEVEL"
-#define DAT_DBG_DEST_ENV       "DAT_DBG_DEST"
-
-
-/*********************************************************************
- *                                                                   *
- * Enumerations                                                      *
- *                                                                   *
- *********************************************************************/
-
-typedef int                    DAT_OS_DBG_DEST;
-
-typedef enum
-{
-    DAT_OS_DBG_DEST_STDOUT             = 0x1,
-} DAT_OS_DBG_DEST_TYPE;
-
-
-/*********************************************************************
- *                                                                   *
- * Global Variables                                                  *
- *                                                                   *
- *********************************************************************/
-
-static DAT_OS_DBG_TYPE_VAL     g_dbg_type = DAT_OS_DBG_TYPE_ERROR;
-static DAT_OS_DBG_DEST                 g_dbg_dest = DAT_OS_DBG_DEST_STDOUT;
-
-
-/***********************************************************************
- * Function: dat_os_dbg_set_level
- ***********************************************************************/
-
-void
-dat_os_dbg_init ( void )
-{
-    char *dbg_type;
-    char *dbg_dest;
-
-    dbg_type = dat_os_getenv (DAT_DBG_LEVEL_ENV);
-    if ( dbg_type != NULL )
-    {
-        g_dbg_type = dat_os_strtol(dbg_type, NULL, 0);
-    }
-
-    dbg_dest = dat_os_getenv (DAT_DBG_DEST_ENV);
-    if ( dbg_dest != NULL )
-    {
-        g_dbg_dest = dat_os_strtol(dbg_dest, NULL, 0);
-    }
-}
-
-
-/***********************************************************************
- * Function: dat_os_dbg_print
- ***********************************************************************/
-
-void 
-dat_os_dbg_print (  
-    DAT_OS_DBG_TYPE_VAL                type, 
-    const char *               fmt, 
-    ...)
-{
-    if ( (DAT_OS_DBG_TYPE_ERROR == type) || (type & g_dbg_type) )
-    {
-        va_list args;
-                
-        if ( DAT_OS_DBG_DEST_STDOUT & g_dbg_dest )
-        {
-            va_start(args, fmt);
-            vfprintf(stdout, fmt, args);
-        fflush(stdout);
-            va_end(args);
-        }
-       /* no syslog() susport in Windows */
-    }
-}
-
-
-BOOL APIENTRY
-DllMain(
-       IN                              HINSTANCE                                       h_module,
-       IN                              DWORD                                           ul_reason_for_call, 
-       IN                              LPVOID                                          lp_reserved )
-{
-       extern DAT_BOOLEAN udat_check_state ( void );
-
-       UNREFERENCED_PARAMETER( lp_reserved );
-
-       switch( ul_reason_for_call )
-       {
-       case DLL_PROCESS_ATTACH:
-               DisableThreadLibraryCalls( h_module );
-               udat_check_state();
-               break;
-
-       case DLL_PROCESS_DETACH:
-               dat_fini();
-       }
-
-       return TRUE;
-}
-
-char *
-dat_os_library_error(void)
-{
-    DWORD rc;
-    LPVOID lpMsgBuf;
-
-    if (errno == 0)
-       return NULL;
-
-    // consider formatmessage()?
-    rc = GetLastError();
-
-    FormatMessage(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-        FORMAT_MESSAGE_FROM_SYSTEM |
-        FORMAT_MESSAGE_IGNORE_INSERTS,
-        NULL,
-        rc,
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-        (LPTSTR) &lpMsgBuf,
-        0, NULL );
-
-    //LocalFree(lpMsgBuf); error condition - will exit anyway.
-
-    return (char*)lpMsgBuf;
-}
-
-#ifndef INLINE_LIB_LOAD
-
-DAT_RETURN
-dat_os_library_load ( const char              *library_path,
-                      DAT_OS_LIBRARY_HANDLE   *library_handle_ptr )
-{
-    DAT_OS_LIBRARY_HANDLE library_handle;
-    DAT_RETURN rc = DAT_SUCCESS;
-
-    if ( NULL != (library_handle = LoadLibrary(library_path)) )
-    {
-        if ( NULL != library_handle_ptr ) 
-        { 
-            *library_handle_ptr = library_handle; 
-        }
-    }
-    else
-    { 
-       dat_os_dbg_print(DAT_OS_DBG_TYPE_ERROR,
-                         "DAT: library %s  load failure\n",library_path);
-       rc = DAT_INTERNAL_ERROR;
-    }
-    return rc;
-}
-#endif
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under either one of the following two licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    in the file LICENSE.txt in the root directory. The license is also\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ * OR\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is in the file\r
+ *    LICENSE2.txt in the root directory. The license is also available from\r
+ *    the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * Licensee has the right to choose either one of the above two licenses.\r
+ *\r
+ * Redistributions of source code must retain both the above copyright\r
+ * notice and either one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, either one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dat_osd.c\r
+ *\r
+ * PURPOSE: Operating System Dependent layer\r
+ * Description: \r
+ *     Provide OS dependent functions with a canonical DAPL\r
+ *     interface. Designed to be portable and hide OS specific quirks\r
+ *     of common functions.\r
+ *\r
+ * $Id: dat_osd.c 33 2005-07-11 19:51:17Z ftillier $\r
+ **********************************************************************/\r
+\r
+#include "dat_osd.h"\r
+#include "dat_init.h"\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Constants                                                         *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+#define DAT_DBG_LEVEL_ENV      "DAT_DBG_LEVEL"\r
+#define DAT_DBG_DEST_ENV       "DAT_DBG_DEST"\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Enumerations                                                      *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef int                    DAT_OS_DBG_DEST;\r
+\r
+typedef enum\r
+{\r
+    DAT_OS_DBG_DEST_STDOUT             = 0x1,\r
+} DAT_OS_DBG_DEST_TYPE;\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Global Variables                                                  *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+static DAT_OS_DBG_TYPE_VAL     g_dbg_type = DAT_OS_DBG_TYPE_ERROR;\r
+static DAT_OS_DBG_DEST                 g_dbg_dest = DAT_OS_DBG_DEST_STDOUT;\r
+\r
+\r
+/***********************************************************************\r
+ * Function: dat_os_dbg_set_level\r
+ ***********************************************************************/\r
+\r
+void\r
+dat_os_dbg_init ( void )\r
+{\r
+    char *dbg_type;\r
+    char *dbg_dest;\r
+\r
+    dbg_type = dat_os_getenv (DAT_DBG_LEVEL_ENV);\r
+    if ( dbg_type != NULL )\r
+    {\r
+        g_dbg_type = dat_os_strtol(dbg_type, NULL, 0);\r
+    }\r
+\r
+    dbg_dest = dat_os_getenv (DAT_DBG_DEST_ENV);\r
+    if ( dbg_dest != NULL )\r
+    {\r
+        g_dbg_dest = dat_os_strtol(dbg_dest, NULL, 0);\r
+    }\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * Function: dat_os_dbg_print\r
+ ***********************************************************************/\r
+\r
+void \r
+dat_os_dbg_print (  \r
+    DAT_OS_DBG_TYPE_VAL                type, \r
+    const char *               fmt, \r
+    ...)\r
+{\r
+    if ( (DAT_OS_DBG_TYPE_ERROR == type) || (type & g_dbg_type) )\r
+    {\r
+        va_list args;\r
+                \r
+        if ( DAT_OS_DBG_DEST_STDOUT & g_dbg_dest )\r
+        {\r
+            va_start(args, fmt);\r
+            vfprintf(stdout, fmt, args);\r
+        fflush(stdout);\r
+            va_end(args);\r
+        }\r
+       /* no syslog() susport in Windows */\r
+    }\r
+}\r
+\r
+HANDLE heap;\r
+\r
+BOOL APIENTRY\r
+DllMain(\r
+       IN                              HINSTANCE                                       h_module,\r
+       IN                              DWORD                                           ul_reason_for_call, \r
+       IN                              LPVOID                                          lp_reserved )\r
+{\r
+       extern DAT_BOOLEAN udat_check_state ( void );\r
+\r
+       UNREFERENCED_PARAMETER( lp_reserved );\r
+\r
+       switch( ul_reason_for_call )\r
+       {\r
+       case DLL_PROCESS_ATTACH:\r
+               heap = HeapCreate(0, 0, 0);\r
+               if (heap == NULL)\r
+                       return FALSE;\r
+               DisableThreadLibraryCalls( h_module );\r
+               udat_check_state();\r
+               break;\r
+\r
+       case DLL_PROCESS_DETACH:\r
+               dat_fini();\r
+               HeapDestroy(heap);\r
+       }\r
+\r
+       return TRUE;\r
+}\r
+\r
+char *\r
+dat_os_library_error(void)\r
+{\r
+    DWORD rc;\r
+    LPVOID lpMsgBuf;\r
+\r
+    if (errno == 0)\r
+       return NULL;\r
+\r
+    // consider formatmessage()?\r
+    rc = GetLastError();\r
+\r
+    FormatMessage(\r
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | \r
+        FORMAT_MESSAGE_FROM_SYSTEM |\r
+        FORMAT_MESSAGE_IGNORE_INSERTS,\r
+        NULL,\r
+        rc,\r
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+        (LPTSTR) &lpMsgBuf,\r
+        0, NULL );\r
+\r
+    //LocalFree(lpMsgBuf); error condition - will exit anyway.\r
+\r
+    return (char*)lpMsgBuf;\r
+}\r
+\r
+#ifndef INLINE_LIB_LOAD\r
+\r
+DAT_RETURN\r
+dat_os_library_load ( const char              *library_path,\r
+                      DAT_OS_LIBRARY_HANDLE   *library_handle_ptr )\r
+{\r
+    DAT_OS_LIBRARY_HANDLE library_handle;\r
+    DAT_RETURN rc = DAT_SUCCESS;\r
+\r
+    if ( NULL != (library_handle = LoadLibrary(library_path)) )\r
+    {\r
+        if ( NULL != library_handle_ptr ) \r
+        { \r
+            *library_handle_ptr = library_handle; \r
+        }\r
+    }\r
+    else\r
+    { \r
+       dat_os_dbg_print(DAT_OS_DBG_TYPE_ERROR,\r
+                         "DAT: library %s  load failure\n",library_path);\r
+       rc = DAT_INTERNAL_ERROR;\r
+    }\r
+    return rc;\r
+}\r
+#endif\r
index d78fe44..f1dae5f 100644 (file)
-/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under either one of the following two licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- * OR
- *
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * Licensee has the right to choose either one of the above two licenses.
- *
- * Redistributions of source code must retain both the above copyright
- * notice and either one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, either one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * HEADER: dat_osd.h
- *
- * PURPOSE: Operating System Dependent layer
- * Description:
- *     Provide OS dependent data structures & functions with
- *     a canonical DAPL interface. Designed to be portable
- *     and hide OS specific quirks of common functions.
- *
- * $Id: dat_osd.h 33 2005-07-11 19:51:17Z ftillier $
- **********************************************************************/
-
-#ifndef _DAT_OSD_H_
-#define _DAT_OSD_H_
-
-/*
- * This file is defined for Windows systems only, including it on any
- * other build will cause an error
- */
-#if !defined(WIN32) && !defined(WIN64)
-#error "UNDEFINED OS TYPE"
-#endif /* WIN32/64 */
-
-#include <dat2/udat.h>
-#include <dat2/dat_registry.h>
-
-#include <windows.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#ifndef STATIC
-#define STATIC static
-#endif /* STATIC */
-
-#ifndef INLINE
-#define INLINE __inline
-#endif /* INLINE */
-
-#ifndef __inline__
-#define __inline__ __inline
-#endif /* __inline */
-
-/*********************************************************************
- *                                                                   *
- * Debuging                                                          *
- *                                                                   *
- *********************************************************************/
-
-#define dat_os_assert(expr)    assert(expr)
-
-typedef int                    DAT_OS_DBG_TYPE_VAL;
-
-typedef enum
-{
-    DAT_OS_DBG_TYPE_ERROR              = 0x1,
-    DAT_OS_DBG_TYPE_GENERIC            = 0x2,
-    DAT_OS_DBG_TYPE_SR                 = 0x4,
-    DAT_OS_DBG_TYPE_DR                 = 0x8,
-    DAT_OS_DBG_TYPE_PROVIDER_API       = 0x10,
-    DAT_OS_DBG_TYPE_CONSUMER_API       = 0x20,
-    DAT_OS_DBG_TYPE_ALL                = 0xff
-} DAT_OS_DBG_TYPE_TYPE;
-
-extern void
-dat_os_dbg_init ( void );
-
-extern void 
-dat_os_dbg_print (  
-    DAT_OS_DBG_TYPE_VAL                type, 
-    const char *               fmt, 
-    ...);
-
-
-/*********************************************************************
- *                                                                   *
- * Utility Functions                                                 *
- *                                                                   *
- *********************************************************************/
-
-#define DAT_ERROR(Type,SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))
-
-typedef size_t                         DAT_OS_SIZE;
-typedef HMODULE                DAT_OS_LIBRARY_HANDLE;
-
-#ifdef INLINE_LIB_LOAD
-
-STATIC INLINE DAT_RETURN
-dat_os_library_load (
-    const char                         *library_path,
-    DAT_OS_LIBRARY_HANDLE      *library_handle_ptr)
-{
-    DAT_OS_LIBRARY_HANDLE      library_handle;
-
-    if ( NULL != (library_handle = LoadLibrary(library_path)) )
-    {
-        if ( NULL != library_handle_ptr ) 
-        { 
-            *library_handle_ptr = library_handle; 
-        }
-        return DAT_SUCCESS;
-    }
-    else
-    { 
-       dat_os_dbg_print(DAT_OS_DBG_TYPE_ERROR,
-                         "DAT: library load failure\n");
-       return DAT_INTERNAL_ERROR;
-    }
-}
-#else
-
-DAT_RETURN
-dat_os_library_load (
-    const char                         *library_path,
-    DAT_OS_LIBRARY_HANDLE      *library_handle_ptr);
-
-#endif
-
-extern char *dat_os_library_error(void);
-
-#ifdef WIN32_LEAN_AND_MEAN
-#define dat_os_library_sym             GetProcAddress
-#else
-STATIC INLINE
-dat_os_library_sym (
-    DAT_OS_LIBRARY_HANDLE library_handle,
-    const char *sym)
-{
-    return GetProcAddress(library_handle, (LPCSTR)sym);
-}
-#endif /* WIN32_LEAN_AND_MEAN */
-
-STATIC INLINE DAT_RETURN
-dat_os_library_unload (
-    const DAT_OS_LIBRARY_HANDLE library_handle)
-{
-    if ( 0 == FreeLibrary(library_handle) )
-    {
-       return DAT_INTERNAL_ERROR;
-    }
-    else 
-    {
-       return DAT_SUCCESS;
-    }
-}
-
-STATIC INLINE char *
-dat_os_getenv (
-    const char *name)
-{
-    return getenv(name);
-}
-
-STATIC INLINE long int
-dat_os_strtol (
-    const char *nptr, 
-    char **endptr, 
-    int base)
-{
-    return strtol(nptr, endptr, base);
-}
-
-STATIC INLINE DAT_OS_SIZE
-dat_os_strlen (
-    const char *s )
-{
-    return strlen(s);
-}
-
-STATIC INLINE int
-dat_os_strncmp (
-    const char *s1, 
-    const char *s2, 
-    DAT_OS_SIZE n)
-{
-    return strncmp(s1, s2, n);
-}
-
-STATIC INLINE void * 
-dat_os_strncpy (
-    char *dest, 
-    const char *src, 
-    DAT_OS_SIZE len)
-{
-    return strncpy (dest, src, len);
-}
-
-STATIC INLINE DAT_BOOLEAN
-dat_os_isblank( 
-    int c)
-{
-    if ( (' ' == c) || ('\t' == c) ) { return DAT_TRUE; }
-    else { return DAT_FALSE; }
-}
-
-STATIC INLINE DAT_BOOLEAN
-dat_os_isdigit( 
-    int c)
-{
-    if ( isdigit(c) ) { return DAT_TRUE; }
-    else { return DAT_FALSE; }
-}
-
-STATIC INLINE void 
-dat_os_usleep( 
-    unsigned long usec)
-{
-    Sleep(usec/1000);
-}
-
-
-/*********************************************************************
- *                                                                   *
- * Memory Functions                                                  *
- *                                                                   *
- *********************************************************************/
-
-STATIC INLINE void *
-dat_os_alloc (
-    int size)
-{
-    return malloc (size);
-}
-
-STATIC INLINE void 
-dat_os_free (
-    void *ptr, 
-    int size)
-{
-    free (ptr);
-}
-
-STATIC INLINE void * 
-dat_os_memset (void *loc, int c, DAT_OS_SIZE size)
-{
-    return memset (loc, c, size);
-}
-
-
-/*********************************************************************
- *                                                                   *
- * File I/O                                                          *
- *                                                                   *
- *********************************************************************/
-
-typedef FILE                   DAT_OS_FILE;
-typedef fpos_t                  DAT_OS_FILE_POS;
-
-
-STATIC INLINE DAT_OS_FILE *
-dat_os_fopen (
-    const char * path)
-{
-    /* always open files in read only mode*/
-    return fopen(path, "r");
-}
-
-STATIC INLINE DAT_RETURN
-dat_os_fgetpos ( 
-    DAT_OS_FILE *file, 
-    DAT_OS_FILE_POS *pos)
-{
-    if ( 0 == fgetpos(file, pos) )
-    {
-       return DAT_SUCCESS;
-    }
-    else
-    {
-       return DAT_INTERNAL_ERROR;
-    }
-}
-
-STATIC INLINE DAT_RETURN
-dat_os_fsetpos ( 
-    DAT_OS_FILE *file, 
-    DAT_OS_FILE_POS *pos)
-{
-    if ( 0 == fsetpos(file, pos) )
-    {
-       return DAT_SUCCESS;
-    }
-    else
-    {
-       return DAT_INTERNAL_ERROR;
-    }
-}
-
-/* dat_os_fgetc() returns EOF on error or end of file. */
-STATIC INLINE int
-dat_os_fgetc ( 
-    DAT_OS_FILE *file)
-{
-    return fgetc(file);
-}
-
-/* dat_os_ungetc() returns EOF on error or char 'c'.
- * Push char 'c' back into specified stream for subsequent read.
- */
-STATIC INLINE int
-dat_os_ungetc ( 
-    DAT_OS_FILE *file, int c)
-{
-    return ungetc(c, file);
-}
-
-/* dat_os_fputc() returns EOF on error or char 'c'. */
-STATIC INLINE int
-dat_os_fputc ( 
-    DAT_OS_FILE *file, int c)
-{
-    return fputc(c, file);
-}
-
-/* dat_os_fread returns the number of bytes read from the file. */
-STATIC INLINE DAT_OS_SIZE
-dat_os_fread (
-    DAT_OS_FILE *file,
-    char *buf, 
-    DAT_OS_SIZE len)
-{
-    return fread(buf, sizeof(char), len, file);
-}
-
-STATIC INLINE DAT_RETURN 
-dat_os_fclose (
-    DAT_OS_FILE *file)
-{
-    if ( 0 == fclose(file) )
-    {
-       return DAT_SUCCESS;
-    }
-    else
-    {
-       return DAT_INTERNAL_ERROR;
-    }
-}
-
-
-/*********************************************************************
- *                                                                   *
- * Locks                                                             *
- *                                                                   *
- *********************************************************************/
-
-typedef HANDLE            DAT_OS_LOCK;
-
-/* lock functions */
-STATIC INLINE DAT_RETURN 
-dat_os_lock_init (
-    IN DAT_OS_LOCK *m)
-{
-  *m = CreateMutex (0, FALSE, 0);
-  if (*(HANDLE *)m == NULL)
-  {
-    return DAT_INTERNAL_ERROR;
-  }
-  return DAT_SUCCESS;
-}
-
-STATIC INLINE DAT_RETURN 
-dat_os_lock (
-    IN DAT_OS_LOCK *m)
-{
-  WaitForSingleObject(*m, INFINITE);
-
-  return DAT_SUCCESS;
-}
-
-STATIC INLINE DAT_RETURN 
-dat_os_unlock (
-    IN DAT_OS_LOCK *m)
-{
-  ReleaseMutex (*m);
-
-  return DAT_SUCCESS;
-}
-
-STATIC INLINE DAT_RETURN 
-dat_os_lock_destroy (
-    IN DAT_OS_LOCK *m)
-{
-    CloseHandle (*m);
-
-    return DAT_SUCCESS;
-}
-
-
-#endif /*  _DAT_OSD_H_ */
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
-
+/*\r
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under either one of the following two licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    in the file LICENSE.txt in the root directory. The license is also\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ * OR\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is in the file\r
+ *    LICENSE2.txt in the root directory. The license is also available from\r
+ *    the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * Licensee has the right to choose either one of the above two licenses.\r
+ *\r
+ * Redistributions of source code must retain both the above copyright\r
+ * notice and either one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, either one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * HEADER: dat_osd.h\r
+ *\r
+ * PURPOSE: Operating System Dependent layer\r
+ * Description:\r
+ *     Provide OS dependent data structures & functions with\r
+ *     a canonical DAPL interface. Designed to be portable\r
+ *     and hide OS specific quirks of common functions.\r
+ *\r
+ * $Id: dat_osd.h 33 2005-07-11 19:51:17Z ftillier $\r
+ **********************************************************************/\r
+\r
+#ifndef _DAT_OSD_H_\r
+#define _DAT_OSD_H_\r
+\r
+/*\r
+ * This file is defined for Windows systems only, including it on any\r
+ * other build will cause an error\r
+ */\r
+#if !defined(WIN32) && !defined(WIN64)\r
+#error "UNDEFINED OS TYPE"\r
+#endif /* WIN32/64 */\r
+\r
+#include <dat2/udat.h>\r
+#include <dat2/dat_registry.h>\r
+\r
+#include <windows.h>\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdarg.h>\r
+\r
+#ifndef STATIC\r
+#define STATIC static\r
+#endif /* STATIC */\r
+\r
+#ifndef INLINE\r
+#define INLINE __inline\r
+#endif /* INLINE */\r
+\r
+#ifndef __inline__\r
+#define __inline__ __inline\r
+#endif /* __inline */\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Debuging                                                          *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+#define dat_os_assert(expr)    assert(expr)\r
+\r
+typedef int                    DAT_OS_DBG_TYPE_VAL;\r
+\r
+typedef enum\r
+{\r
+    DAT_OS_DBG_TYPE_ERROR              = 0x1,\r
+    DAT_OS_DBG_TYPE_GENERIC            = 0x2,\r
+    DAT_OS_DBG_TYPE_SR                 = 0x4,\r
+    DAT_OS_DBG_TYPE_DR                 = 0x8,\r
+    DAT_OS_DBG_TYPE_PROVIDER_API       = 0x10,\r
+    DAT_OS_DBG_TYPE_CONSUMER_API       = 0x20,\r
+    DAT_OS_DBG_TYPE_ALL                = 0xff\r
+} DAT_OS_DBG_TYPE_TYPE;\r
+\r
+extern void\r
+dat_os_dbg_init ( void );\r
+\r
+extern void \r
+dat_os_dbg_print (  \r
+    DAT_OS_DBG_TYPE_VAL                type, \r
+    const char *               fmt, \r
+    ...);\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Utility Functions                                                 *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+#define DAT_ERROR(Type,SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))\r
+\r
+typedef size_t                         DAT_OS_SIZE;\r
+typedef HMODULE                DAT_OS_LIBRARY_HANDLE;\r
+\r
+#ifdef INLINE_LIB_LOAD\r
+\r
+STATIC INLINE DAT_RETURN\r
+dat_os_library_load (\r
+    const char                         *library_path,\r
+    DAT_OS_LIBRARY_HANDLE      *library_handle_ptr)\r
+{\r
+    DAT_OS_LIBRARY_HANDLE      library_handle;\r
+\r
+    if ( NULL != (library_handle = LoadLibrary(library_path)) )\r
+    {\r
+        if ( NULL != library_handle_ptr ) \r
+        { \r
+            *library_handle_ptr = library_handle; \r
+        }\r
+        return DAT_SUCCESS;\r
+    }\r
+    else\r
+    { \r
+       dat_os_dbg_print(DAT_OS_DBG_TYPE_ERROR,\r
+                         "DAT: library load failure\n");\r
+       return DAT_INTERNAL_ERROR;\r
+    }\r
+}\r
+#else\r
+\r
+DAT_RETURN\r
+dat_os_library_load (\r
+    const char                         *library_path,\r
+    DAT_OS_LIBRARY_HANDLE      *library_handle_ptr);\r
+\r
+#endif\r
+\r
+extern char *dat_os_library_error(void);\r
+\r
+#ifdef WIN32_LEAN_AND_MEAN\r
+#define dat_os_library_sym             GetProcAddress\r
+#else\r
+STATIC INLINE\r
+dat_os_library_sym (\r
+    DAT_OS_LIBRARY_HANDLE library_handle,\r
+    const char *sym)\r
+{\r
+    return GetProcAddress(library_handle, (LPCSTR)sym);\r
+}\r
+#endif /* WIN32_LEAN_AND_MEAN */\r
+\r
+STATIC INLINE DAT_RETURN\r
+dat_os_library_unload (\r
+    const DAT_OS_LIBRARY_HANDLE library_handle)\r
+{\r
+    if ( 0 == FreeLibrary(library_handle) )\r
+    {\r
+       return DAT_INTERNAL_ERROR;\r
+    }\r
+    else \r
+    {\r
+       return DAT_SUCCESS;\r
+    }\r
+}\r
+\r
+STATIC INLINE char *\r
+dat_os_getenv (\r
+    const char *name)\r
+{\r
+    return getenv(name);\r
+}\r
+\r
+STATIC INLINE long int\r
+dat_os_strtol (\r
+    const char *nptr, \r
+    char **endptr, \r
+    int base)\r
+{\r
+    return strtol(nptr, endptr, base);\r
+}\r
+\r
+STATIC INLINE DAT_OS_SIZE\r
+dat_os_strlen (\r
+    const char *s )\r
+{\r
+    return strlen(s);\r
+}\r
+\r
+STATIC INLINE int\r
+dat_os_strncmp (\r
+    const char *s1, \r
+    const char *s2, \r
+    DAT_OS_SIZE n)\r
+{\r
+    return strncmp(s1, s2, n);\r
+}\r
+\r
+STATIC INLINE void * \r
+dat_os_strncpy (\r
+    char *dest, \r
+    const char *src, \r
+    DAT_OS_SIZE len)\r
+{\r
+    return strncpy (dest, src, len);\r
+}\r
+\r
+STATIC INLINE DAT_BOOLEAN\r
+dat_os_isblank( \r
+    int c)\r
+{\r
+    if ( (' ' == c) || ('\t' == c) ) { return DAT_TRUE; }\r
+    else { return DAT_FALSE; }\r
+}\r
+\r
+STATIC INLINE DAT_BOOLEAN\r
+dat_os_isdigit( \r
+    int c)\r
+{\r
+    if ( isdigit(c) ) { return DAT_TRUE; }\r
+    else { return DAT_FALSE; }\r
+}\r
+\r
+STATIC INLINE void \r
+dat_os_usleep( \r
+    unsigned long usec)\r
+{\r
+    Sleep(usec/1000);\r
+}\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Memory Functions                                                  *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+extern HANDLE heap;\r
+\r
+STATIC INLINE void *\r
+dat_os_alloc (\r
+    int size)\r
+{\r
+       return HeapAlloc(heap, 0, size);\r
+}\r
+\r
+STATIC INLINE void \r
+dat_os_free (\r
+    void *ptr, \r
+    int size)\r
+{\r
+       UNREFERENCED_PARAMETER(size);\r
+       HeapFree(heap, 0, ptr);\r
+}\r
+\r
+STATIC INLINE void * \r
+dat_os_memset (void *loc, int c, DAT_OS_SIZE size)\r
+{\r
+    return memset (loc, c, size);\r
+}\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * File I/O                                                          *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef FILE                   DAT_OS_FILE;\r
+typedef fpos_t                  DAT_OS_FILE_POS;\r
+\r
+\r
+STATIC INLINE DAT_OS_FILE *\r
+dat_os_fopen (\r
+    const char * path)\r
+{\r
+    /* always open files in read only mode*/\r
+    return fopen(path, "r");\r
+}\r
+\r
+STATIC INLINE DAT_RETURN\r
+dat_os_fgetpos ( \r
+    DAT_OS_FILE *file, \r
+    DAT_OS_FILE_POS *pos)\r
+{\r
+    if ( 0 == fgetpos(file, pos) )\r
+    {\r
+       return DAT_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+       return DAT_INTERNAL_ERROR;\r
+    }\r
+}\r
+\r
+STATIC INLINE DAT_RETURN\r
+dat_os_fsetpos ( \r
+    DAT_OS_FILE *file, \r
+    DAT_OS_FILE_POS *pos)\r
+{\r
+    if ( 0 == fsetpos(file, pos) )\r
+    {\r
+       return DAT_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+       return DAT_INTERNAL_ERROR;\r
+    }\r
+}\r
+\r
+/* dat_os_fgetc() returns EOF on error or end of file. */\r
+STATIC INLINE int\r
+dat_os_fgetc ( \r
+    DAT_OS_FILE *file)\r
+{\r
+    return fgetc(file);\r
+}\r
+\r
+/* dat_os_ungetc() returns EOF on error or char 'c'.\r
+ * Push char 'c' back into specified stream for subsequent read.\r
+ */\r
+STATIC INLINE int\r
+dat_os_ungetc ( \r
+    DAT_OS_FILE *file, int c)\r
+{\r
+    return ungetc(c, file);\r
+}\r
+\r
+/* dat_os_fputc() returns EOF on error or char 'c'. */\r
+STATIC INLINE int\r
+dat_os_fputc ( \r
+    DAT_OS_FILE *file, int c)\r
+{\r
+    return fputc(c, file);\r
+}\r
+\r
+/* dat_os_fread returns the number of bytes read from the file. */\r
+STATIC INLINE DAT_OS_SIZE\r
+dat_os_fread (\r
+    DAT_OS_FILE *file,\r
+    char *buf, \r
+    DAT_OS_SIZE len)\r
+{\r
+    return fread(buf, sizeof(char), len, file);\r
+}\r
+\r
+STATIC INLINE DAT_RETURN \r
+dat_os_fclose (\r
+    DAT_OS_FILE *file)\r
+{\r
+    if ( 0 == fclose(file) )\r
+    {\r
+       return DAT_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+       return DAT_INTERNAL_ERROR;\r
+    }\r
+}\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Locks                                                             *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef HANDLE            DAT_OS_LOCK;\r
+\r
+/* lock functions */\r
+STATIC INLINE DAT_RETURN \r
+dat_os_lock_init (\r
+    IN DAT_OS_LOCK *m)\r
+{\r
+  *m = CreateMutex (0, FALSE, 0);\r
+  if (*(HANDLE *)m == NULL)\r
+  {\r
+    return DAT_INTERNAL_ERROR;\r
+  }\r
+  return DAT_SUCCESS;\r
+}\r
+\r
+STATIC INLINE DAT_RETURN \r
+dat_os_lock (\r
+    IN DAT_OS_LOCK *m)\r
+{\r
+  WaitForSingleObject(*m, INFINITE);\r
+\r
+  return DAT_SUCCESS;\r
+}\r
+\r
+STATIC INLINE DAT_RETURN \r
+dat_os_unlock (\r
+    IN DAT_OS_LOCK *m)\r
+{\r
+  ReleaseMutex (*m);\r
+\r
+  return DAT_SUCCESS;\r
+}\r
+\r
+STATIC INLINE DAT_RETURN \r
+dat_os_lock_destroy (\r
+    IN DAT_OS_LOCK *m)\r
+{\r
+    CloseHandle (*m);\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+#endif /*  _DAT_OSD_H_ */\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
+\r
index 5e92720..772f2dd 100644 (file)
@@ -203,6 +203,6 @@ do { \
 /*
  * Release processor to reschedule
  */
-#define DT_Mdep_yield pthread_yield()
+#define DT_Mdep_yield pthread_yield
 
 #endif
index 3a1e628..0ed3992 100644 (file)
@@ -74,6 +74,10 @@ do { \
 #define DT_Mdep_printf printf
 #define DT_Mdep_flush() fflush(NULL)
 
+/*
+ * Release processor to reschedule
+ */
+#define DT_Mdep_yield pthread_yield
 
 /*
  * Locks
index dffbd9b..d551dd0 100644 (file)
@@ -82,7 +82,7 @@ do { \
 /*
  * Release processor to reschedule
  */
-#define DT_Mdep_yield Sleep(0)
+#define DT_Mdep_yield() Sleep(0)
 
 /*
  * Locks
index 25800bf..f1eb23b 100644 (file)
@@ -17,11 +17,7 @@ if not "!F!" == "off" (
 rem set DAT_OVERRIDE=D:\dapl2\dat.conf\r
 rem favor DAT 2.0 (dapl2test.exe) over DAT 1.1 (dapltest.exe)\r
 \r
-if EXIST "%ProgramFiles(x86)%" (\r
-    set PF="%ProgramFiles(x86)%\WinOF"\r
-) else (\r
-    set PF="%ProgramFiles%\WinOF"\r
-)\r
+set PF="%ProgramFiles%\WinOF"\r
 \r
 if NOT EXIST %PF%\dapl2test.exe (\r
     echo Missing file %PF%\dapl2test.exe ?\r
index c876d41..abd17fb 100644 (file)
@@ -6,11 +6,7 @@ SETLOCAL
 \r
 rem set DAT_OVERRIDE=C:\DAT\dat.conf\r
 \r
-if EXIST "%ProgramFiles(x86)%" (\r
-    set PF="%ProgramFiles(x86)%\WinOF"\r
-) else (\r
-    set PF="%ProgramFiles%\WinOF"\r
-)\r
+set PF="%ProgramFiles%\WinOF"\r
 \r
 if NOT EXIST %PF%\dapl2test.exe (\r
     echo Missing file %PF%\dapl2test.exe ?\r
index 2b78b9d..9f5a555 100644 (file)
-/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a 
- *    copy of which is in the file LICENSE3.txt in the root directory. The 
- *    license is also available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-#include "dapl_proto.h"
-
-/* -----------------------------------------------------------
- * Gather info about default attributes
- */
-DAT_BOOLEAN
-DT_query(Per_Test_Data_t * pt_ptr,
-        DAT_IA_HANDLE ia_handle, DAT_EP_HANDLE ep_handle)
-{
-       char *module = "DT_query";
-       DAT_EVD_HANDLE async_evd_hdl;   /* not used */
-       DAT_EP_PARAM ep_params;
-       DAT_RETURN ret;
-       DT_Tdep_Print_Head *phead;
-
-       phead = pt_ptr->Params.phead;
-
-       /* Query the IA */
-       ret = dat_ia_query(ia_handle,
-                          &async_evd_hdl,
-                          DAT_IA_ALL,
-                          &pt_ptr->ia_attr,
-                          DAT_PROVIDER_FIELD_ALL, &pt_ptr->provider_attr);
-       if (ret != DAT_SUCCESS) {
-               DT_Tdep_PT_Printf(phead, "%s: dat_ia_query error: %s\n",
-                                 module, DT_RetToString(ret));
-               return (false);
-       }
-
-       /* Query the EP */
-       ret = dat_ep_query(ep_handle, DAT_EP_FIELD_ALL, &ep_params);
-       if (ret != DAT_SUCCESS) {
-               DT_Tdep_PT_Printf(phead, "%s: dat_ep_query error: %s\n",
-                                 module, DT_RetToString(ret));
-               return (false);
-       }
-       pt_ptr->ep_attr = ep_params.ep_attr;
-
-       /*
-        * If debugging, print out some interesting attributes
-        */
-       if (DT_dapltest_debug) {
-               DAT_SOCK_ADDR6 *ip6_addr;
-               struct sockaddr_in *ip_addr;
-
-               DT_Tdep_PT_Printf(phead,
-                                 "*****  DAPL  Characteristics  *****\n");
-               DT_Tdep_PT_Printf(phead,
-                                 "Provider: %s  Version %d.%d  DAPL %d.%d\n",
-                                 pt_ptr->provider_attr.provider_name,
-                                 pt_ptr->provider_attr.provider_version_major,
-                                 pt_ptr->provider_attr.provider_version_minor,
-                                 pt_ptr->provider_attr.dapl_version_major,
-                                 pt_ptr->provider_attr.dapl_version_minor);
-               DT_Tdep_PT_Printf(phead, "Adapter: %s by %s Version %d.%d\n",
-                                 pt_ptr->ia_attr.adapter_name,
-                                 pt_ptr->ia_attr.vendor_name,
-                                 pt_ptr->ia_attr.hardware_version_major,
-                                 pt_ptr->ia_attr.hardware_version_minor);
-               DT_Tdep_PT_Printf(phead, "Supporting:\n");
-               DT_Tdep_PT_Printf(phead,
-                                 "\t%d EPs with %d DTOs and %d RDMA/RDs each\n",
-                                 pt_ptr->ia_attr.max_eps,
-                                 pt_ptr->ia_attr.max_dto_per_ep,
-                                 pt_ptr->ia_attr.max_rdma_read_per_ep);
-               DT_Tdep_PT_Printf(phead,
-                                 "\t%d EVDs of up to %d entries "
-                                 " (default S/R size is %d/%d)\n",
-                                 pt_ptr->ia_attr.max_evds,
-                                 pt_ptr->ia_attr.max_evd_qlen,
-                                 pt_ptr->ep_attr.max_request_dtos,
-                                 pt_ptr->ep_attr.max_recv_dtos);
-               DT_Tdep_PT_Printf(phead, "\tIOVs of up to %d elements\n",
-                                 pt_ptr->ia_attr.max_iov_segments_per_dto);
-               DT_Tdep_PT_Printf(phead,
-                                 "\t%d LMRs (and %d RMRs) of up to 0x" F64x
-                                 " bytes\n", pt_ptr->ia_attr.max_lmrs,
-                                 pt_ptr->ia_attr.max_rmrs,
-                                 pt_ptr->ia_attr.max_lmr_block_size);
-               DT_Tdep_PT_Printf(phead,
-                                 "\tMaximum MTU 0x" F64x " bytes, RDMA 0x" F64x
-                                 " bytes\n", pt_ptr->ia_attr.max_mtu_size,
-                                 pt_ptr->ia_attr.max_rdma_size);
-               DT_Tdep_PT_Printf(phead,
-                                 "\tMaximum Private data size %d bytes\n",
-                                 pt_ptr->provider_attr.max_private_data_size);
-
-               ip6_addr = (DAT_SOCK_ADDR6 *) pt_ptr->ia_attr.ia_address_ptr;
-               if (ip6_addr->sin6_family == AF_INET6) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "\tLocal IP address  %x:%x:%x:%x:%x:%x:%x:%x:\n",
-                                         ip6_addr->sin6_addr.s6_addr[0],
-                                         ip6_addr->sin6_addr.s6_addr[1],
-                                         ip6_addr->sin6_addr.s6_addr[2],
-                                         ip6_addr->sin6_addr.s6_addr[3],
-                                         ip6_addr->sin6_addr.s6_addr[4],
-                                         ip6_addr->sin6_addr.s6_addr[5],
-                                         ip6_addr->sin6_addr.s6_addr[6],
-                                         ip6_addr->sin6_addr.s6_addr[7]);
-                       DT_Tdep_PT_Printf(phead, "%x:%x:%x:%x:%x:%x:%x:%x\n",
-                                         ip6_addr->sin6_addr.s6_addr[8],
-                                         ip6_addr->sin6_addr.s6_addr[9],
-                                         ip6_addr->sin6_addr.s6_addr[10],
-                                         ip6_addr->sin6_addr.s6_addr[11],
-                                         ip6_addr->sin6_addr.s6_addr[12],
-                                         ip6_addr->sin6_addr.s6_addr[13],
-                                         ip6_addr->sin6_addr.s6_addr[14],
-                                         ip6_addr->sin6_addr.s6_addr[15]);
-               } else if (ip6_addr->sin6_family == AF_INET)
-               {
-                       ip_addr =
-                           (struct sockaddr_in *)pt_ptr->ia_attr.
-                           ia_address_ptr;
-
-                       DT_Tdep_PT_Printf(phead, "\tLocal IP address %s\n",
-                                         inet_ntoa(ip_addr->sin_addr));
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "***** ***** ***** ***** ***** *****\n");
-       }
-
-       return (true);
-}
-
-/* -----------------------------------------------------------
- * Post a recv buffer
- */
-DAT_BOOLEAN
-DT_post_recv_buffer(DT_Tdep_Print_Head * phead,
-                   DAT_EP_HANDLE ep_handle, Bpool * bp, int index, int size)
-{
-       unsigned char *buff = DT_Bpool_GetBuffer(bp, index);
-       DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(bp, index);
-       DAT_LMR_CONTEXT lmr_c = DT_Bpool_GetLMR(bp, index);
-       DAT_DTO_COOKIE cookie;
-       DAT_RETURN ret;
-
-       /*
-        * Prep the inputs
-        */
-       iov->virtual_address = (DAT_VADDR) (uintptr_t) buff;
-       iov->segment_length = size;
-       iov->lmr_context = lmr_c;
-       cookie.as_64 = (DAT_UINT64) 0UL;
-       cookie.as_ptr = (DAT_PVOID) buff;
-
-       DT_Tdep_PT_Debug(3,
-                        (phead, "Post-Recv #%d [%p, %x]\n", index, buff,
-                         size));
-
-       /* Post the recv buffer */
-       ret = dat_ep_post_recv(ep_handle,
-                              1, iov, cookie, DAT_COMPLETION_DEFAULT_FLAG);
-       if (ret != DAT_SUCCESS) {
-               DT_Tdep_PT_Printf(phead,
-                                 "Test Error: dat_ep_post_recv failed: %s\n",
-                                 DT_RetToString(ret));
-               DT_Test_Error();
-               return false;
-       }
-       return true;
-}
-
-/* -----------------------------------------------------------
- * Post a send buffer
- */
-DAT_BOOLEAN
-DT_post_send_buffer(DT_Tdep_Print_Head * phead,
-                   DAT_EP_HANDLE ep_handle, Bpool * bp, int index, int size)
-{
-       unsigned char *buff = DT_Bpool_GetBuffer(bp, index);
-       DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(bp, index);
-       DAT_LMR_CONTEXT lmr_c = DT_Bpool_GetLMR(bp, index);
-       DAT_DTO_COOKIE cookie;
-       DAT_RETURN ret;
-
-       /*
-        * Prep the inputs
-        */
-       iov->virtual_address = (DAT_VADDR) (uintptr_t) buff;
-       iov->segment_length = size;
-       iov->lmr_context = lmr_c;
-       cookie.as_64 = (DAT_UINT64) 0UL;
-       cookie.as_ptr = (DAT_PVOID) buff;
-
-       DT_Tdep_PT_Debug(3,
-                        (phead, "Post-Send #%d [%p, %x]\n", index, buff,
-                         size));
-
-       /* Post the recv buffer */
-       ret = dat_ep_post_send(ep_handle,
-                              1, iov, cookie, DAT_COMPLETION_DEFAULT_FLAG);
-       if (ret != DAT_SUCCESS) {
-               DT_Tdep_PT_Printf(phead,
-                                 "Test Error: dat_ep_post_send failed: %s\n",
-                                 DT_RetToString(ret));
-               DT_Test_Error();
-               return false;
-       }
-       return true;
-}
-
-/* -----------------------------------------------------------
- * Wait for a CR event, returning false on error.
- */
-bool
-DT_cr_event_wait(DT_Tdep_Print_Head * phead,
-                DAT_EVD_HANDLE evd_handle,
-                DAT_CR_ARRIVAL_EVENT_DATA * cr_stat_p)
-{
-       int err_cnt;
-
-       err_cnt = 0;
-
-       for (;;) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret =
-                   DT_Tdep_evd_wait(evd_handle, DAT_TIMEOUT_INFINITE, &event);
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (CR) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       /*
-                        * If we get an error due to the client breaking the
-                        * connection early or some transients, just ignore it
-                        * and keep going. If we get a bunch of errors, bail
-                        * out.
-                        */
-                       /*      if ( err_cnt++ < 10 ) */
-                       /*      { */
-                       /*              continue; */
-                       /*      } */
-
-                       break;
-               }
-
-               if (event.event_number == DAT_CONNECTION_REQUEST_EVENT) {
-                       /*
-                        * Pass back what we know, if requested.
-                        */
-                       if (cr_stat_p) {
-                               *cr_stat_p =
-                                   event.event_data.cr_arrival_event_data;
-                       }
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: cr_event_wait swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Wait for a connection event, returning false on error.
- */
-bool
-DT_conn_event_wait(DT_Tdep_Print_Head * phead,
-                  DAT_EP_HANDLE ep_handle,
-                  DAT_EVD_HANDLE evd_handle, DAT_EVENT_NUMBER * event_number)
-{
-       for (;;) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret =
-                   DT_Tdep_evd_wait(evd_handle, DAT_TIMEOUT_INFINITE, &event);
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (CONN) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       break;
-               }
-               *event_number = event.event_number;
-               if (event.event_number == DAT_CONNECTION_EVENT_PEER_REJECTED
-                   || event.event_number ==
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED
-                   || event.event_number ==
-                   DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR
-                   || event.event_number == DAT_CONNECTION_EVENT_DISCONNECTED
-                   || event.event_number == DAT_CONNECTION_EVENT_BROKEN
-                   || event.event_number == DAT_CONNECTION_EVENT_UNREACHABLE
-                   || event.event_number == DAT_CONNECTION_EVENT_TIMED_OUT) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Warning: conn_event_wait %s\n",
-                                         DT_EventToSTr(event.event_number));
-                       break;
-               }
-               if (event.event_number == DAT_CONNECTION_EVENT_ESTABLISHED) {
-                       /*
-                        * Could return DAT_CONNECTION_EVENT_DATA and verify:
-                        *      event.event_data.connect_event_data.ep_handle
-                        *      event.event_data.connect_event_data.private_data_size
-                        *      event.event_data.connect_event_data.private_data
-                        */
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: conn_event_wait swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Wait for a disconnection event, returning false on error.
- */
-bool
-DT_disco_event_wait(DT_Tdep_Print_Head * phead,
-                   DAT_EVD_HANDLE evd_handle, DAT_EP_HANDLE * ep_handle)
-{
-       for (;;) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret =
-                   DT_Tdep_evd_wait(evd_handle, DAT_TIMEOUT_INFINITE, &event);
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (DISCONN) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       break;
-               }
-               if (event.event_number == DAT_CONNECTION_EVENT_PEER_REJECTED
-                   || event.event_number ==
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED
-                   || event.event_number ==
-                   DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR
-                   || event.event_number == DAT_CONNECTION_EVENT_BROKEN
-                   || event.event_number == DAT_CONNECTION_EVENT_UNREACHABLE
-                   || event.event_number == DAT_CONNECTION_EVENT_TIMED_OUT) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Warning: disconn_event_wait %s\n",
-                                         DT_EventToSTr(event.event_number));
-                       break;
-               }
-
-               if (event.event_number == DAT_CONNECTION_EVENT_DISCONNECTED) {
-                       if (ep_handle != NULL) {
-                               *ep_handle =
-                                   event.event_data.connect_event_data.
-                                   ep_handle;
-                       }
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: conn_event_wait swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Reap a DTO event using a wait or polling, returning false on error.
- */
-bool
-DT_dto_event_reap(DT_Tdep_Print_Head * phead,
-                 DAT_EVD_HANDLE evd_handle,
-                 bool poll, DAT_DTO_COMPLETION_EVENT_DATA * dto_statusp)
-{
-       if (poll) {
-               return DT_dto_event_poll(phead, evd_handle, dto_statusp);
-       } else {
-               return DT_dto_event_wait(phead, evd_handle, dto_statusp);
-       }
-}
-
-/* -----------------------------------------------------------
- * Poll for a DTO event, returning false on error.
- */
-bool
-DT_dto_event_poll(DT_Tdep_Print_Head * phead,
-                 DAT_EVD_HANDLE evd_handle,
-                 DAT_DTO_COMPLETION_EVENT_DATA * dto_statusp)
-{
-       for (;;DT_Mdep_yield) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret = DT_Tdep_evd_dequeue(evd_handle, &event);
-
-               if (DAT_GET_TYPE(ret) == DAT_QUEUE_EMPTY) {
-                       continue;
-               }
-
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (DTO) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       break;
-               }
-
-               if (event.event_number == DAT_DTO_COMPLETION_EVENT) {
-                       /*
-                        * Pass back all the useful bits if requested:
-                        *      ep_handle,  user_cookie.as_ptr
-                        *      status,     transfered_length
-                        */
-                       if (dto_statusp) {
-                               *dto_statusp =
-                                   event.event_data.dto_completion_event_data;
-                       }
-
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: dto_event_poll swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Wait for a DTO event, returning false on error.
- */
-bool
-DT_dto_event_wait(DT_Tdep_Print_Head * phead,
-                 DAT_EVD_HANDLE evd_handle,
-                 DAT_DTO_COMPLETION_EVENT_DATA * dto_statusp)
-{
-       for (;;) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret =
-                   DT_Tdep_evd_wait(evd_handle, DAT_TIMEOUT_INFINITE, &event);
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (DTO) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       break;
-               }
-
-               if (event.event_number == DAT_DTO_COMPLETION_EVENT) {
-                       /*
-                        * Pass back all the useful bits if requested:
-                        *      ep_handle,  user_cookie.as_ptr
-                        *      status,     transfered_length
-                        */
-                       if (dto_statusp) {
-                               *dto_statusp =
-                                   event.event_data.dto_completion_event_data;
-                       }
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: dto_event_wait swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Wait for a RMR event, returning false on error.
- */
-bool
-DT_rmr_event_wait(DT_Tdep_Print_Head * phead,
-                 DAT_EVD_HANDLE evd_handle,
-                 DAT_RMR_BIND_COMPLETION_EVENT_DATA * rmr_statusp)
-{
-       for (;;) {
-               DAT_RETURN ret;
-               DAT_EVENT event;
-
-               ret =
-                   DT_Tdep_evd_wait(evd_handle, DAT_TIMEOUT_INFINITE, &event);
-               if (ret != DAT_SUCCESS) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "Test Error: dapl_event_wait (RMR) failed: %s\n",
-                                         DT_RetToString(ret));
-                       DT_Test_Error();
-                       break;
-               }
-
-               if (event.event_number == DAT_RMR_BIND_COMPLETION_EVENT) {
-                       /*
-                        * Pass back all the useful bits if requested:
-                        *      rmr_handle,  user_cookie, status
-                        */
-                       if (rmr_statusp) {
-                               *rmr_statusp =
-                                   event.event_data.rmr_completion_event_data;
-                       }
-                       return (true);
-               }
-
-               DT_Tdep_PT_Printf(phead,
-                                 "Warning: rmr_event_wait swallowing %s event\n",
-                                 DT_EventToSTr(event.event_number));
-       }
-
-       return (false);
-}
-
-/* -----------------------------------------------------------
- * Check a DTO and print some debug info if anything is amiss.
- */
-bool
-DT_dto_check(DT_Tdep_Print_Head * phead,
-            DAT_DTO_COMPLETION_EVENT_DATA * dto_p,
-            DAT_EP_HANDLE ep_expected,
-            DAT_COUNT len_expected,
-            DAT_DTO_COOKIE cookie_expected, char *message)
-{
-       if (((ep_expected != NULL) && (dto_p->ep_handle != ep_expected))
-           || dto_p->transfered_length != len_expected
-           || dto_p->user_cookie.as_64 != cookie_expected.as_64
-           || dto_p->status != DAT_DTO_SUCCESS) {
-               DT_Tdep_PT_Printf(phead,
-                                 "Test Error: %s-reaping DTO problem, status = %s\n",
-                                 message,
-                                 (dto_p->status ==
-                                  DAT_DTO_SUCCESS ? "OK" : (dto_p->status ==
-                                                            DAT_DTO_FAILURE ?
-                                                            "FAILURE" :
-                                                            "LengthError")));
-               DT_Test_Error();
-               if ((ep_expected != NULL) && (dto_p->ep_handle != ep_expected)) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "\tEndPoint mismatch (got %p wanted %p)\n",
-                                         dto_p->ep_handle, ep_expected);
-               }
-               if (dto_p->transfered_length != len_expected) {
-                       DT_Tdep_PT_Printf(phead,
-                                         "\tLength mismatch (xfer 0x" F64x
-