00001
00002
00003
00004
00005
00006
00007
00015 #ifndef WIN32
00016 #include <unistd.h>
00017 #endif
00018 #include <stdlib.h>
00019
00020 #include "vipl_priv.h"
00021
00022
00023
00024
00025
00026
00027
00028
00054 VIP_RETURN
00055 vip_init_handle_set (VIP_HANDLE_SET * set_ptr,
00056 VIP_UINT32 handle_size,
00057 VIP_UINT32 max_count,
00058 VIP_UINT32 magic_number)
00059 {
00060 VIP_DEBUG_LABEL (("vip_init_handle_set"));
00061
00062 if (set_ptr == NULL)
00063 {
00064 VIP_DEBUG (("Handle Set ptr is NULL"));
00065 return VIP_INVALID_PARAMETER;
00066 }
00067
00068 if (handle_size == 0)
00069 {
00070 VIP_DEBUG (("Handle size is 0"));
00071 return VIP_INVALID_PARAMETER;
00072 }
00073
00074 if (max_count == 0)
00075 {
00076 VIP_DEBUG (("Max count is 0"));
00077 return VIP_INVALID_PARAMETER;
00078 }
00079
00080 if ((magic_number != VIP_CONN_MAGIC) && (magic_number != VIP_VI_MAGIC)
00081 && (magic_number != VIP_CQ_MAGIC) && (magic_number != VIP_MEM_MAGIC)
00082 && (magic_number != VIP_PTAG_MAGIC))
00083 {
00084 VIP_DEBUG (("Magic number is unknown"));
00085 return VIP_INVALID_PARAMETER;
00086 }
00087
00088 set_ptr->lookaside = NULL;
00089 set_ptr->lookaside = gm_create_lookaside (handle_size, 8);
00090 if (set_ptr->lookaside == NULL)
00091 {
00092 VIP_DEBUG (("Unable to allocate lookaside list"));
00093 return VIP_ERROR_RESOURCE;
00094 }
00095
00096 set_ptr->set_magic = magic_number;
00097 set_ptr->count = 0;
00098 set_ptr->max_count = max_count;
00099 set_ptr->cur_seq_num = 1;
00100 set_ptr->head = NULL;
00101 set_ptr->tail = NULL;
00102
00103 VIP_DEBUG (("Success"));
00104 return VIP_SUCCESS;
00105 }
00106
00107
00126 VIP_HANDLE *
00127 vip_allocate_handle (VIP_HANDLE_SET * set_ptr)
00128 {
00129 VIP_HANDLE *handle_ptr;
00130 VIP_DEBUG_LABEL (("vip_allocate_handle"));
00131
00132 VIP_ASSERT (set_ptr != NULL);
00133 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00134
00135 if (set_ptr->count >= set_ptr->max_count)
00136 {
00137 VIP_DEBUG (("Maximum of handles reached (%d)", set_ptr->max_count));
00138 return NULL;
00139 }
00140
00141 handle_ptr = NULL;
00142 handle_ptr = (VIP_HANDLE *) gm_lookaside_zalloc (set_ptr->lookaside);
00143 if (handle_ptr == NULL)
00144 {
00145 VIP_DEBUG (("Unable to allocate handle from lookaside list"));
00146 return NULL;
00147 }
00148 else
00149 {
00150 handle_ptr->magic = set_ptr->set_magic;
00151 handle_ptr->seq_num = set_ptr->cur_seq_num;
00152
00153 if (set_ptr->count == 0)
00154 {
00155 VIP_ASSERT (set_ptr->head == NULL);
00156 VIP_ASSERT (set_ptr->tail == NULL);
00157 set_ptr->head = handle_ptr;
00158 set_ptr->tail = handle_ptr;
00159 }
00160 else
00161 {
00162 VIP_ASSERT (set_ptr->head != NULL);
00163 VIP_ASSERT (set_ptr->tail != NULL);
00164 handle_ptr->prev = set_ptr->tail;
00165 set_ptr->tail->next = handle_ptr;
00166 set_ptr->tail = handle_ptr;
00167 }
00168
00169 handle_ptr->vip_nic_ptr = set_ptr->vip_nic_ptr;
00170 handle_ptr->ref_count = 0;
00171 set_ptr->count++;
00172 set_ptr->cur_seq_num++;
00173
00174 VIP_DEBUG (("Success"));
00175 return handle_ptr;
00176 }
00177 }
00178
00179
00198 void
00199 vip_free_handle (VIP_HANDLE_SET * set_ptr, VIP_HANDLE * handle_ptr)
00200 {
00201 VIP_DEBUG_LABEL (("vip_free_handle"));
00202
00203 VIP_ASSERT (set_ptr != NULL);
00204 VIP_ASSERT (handle_ptr != NULL);
00205 VIP_ASSERT (set_ptr->count > 0);
00206 VIP_ASSERT (handle_ptr->ref_count == 0);
00207 VIP_ASSERT (set_ptr->vip_nic_ptr = handle_ptr->vip_nic_ptr);
00208 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00209
00210 handle_ptr->magic = 0;
00211 if (handle_ptr->prev != NULL)
00212 {
00213 handle_ptr->prev->next = handle_ptr->next;
00214 }
00215 else
00216 {
00217 set_ptr->head = handle_ptr->next;
00218 }
00219 if (handle_ptr->next != NULL)
00220 {
00221 handle_ptr->next->prev = handle_ptr->prev;
00222 }
00223 else
00224 {
00225 set_ptr->tail = handle_ptr->prev;
00226 }
00227
00228 gm_lookaside_free (handle_ptr);
00229 set_ptr->count--;
00230
00231 VIP_DEBUG (("Success"));
00232 }
00233
00234
00250 void
00251 vip_destroy_conn_handle_set (VIP_HANDLE_SET * set_ptr)
00252 {
00253 VIP_CONN *vip_conn_ptr;
00254 unsigned int i;
00255 VIP_DEBUG_LABEL (("vip_destroy_conn_handle_set"));
00256
00257 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00258 VIP_ASSERT (set_ptr->set_magic == VIP_CONN_MAGIC);
00259
00260 while (set_ptr->head != NULL)
00261 {
00262 vip_conn_ptr = (VIP_CONN *) (set_ptr->head);
00263 while (vip_conn_ptr->handle.ref_count > 0)
00264 {
00265 VIP_EVENT_SIGNAL (&(vip_conn_ptr->event));
00266 VIP_MUTEX_UNLOCK (&(set_ptr->vip_nic_ptr->lock));
00267
00268 for (i = 0; i < 100; i++)
00269 {
00270 vip_millisleep (1);
00271 VIP_MUTEX_LOCK (&(set_ptr->vip_nic_ptr->lock));
00272 if (vip_conn_ptr->handle.ref_count == 0)
00273 {
00274 break;
00275 }
00276 else
00277 {
00278 VIP_ABORT (("Persistent reference despite notification"));
00279 }
00280 }
00281 }
00282
00283 vip_free_handle (set_ptr, set_ptr->head);
00284 }
00285
00286 VIP_ASSERT (set_ptr->count == 0);
00287 VIP_ASSERT (set_ptr->tail == NULL);
00288
00289 if (set_ptr->lookaside != NULL)
00290 {
00291 gm_destroy_lookaside (set_ptr->lookaside);
00292 }
00293 set_ptr->max_count = 0;
00294 set_ptr->set_magic = 0;
00295
00296 VIP_DEBUG (("Success"));
00297 }
00298
00299
00315 void
00316 vip_destroy_vi_handle_set (VIP_HANDLE_SET * set_ptr)
00317 {
00318 VIP_VI *vip_vi_ptr;
00319 unsigned int i;
00320 VIP_DEBUG_LABEL (("vip_destroy_vi_handle_set"));
00321
00322 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00323 VIP_ASSERT (set_ptr->set_magic == VIP_VI_MAGIC);
00324
00325 while (set_ptr->head != NULL)
00326 {
00327 vip_vi_ptr = (VIP_VI *) (set_ptr->head);
00328 while (vip_vi_ptr->handle.ref_count > 0)
00329 {
00330 VIP_EVENT_SIGNAL (&(vip_vi_ptr->send_queue.event));
00331 VIP_EVENT_SIGNAL (&(vip_vi_ptr->recv_queue.event));
00332 VIP_MUTEX_UNLOCK (&(set_ptr->vip_nic_ptr->lock));
00333
00334 for (i = 0; i < 100; i++)
00335 {
00336 vip_millisleep (1);
00337 VIP_MUTEX_LOCK (&(set_ptr->vip_nic_ptr->lock));
00338 if (vip_vi_ptr->handle.ref_count == 0)
00339 {
00340 break;
00341 }
00342 else
00343 {
00344 VIP_ABORT (("Persistent reference despite notification"));
00345 }
00346 }
00347 }
00348
00349
00350 if (vip_vi_ptr->send_queue.vip_cq_ptr != NULL)
00351 {
00352 vip_vi_ptr->send_queue.vip_cq_ptr->handle.ref_count--;
00353 }
00354
00355
00356 if (vip_vi_ptr->recv_queue.vip_cq_ptr != NULL)
00357 {
00358 vip_vi_ptr->recv_queue.vip_cq_ptr->handle.ref_count--;
00359 }
00360
00361
00362 vip_vi_ptr->vip_ptag_ptr->handle.ref_count--;
00363
00364
00365 vip_free_handle (set_ptr, set_ptr->head);
00366 }
00367
00368 VIP_ASSERT (set_ptr->count == 0);
00369 VIP_ASSERT (set_ptr->tail == NULL);
00370
00371 if (set_ptr->lookaside != NULL)
00372 {
00373 gm_destroy_lookaside (set_ptr->lookaside);
00374 }
00375 set_ptr->max_count = 0;
00376 set_ptr->set_magic = 0;
00377
00378 VIP_DEBUG (("Success"));
00379 }
00380
00381
00397 void
00398 vip_destroy_cq_handle_set (VIP_HANDLE_SET * set_ptr)
00399 {
00400 VIP_CQ *vip_cq_ptr;
00401 unsigned int i;
00402 VIP_DEBUG_LABEL (("vip_destroy_cq_handle_set"));
00403
00404 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00405 VIP_ASSERT (set_ptr->set_magic == VIP_CQ_MAGIC);
00406
00407 while (set_ptr->head != NULL)
00408 {
00409 vip_cq_ptr = (VIP_CQ *) (set_ptr->head);
00410 if (vip_cq_ptr->handle.ref_count > 0)
00411 {
00412 VIP_EVENT_SIGNAL (&(vip_cq_ptr->event));
00413 VIP_MUTEX_UNLOCK (&(set_ptr->vip_nic_ptr->lock));
00414
00415 for (i = 0; i < 100; i++)
00416 {
00417 vip_millisleep (1);
00418 VIP_MUTEX_LOCK (&(set_ptr->vip_nic_ptr->lock));
00419 if (vip_cq_ptr->handle.ref_count == 0)
00420 {
00421 break;
00422 }
00423 else
00424 {
00425 VIP_ABORT (("Persistent reference despite notification"));
00426 }
00427 }
00428 }
00429
00430
00431 vip_free_handle (set_ptr, set_ptr->head);
00432 }
00433
00434 VIP_ASSERT (set_ptr->count == 0);
00435 VIP_ASSERT (set_ptr->tail == NULL);
00436
00437 if (set_ptr->lookaside != NULL)
00438 {
00439 gm_destroy_lookaside (set_ptr->lookaside);
00440 }
00441 set_ptr->max_count = 0;
00442 set_ptr->set_magic = 0;
00443
00444 VIP_DEBUG (("Success"));
00445 }
00446
00447
00463 void
00464 vip_destroy_mem_handle_set (VIP_HANDLE_SET * set_ptr)
00465 {
00466 VIP_DEBUG_LABEL (("vip_destroy_mem_handle_set"));
00467
00468 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00469 VIP_ASSERT (set_ptr->set_magic == VIP_MEM_MAGIC);
00470
00471 while (set_ptr->head != NULL)
00472 {
00473 if (set_ptr->head->ref_count > 0)
00474 {
00475 VIP_ABORT (("MEM reference count is > 0, prevent destruction"));
00476 }
00477
00478
00479 ((VIP_MEM *) set_ptr->head)->vip_ptag_ptr->handle.ref_count--;
00480
00481
00482 vip_free_handle (set_ptr, set_ptr->head);
00483 }
00484
00485 VIP_ASSERT (set_ptr->count == 0);
00486 VIP_ASSERT (set_ptr->tail == NULL);
00487
00488 if (set_ptr->lookaside != NULL)
00489 {
00490 gm_destroy_lookaside (set_ptr->lookaside);
00491 }
00492 set_ptr->max_count = 0;
00493 set_ptr->set_magic = 0;
00494
00495 VIP_DEBUG (("Success"));
00496 }
00497
00498
00514 void
00515 vip_destroy_ptag_handle_set (VIP_HANDLE_SET * set_ptr)
00516 {
00517 VIP_DEBUG_LABEL (("vip_destroy_ptag_handle_set"));
00518
00519 VIP_ASSERT_MUTEX_LOCKED (&(set_ptr->vip_nic_ptr->lock));
00520 VIP_ASSERT (set_ptr->set_magic == VIP_PTAG_MAGIC);
00521
00522 while (set_ptr->head != NULL)
00523 {
00524 if (set_ptr->head->ref_count > 0)
00525 {
00526 VIP_ABORT (("PTAG reference count is > 0, prevent destruction"));
00527 }
00528
00529
00530 vip_free_handle (set_ptr, set_ptr->head);
00531 }
00532
00533 VIP_ASSERT (set_ptr->count == 0);
00534 VIP_ASSERT (set_ptr->tail == NULL);
00535
00536 if (set_ptr->lookaside != NULL)
00537 {
00538 gm_destroy_lookaside (set_ptr->lookaside);
00539 }
00540 set_ptr->max_count = 0;
00541 set_ptr->set_magic = 0;
00542
00543 VIP_DEBUG (("Success"));
00544 }
00545
00559 VIP_BOOLEAN
00560 vip_is_conn_notified (VIP_PVOID ptr)
00561 {
00562 VIP_CONN *vip_conn_ptr;
00563
00564 vip_conn_ptr = (VIP_CONN *) ptr;
00565 if (vip_conn_ptr->status != VIP_NOT_DONE)
00566 {
00567 return VIP_TRUE;
00568 }
00569 else
00570 {
00571 return VIP_FALSE;
00572 }
00573 }
00574
00591 VIP_BOOLEAN
00592 vip_is_first_desc_notified (VIP_PVOID ptr)
00593 {
00594 VIP_VI_QUEUE *vip_vi_queue_ptr;
00595
00596 vip_vi_queue_ptr = (VIP_VI_QUEUE *) ptr;
00597 if ((vip_vi_queue_ptr->first->CS.Status & VIP_STATUS_DONE) != 0)
00598 {
00599 return VIP_TRUE;
00600 }
00601 else
00602 {
00603 return VIP_FALSE;
00604 }
00605 }
00606
00623 VIP_BOOLEAN
00624 vip_is_first_cq_entry_notified (VIP_PVOID ptr)
00625 {
00626 VIP_CQ *vip_cq_ptr;
00627
00628 vip_cq_ptr = (VIP_CQ *) ptr;
00629 if (vip_cq_ptr->queue[vip_cq_ptr->next_poll].completed == VIP_TRUE)
00630 {
00631 return VIP_TRUE;
00632 }
00633 else
00634 {
00635 return VIP_FALSE;
00636 }
00637 }
00638
00639
00655 void *
00656 vip_send_notify_thread (void *arg)
00657 {
00658 VIP_VI *vip_vi_ptr;
00659 VIP_NIC *vip_nic_ptr;
00660 VIP_PVOID context;
00661 VIP_NOTIFY *vip_notify_ptr;
00662 VIP_DESCRIPTOR *vip_desc_ptr;
00663 void (*fct) (VIP_PVOID, VIP_NIC_HANDLE, VIP_VI_HANDLE, VIP_DESCRIPTOR *);
00664 VIP_DEBUG_LABEL (("vip_send_notify_thread"));
00665
00666 vip_vi_ptr = (VIP_VI *) arg;
00667 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00668
00669 while (1)
00670 {
00671 VIP_SEMAPHORE_WAIT (&(vip_vi_ptr->send_queue.notify_tokens));
00672
00673
00674 if (vip_vi_ptr->send_queue.notify_cancelled == VIP_TRUE)
00675 {
00676 VIP_THREAD_EXIT (0);
00677 }
00678
00679 VIP_DEBUG (("Process a pending send notify handle"));
00680 vip_desc_ptr = NULL;
00681 switch (VipSendWait (vip_vi_ptr, VIP_INFINITE, &vip_desc_ptr))
00682 {
00683 case VIP_SUCCESS:
00684 case VIP_DESCRIPTOR_ERROR:
00685 VIP_MUTEX_LOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00686 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00687 vip_notify_ptr = vip_vi_ptr->send_queue.first_notify_handler;
00688 VIP_ASSERT (vip_notify_ptr != NULL);
00689
00690
00691 vip_vi_ptr->send_queue.first_notify_handler = vip_notify_ptr->next;
00692 if (vip_vi_ptr->send_queue.last_notify_handler == vip_notify_ptr)
00693 {
00694 VIP_ASSERT (vip_vi_ptr->send_queue.first_notify_handler ==
00695 NULL);
00696 vip_vi_ptr->send_queue.last_notify_handler = NULL;
00697 }
00698
00699 fct = vip_notify_ptr->handler;
00700 context = vip_notify_ptr->context;
00701
00702
00703 gm_lookaside_free (vip_notify_ptr);
00704
00705 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00706 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00707
00708
00709 (*fct) (context, vip_nic_ptr, vip_vi_ptr, vip_desc_ptr);
00710 break;
00711
00712 default:
00713
00714 if (vip_vi_ptr->send_queue.notify_cancelled == VIP_TRUE)
00715 {
00716 VIP_THREAD_EXIT (0);
00717 }
00718 else
00719 {
00720 VIP_ABORT (("Internal error"));
00721 }
00722 }
00723 }
00724 }
00725
00726
00742 void *
00743 vip_recv_notify_thread (void *arg)
00744 {
00745 VIP_VI *vip_vi_ptr;
00746 VIP_NIC *vip_nic_ptr;
00747 VIP_PVOID context;
00748 VIP_NOTIFY *vip_notify_ptr;
00749 VIP_DESCRIPTOR *vip_desc_ptr;
00750 void (*fct) (VIP_PVOID, VIP_NIC_HANDLE, VIP_VI_HANDLE, VIP_DESCRIPTOR *);
00751 VIP_DEBUG_LABEL (("vip_recv_notify_thread"));
00752
00753 vip_vi_ptr = (VIP_VI *) arg;
00754 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00755
00756 while (1)
00757 {
00758 VIP_SEMAPHORE_WAIT (&(vip_vi_ptr->recv_queue.notify_tokens));
00759
00760
00761 if (vip_vi_ptr->recv_queue.notify_cancelled == VIP_TRUE)
00762 {
00763 VIP_THREAD_EXIT (0);
00764 }
00765
00766 VIP_DEBUG (("Process a pending recv notify handle"));
00767 vip_desc_ptr = NULL;
00768 switch (VipRecvWait (vip_vi_ptr, VIP_INFINITE, &vip_desc_ptr))
00769 {
00770 case VIP_SUCCESS:
00771 case VIP_DESCRIPTOR_ERROR:
00772 VIP_MUTEX_LOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00773 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00774 vip_notify_ptr = vip_vi_ptr->recv_queue.first_notify_handler;
00775 VIP_ASSERT (vip_notify_ptr != NULL);
00776
00777
00778 vip_vi_ptr->recv_queue.first_notify_handler = vip_notify_ptr->next;
00779 if (vip_vi_ptr->recv_queue.last_notify_handler == vip_notify_ptr)
00780 {
00781 VIP_ASSERT (vip_vi_ptr->recv_queue.first_notify_handler ==
00782 NULL);
00783 vip_vi_ptr->recv_queue.last_notify_handler = NULL;
00784 }
00785
00786 fct = vip_notify_ptr->handler;
00787 context = vip_notify_ptr->context;
00788
00789
00790 gm_lookaside_free (vip_notify_ptr);
00791
00792 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00793 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00794
00795
00796 (*fct) (context, vip_nic_ptr, vip_vi_ptr, vip_desc_ptr);
00797 break;
00798
00799 default:
00800
00801 if (vip_vi_ptr->recv_queue.notify_cancelled == VIP_TRUE)
00802 {
00803 VIP_THREAD_EXIT (0);
00804 }
00805 else
00806 {
00807 VIP_ABORT (("Internal error"));
00808 }
00809 }
00810 }
00811 }
00812
00813
00829 void *
00830 vip_cq_notify_thread (void *arg)
00831 {
00832 VIP_CQ *vip_cq_ptr;
00833 VIP_NIC *vip_nic_ptr;
00834 VIP_PVOID context;
00835 VIP_VI_HANDLE vip_vi_handle;
00836 VIP_NOTIFY *vip_notify_ptr;
00837 VIP_BOOLEAN recv_queue;
00838 void (*fct) (VIP_PVOID, VIP_NIC_HANDLE, VIP_VI_HANDLE, VIP_BOOLEAN);
00839 VIP_DEBUG_LABEL (("vip_cq_notify_thread"));
00840
00841 vip_cq_ptr = (VIP_CQ *) arg;
00842 vip_nic_ptr = vip_cq_ptr->handle.vip_nic_ptr;
00843
00844 while (1)
00845 {
00846 VIP_SEMAPHORE_WAIT (&(vip_cq_ptr->notify_tokens));
00847
00848
00849 if (vip_cq_ptr->notify_cancelled == VIP_TRUE)
00850 {
00851 VIP_THREAD_EXIT (0);
00852 }
00853
00854 VIP_DEBUG (("Process a pending CQ notify handle"));
00855 if (VipCQWait (vip_cq_ptr, VIP_INFINITE, &vip_vi_handle,
00856 &recv_queue) != VIP_SUCCESS)
00857 {
00858
00859 if (vip_cq_ptr->notify_cancelled == VIP_TRUE)
00860 {
00861 VIP_THREAD_EXIT (0);
00862 }
00863 else
00864 {
00865 VIP_ABORT (("Internal error"));
00866 }
00867 }
00868
00869 VIP_MUTEX_LOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00870 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00871 vip_notify_ptr = vip_cq_ptr->first_notify_handler;
00872 VIP_ASSERT (vip_notify_ptr != NULL);
00873
00874
00875 vip_cq_ptr->first_notify_handler = vip_notify_ptr->next;
00876 if (vip_cq_ptr->last_notify_handler == vip_notify_ptr)
00877 {
00878 VIP_ASSERT (vip_cq_ptr->first_notify_handler == NULL);
00879 vip_cq_ptr->last_notify_handler = NULL;
00880 }
00881
00882 fct = vip_notify_ptr->handler;
00883 context = vip_notify_ptr->context;
00884
00885
00886 gm_lookaside_free (vip_notify_ptr);
00887
00888 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00889 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->vip_gm_ptr->lock));
00890
00891
00892 (*fct) (context, vip_nic_ptr, vip_vi_handle, recv_queue);
00893 }
00894 }