Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

vipl_priv_handles.c

Go to the documentation of this file.
00001 /********************************************************
00002  * Myricom VI-GM  networking software and documentation *
00003  * Copyright (c) 2001 by Myricom, Inc.                  *
00004  * All rights reserved.                                 *
00005  * See the file `COPYING' for copyright notice.         *
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 /*   handle sets   */
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       /* decrease send CQ reference counter if needed */
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       /* decrease recv CQ reference counter if needed */
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       /* decrease ptag reference counter */
00362       vip_vi_ptr->vip_ptag_ptr->handle.ref_count--;
00363 
00364       /* free the handle */
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       /* free the handle */
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       /* decrease ptag reference counter */
00479       ((VIP_MEM *) set_ptr->head)->vip_ptag_ptr->handle.ref_count--;
00480 
00481       /* free the handle */
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       /* free the handle */
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       /* test if the notify thread should be cancelled */
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           /* remove the notify handle from the pending list */
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           /* release the notify structure */
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           /* execute the send notify handler */
00709           (*fct) (context, vip_nic_ptr, vip_vi_ptr, vip_desc_ptr);
00710           break;
00711 
00712         default:
00713           /* test if the notify thread should be cancelled */
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       /* test if the notify thread should be cancelled */
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           /* remove the notify handle from the pending list */
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           /* release the notify structure */
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           /* execute the recv notify handler */
00796           (*fct) (context, vip_nic_ptr, vip_vi_ptr, vip_desc_ptr);
00797           break;
00798 
00799         default:
00800           /* test if the notify thread should be cancelled */
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       /* test if the notify thread should be cancelled */
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           /* test if the notify thread should be cancelled */
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       /* remove the notify handle from the pending list */
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       /* release the notify structure */
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       /* execute the cq notify handler */
00892       (*fct) (context, vip_nic_ptr, vip_vi_handle, recv_queue);
00893     }
00894 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.