
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 "vipl_priv.h" 00014 00073 VIP_ENTRY_POINT VIP_RETURN 00074 VipSendNotify (VIP_VI_HANDLE ViHandle, 00075 VIP_PVOID Context, 00076 void (*Handler) (VIP_PVOID Context, 00077 VIP_NIC_HANDLE NicHandle, 00078 VIP_VI_HANDLE ViHandle, 00079 VIP_DESCRIPTOR * DescriptorPtr)) 00080 { 00081 VIP_GM *vip_gm_ptr; 00082 VIP_VI *vip_vi_ptr; 00083 VIP_NIC *vip_nic_ptr; 00084 VIP_NOTIFY *vip_notify_ptr; 00085 VIP_VI_QUEUE *vip_vi_queue_ptr; 00086 VIP_DEBUG_LABEL (("VipSendNotify")); 00087 00088 /* check VI handle */ 00089 vip_vi_ptr = (VIP_VI *) ViHandle; 00090 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr)) 00091 { 00092 VIP_DEBUG (("Invalid VI handle")); 00093 return VIP_INVALID_PARAMETER; 00094 } 00095 00096 /* check Handler address */ 00097 if (Handler == NULL) 00098 { 00099 VIP_DEBUG (("Notify handler is null")); 00100 return VIP_INVALID_PARAMETER; 00101 } 00102 00103 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr; 00104 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr; 00105 vip_vi_queue_ptr = &(vip_vi_ptr->send_queue); 00106 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock)); 00107 VIP_PROGRESSION (vip_gm_ptr); 00108 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock)); 00109 00110 /* check if send queue associated with completion queue */ 00111 if (vip_vi_queue_ptr->vip_cq_ptr != NULL) 00112 { 00113 VIP_DEBUG (("VI send queue is associated with a completion queue")); 00114 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00115 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00116 return VIP_ERROR_RESOURCE; 00117 } 00118 00119 /* check if send queue empty */ 00120 if (vip_vi_queue_ptr->total_count == 0) 00121 { 00122 VIP_DEBUG (("VI send queue is empty")); 00123 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00124 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00125 return VIP_DESCRIPTOR_ERROR; 00126 } 00127 00128 /* create the notify thread if needed */ 00129 if (vip_vi_queue_ptr->notify_initialized == VIP_FALSE) 00130 { 00131 if (VIP_THREAD_CREATE (&(vip_vi_queue_ptr->notify_thread), 00132 vip_send_notify_thread, vip_vi_ptr) != 0) 00133 { 00134 VIP_DEBUG (("Unable to spawn send notify thread")); 00135 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00136 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00137 return VIP_ERROR_RESOURCE; 00138 } 00139 00140 vip_vi_queue_ptr->notify_initialized = VIP_TRUE; 00141 } 00142 00143 /* alloc a notify handle */ 00144 vip_notify_ptr = 00145 (VIP_NOTIFY *) gm_lookaside_alloc (vip_gm_ptr->notify_lookaside); 00146 if (vip_notify_ptr == NULL) 00147 { 00148 VIP_DEBUG (("Error allocating notify handler")); 00149 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00150 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00151 return VIP_ERROR_RESOURCE; 00152 } 00153 00154 /* fill the notify handle */ 00155 vip_notify_ptr->handler = Handler; 00156 vip_notify_ptr->context = Context; 00157 vip_notify_ptr->next = NULL; 00158 00159 /* insert it in the pending list */ 00160 if (vip_vi_queue_ptr->first_notify_handler == NULL) 00161 { 00162 VIP_ASSERT (vip_vi_queue_ptr->last_notify_handler == NULL); 00163 vip_vi_queue_ptr->first_notify_handler = vip_notify_ptr; 00164 vip_vi_queue_ptr->last_notify_handler = vip_notify_ptr; 00165 } 00166 else 00167 { 00168 VIP_ASSERT (vip_vi_queue_ptr->last_notify_handler != NULL); 00169 vip_vi_queue_ptr->last_notify_handler->next = vip_notify_ptr; 00170 vip_vi_queue_ptr->last_notify_handler = vip_notify_ptr; 00171 } 00172 00173 /* acknoledge the new notify handler by giving a token to the thread. */ 00174 VIP_SEMAPHORE_POST (&(vip_vi_queue_ptr->notify_tokens)); 00175 00176 VIP_DEBUG (("Success")); 00177 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00178 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00179 return VIP_SUCCESS; 00180 }
1.4.4.