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

vipsendnotify.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 
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 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.