
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 00013 #include <stdlib.h> 00014 00015 #include "vipl_priv.h" 00016 00017 00069 VIP_ENTRY_POINT VIP_RETURN 00070 VipCQWait (VIP_CQ_HANDLE CQHandle, 00071 VIP_ULONG Timeout, 00072 VIP_VI_HANDLE * ViHandle, VIP_BOOLEAN * RecvQueue) 00073 { 00074 VIP_CQ *vip_cq_ptr; 00075 VIP_GM *vip_gm_ptr; 00076 VIP_NIC *vip_nic_ptr; 00077 VIP_RETURN vip_status; 00078 VIP_CQ_ENTRY *vip_cq_entry_ptr; 00079 VIP_DEBUG_LABEL (("VipCQWait")); 00080 00081 /* check CQ handle */ 00082 vip_cq_ptr = (VIP_CQ *) CQHandle; 00083 if (VIP_INVALID_CQ_HANDLE (vip_cq_ptr)) 00084 { 00085 VIP_DEBUG (("Invalid CQ handle")); 00086 return VIP_INVALID_PARAMETER; 00087 } 00088 vip_nic_ptr = vip_cq_ptr->handle.vip_nic_ptr; 00089 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr; 00090 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock)); 00091 VIP_PROGRESSION (vip_gm_ptr); 00092 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock)); 00093 00094 /* check if first entry is complete */ 00095 VIP_ASSERT (vip_cq_ptr->next_poll < vip_cq_ptr->count); 00096 vip_cq_entry_ptr = &(vip_cq_ptr->queue[vip_cq_ptr->next_poll]); 00097 if ((vip_cq_ptr->event_count > 0) 00098 || (vip_cq_entry_ptr->completed == VIP_FALSE)) 00099 { 00100 VIP_DEBUG (("First Completion Queue entry is not complete, blocks...")); 00101 00102 /* blocks */ 00103 vip_cq_ptr->event_count++; 00104 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00105 vip_status = 00106 vip_wait_for_notification (Timeout, 00107 (VIP_HANDLE *) vip_cq_ptr, 00108 &(vip_cq_ptr->event), 00109 vip_is_first_cq_entry_notified, 00110 vip_cq_ptr); 00111 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock)); 00112 vip_cq_ptr->event_count--; 00113 00114 /* check return code of blocking wait */ 00115 switch (vip_status) 00116 { 00117 case VIP_SUCCESS: 00118 /* Completed by the entry may have changed */ 00119 vip_cq_entry_ptr = &(vip_cq_ptr->queue[vip_cq_ptr->next_poll]); 00120 VIP_ASSERT (vip_cq_entry_ptr->completed == VIP_TRUE); 00121 break; 00122 00123 case VIP_INVALID_PARAMETER: 00124 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00125 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00126 return VIP_INVALID_PARAMETER; 00127 00128 case VIP_TIMEOUT: 00129 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00130 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00131 return VIP_TIMEOUT; 00132 00133 default: 00134 VIP_ABORT (("Blocking wait return code is invalid")); 00135 } 00136 } 00137 00138 /* dequeue the completion queue entry */ 00139 if ((vip_cq_ptr->next_poll + 1) < vip_cq_ptr->count) 00140 { 00141 vip_cq_ptr->next_poll++; 00142 } 00143 else 00144 { 00145 vip_cq_ptr->next_poll = 0; 00146 } 00147 00148 /* return usefull information */ 00149 00150 VIP_ASSERT (vip_cq_entry_ptr->vip_vi_ptr != NULL); 00151 *ViHandle = (VIP_VI_HANDLE) (vip_cq_entry_ptr->vip_vi_ptr); 00152 *RecvQueue = vip_cq_entry_ptr->recv_queue; 00153 00154 /* invalid the cq entry */ 00155 vip_cq_entry_ptr->vip_vi_ptr = NULL; 00156 vip_cq_entry_ptr->completed = VIP_FALSE; 00157 00158 VIP_DEBUG (("Success")); 00159 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00160 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00161 return VIP_SUCCESS; 00162 }
1.4.4.