Пример #1
0
int
osm_db_guid2lid_guids(IN osm_db_domain_t * const p_g2l,
		      OUT cl_qlist_t * p_guid_list)
{
	char *p_key;
	cl_list_t keys;
	osm_db_guid_elem_t *p_guid_elem;

	cl_list_construct(&keys);
	cl_list_init(&keys, 10);

	if (osm_db_keys(p_g2l, &keys))
		return 1;

	while ((p_key = cl_list_remove_head(&keys)) != NULL) {
		p_guid_elem =
		    (osm_db_guid_elem_t *) malloc(sizeof(osm_db_guid_elem_t));
		CL_ASSERT(p_guid_elem != NULL);

		p_guid_elem->guid = __osm_unpack_guid(p_key);
		cl_qlist_insert_head(p_guid_list, &p_guid_elem->item);
	}

	cl_list_destroy(&keys);
	return 0;
}
Пример #2
0
cl_status_t
cl_timer_start(IN cl_timer_t * const p_timer, IN const uint32_t time_ms)
{
	struct timeval curtime;
	cl_list_item_t *p_list_item;
	uint32_t delta_time = time_ms;

	CL_ASSERT(p_timer);
	CL_ASSERT(p_timer->state == CL_INITIALIZED);

	pthread_mutex_lock(&gp_timer_prov->mutex);
	/* Signal the timer provider thread to wake up. */
	pthread_cond_signal(&gp_timer_prov->cond);

	/* Remove the timer from the queue if currently queued. */
	if (p_timer->timer_state == CL_TIMER_QUEUED)
		cl_qlist_remove_item(&gp_timer_prov->queue,
				     &p_timer->list_item);

	/* Get the current time */
#ifndef timerclear
#define	timerclear(tvp)		(tvp)->tv_sec = (time_t)0, (tvp)->tv_usec = 0L
#endif
	timerclear(&curtime);
	gettimeofday(&curtime, NULL);

	/* do not do 0 wait ! */
	/* if (delta_time < 1000.0) {delta_time = 1000;} */

	/* Calculate the timeout. */
	p_timer->timeout.tv_sec = curtime.tv_sec + (delta_time / 1000);
	p_timer->timeout.tv_nsec =
	    (curtime.tv_usec + ((delta_time % 1000) * 1000)) * 1000;

	/* Add the timer to the queue. */
	if (cl_is_qlist_empty(&gp_timer_prov->queue)) {
		/* The timer list is empty.  Add to the head. */
		cl_qlist_insert_head(&gp_timer_prov->queue,
				     &p_timer->list_item);
	} else {
		/* Find the correct insertion place in the list for the timer. */
		p_list_item = cl_qlist_find_from_tail(&gp_timer_prov->queue,
						      __cl_timer_find, p_timer);

		/* Insert the timer. */
		cl_qlist_insert_next(&gp_timer_prov->queue, p_list_item,
				     &p_timer->list_item);
	}
	/* Set the state. */
	p_timer->timer_state = CL_TIMER_QUEUED;
	pthread_mutex_unlock(&gp_timer_prov->mutex);

	return (CL_SUCCESS);
}
Пример #3
0
osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,
		IN osm_bind_info_t * const p_osm_bind_info,
		IN osm_mad_pool_t * const p_mad_pool,
		IN osm_vend_mad_recv_callback_t mad_recv_callback,
		IN void *context)
{
	cl_status_t cl_status;
	FSTATUS Status;		/*  GEN1 Status for Umadt */

	mad_bind_info_t *p_mad_bind_info;
	RegisterClassStruct *p_umadt_reg_class;

	umadt_obj_t *p_umadt_obj;
	OSM_LOG_ENTER(((umadt_obj_t *) p_vend)->p_log);

	CL_ASSERT(p_vend);

	p_umadt_obj = (umadt_obj_t *) p_vend;

	/*  Sanity check */
	CL_ASSERT(p_umadt_obj->init_done);
	CL_ASSERT(p_osm_bind_info);
	CL_ASSERT(p_mad_pool);
	CL_ASSERT(mad_recv_callback);

	/*  Allocate memory for registering the handle. */
	p_mad_bind_info = (mad_bind_info_t *) malloc(sizeof(*p_mad_bind_info));
	if (p_mad_bind_info) {
		memset(p_mad_bind_info, 0, sizeof(*p_mad_bind_info));
		p_umadt_reg_class = &p_mad_bind_info->umadt_reg_class;
	}
	p_umadt_reg_class->PortGuid = cl_ntoh64(p_osm_bind_info->port_guid);
	p_umadt_reg_class->ClassId = p_osm_bind_info->mad_class;
	p_umadt_reg_class->ClassVersion = p_osm_bind_info->class_version;
	p_umadt_reg_class->isResponder = p_osm_bind_info->is_responder;
	p_umadt_reg_class->isTrapProcessor = p_osm_bind_info->is_trap_processor;
	p_umadt_reg_class->isReportProcessor =
	    p_osm_bind_info->is_report_processor;
	p_umadt_reg_class->SendQueueSize = p_osm_bind_info->send_q_size;
	p_umadt_reg_class->RecvQueueSize = p_osm_bind_info->recv_q_size;
	p_umadt_reg_class->NotifySendCompletion = TRUE;

	p_mad_bind_info->p_umadt_obj = p_umadt_obj;
	p_mad_bind_info->p_mad_pool = p_mad_pool;
	p_mad_bind_info->mad_recv_callback = mad_recv_callback;
	p_mad_bind_info->client_context = context;

	/*  register with Umadt for MAD interface */
	Status = p_umadt_obj->uMadtInterface.uMadtRegister(p_umadt_reg_class,
							   &p_mad_bind_info->
							   umadt_handle);
	if (Status != FSUCCESS) {
		free(p_mad_bind_info);
		OSM_LOG_EXIT(p_umadt_obj->p_log);
		return (OSM_BIND_INVALID_HANDLE);
	}
	CL_ASSERT(p_mad_bind_info->umadt_handle);
	/*  */
	/*  Start a worker thread to process receives. */
	/*  */
	cl_thread_construct(&p_mad_bind_info->recv_processor_thread);
	cl_status = cl_thread_init(&p_mad_bind_info->recv_processor_thread,
				   __mad_recv_processor,
				   (void *)p_mad_bind_info, "mad_recv_worker");
	CL_ASSERT(cl_status == CL_SUCCESS);

	cl_qlist_init(&p_mad_bind_info->trans_ctxt_list);
	cl_spinlock_construct(&p_mad_bind_info->trans_ctxt_lock);
	cl_spinlock_init(&p_mad_bind_info->trans_ctxt_lock);
	cl_spinlock_construct(&p_mad_bind_info->timeout_list_lock);
	cl_spinlock_init(&p_mad_bind_info->timeout_list_lock);

	cl_status = cl_timer_init(&p_mad_bind_info->timeout_timer,
				  __osm_vendor_timer_callback,
				  (void *)p_mad_bind_info);
	CL_ASSERT(cl_status == CL_SUCCESS);
	cl_qlist_init(&p_mad_bind_info->timeout_list);
	/*  */
	/*  Insert the mad_reg_struct in list and return pointer to it as the handle */
	/*  */
	cl_spinlock_acquire(&p_umadt_obj->register_lock);

	cl_qlist_insert_head(&p_umadt_obj->register_list,
			     &p_mad_bind_info->list_item);

	cl_spinlock_release(&p_umadt_obj->register_lock);

	/*
	   A timeout value of 0 means disable timeouts.
	 */
	if (p_umadt_obj->timeout) {
		cl_timer_start(&p_mad_bind_info->timeout_timer,
			       DEFAULT_TIMER_INTERVAL_MSEC);
	}

	OSM_LOG_EXIT(p_umadt_obj->p_log);
	return ((osm_bind_handle_t) p_mad_bind_info);
}
Пример #4
0
cl_status_t cl_qcpool_grow(IN cl_qcpool_t * const p_pool, IN size_t obj_count)
{
	cl_status_t status = CL_SUCCESS;
	uint8_t *p_objects;
	cl_pool_item_t *p_pool_item;
	uint32_t i;
	size_t obj_size;

	CL_ASSERT(p_pool);
	CL_ASSERT(p_pool->state == CL_INITIALIZED);
	CL_ASSERT(obj_count);

	/* Validate that growth is possible. */
	if (p_pool->num_objects == p_pool->max_objects)
		return (CL_INSUFFICIENT_MEMORY);

	/* Cap the growth to the desired maximum. */
	if (obj_count > (p_pool->max_objects - p_pool->num_objects))
		obj_count = p_pool->max_objects - p_pool->num_objects;

	/* Calculate the size of an object. */
	obj_size = 0;
	for (i = 0; i < p_pool->num_components; i++)
		obj_size += p_pool->component_sizes[i];

	/* Allocate the buffer for the new objects. */
	p_objects = (uint8_t *)
	    malloc(sizeof(cl_list_item_t) + (obj_size * obj_count));

	/* Make sure the allocation succeeded. */
	if (!p_objects)
		return (CL_INSUFFICIENT_MEMORY);
	else
		memset(p_objects, 0,
		       sizeof(cl_list_item_t) + (obj_size * obj_count));

	/* Insert the allocation in our list. */
	cl_qlist_insert_tail(&p_pool->alloc_list, (cl_list_item_t *) p_objects);
	p_objects += sizeof(cl_list_item_t);

	/* initialize the new elements and add them to the free list */
	while (obj_count--) {
		/* Setup the array of components for the current object. */
		p_pool->p_components[0] = p_objects;
		for (i = 1; i < p_pool->num_components; i++) {
			/* Calculate the pointer to the next component. */
			p_pool->p_components[i] =
			    (uint8_t *) p_pool->p_components[i - 1] +
			    p_pool->component_sizes[i - 1];
		}

		/*
		 * call the user's initializer
		 * this can fail!
		 */
		if (p_pool->pfn_init) {
			p_pool_item = NULL;
			status = p_pool->pfn_init(p_pool->p_components,
						  p_pool->num_components,
						  (void *)p_pool->context,
						  &p_pool_item);
			if (status != CL_SUCCESS) {
				/*
				 * User initialization failed
				 * we may have only grown the pool by some partial amount
				 * Invoke the destructor for the object that failed
				 * initialization.
				 */
				if (p_pool->pfn_dtor)
					p_pool->pfn_dtor(p_pool_item,
							 (void *)p_pool->
							 context);

				/* Return the user's status. */
				return (status);
			}
			CL_ASSERT(p_pool_item);
		} else {
			/*
			 * If no initializer is provided, assume that the pool item
			 * is stored at the beginning of the first component.
			 */
			p_pool_item =
			    (cl_pool_item_t *) p_pool->p_components[0];
		}

#ifdef _DEBUG_
		/*
		 * Set the pool item's pool pointer to this pool so that we can
		 * check that items get returned to the correct pool.
		 */
		p_pool_item->p_pool = p_pool;
#endif

		/* Insert the new item in the free list, traping for failure. */
		cl_qlist_insert_head(&p_pool->free_list,
				     &p_pool_item->list_item);

		p_pool->num_objects++;

		/* move the pointer to the next item */
		p_objects += obj_size;
	}

	return (status);
}
Пример #5
0
osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,
		IN osm_bind_info_t * const p_bind_info,
		IN osm_mad_pool_t * const p_mad_pool,
		IN osm_vend_mad_recv_callback_t mad_recv_callback,
		IN osm_vend_mad_send_err_callback_t send_err_callback,
		IN void *context)
{
	osmv_bind_obj_t *p_bo;
	ib_api_status_t status;
	char hca_id[32];
	cl_status_t cl_st;
	cl_list_obj_t *p_obj;
	uint8_t hca_index;

	if (NULL == p_vend || NULL == p_bind_info || NULL == p_mad_pool
	    || NULL == mad_recv_callback || NULL == send_err_callback) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7302: "
			"NULL parameter passed in: p_vend=%p p_bind_info=%p p_mad_pool=%p recv_cb=%p send_err_cb=%p\n",
			p_vend, p_bind_info, p_mad_pool, mad_recv_callback,
			send_err_callback);

		return OSM_BIND_INVALID_HANDLE;
	}

	p_bo = malloc(sizeof(osmv_bind_obj_t));
	if (NULL == p_bo) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7303: could not allocate the bind object\n");
		return OSM_BIND_INVALID_HANDLE;
	}

	memset(p_bo, 0, sizeof(osmv_bind_obj_t));
	p_bo->p_vendor = p_vend;
	p_bo->recv_cb = mad_recv_callback;
	p_bo->send_err_cb = send_err_callback;
	p_bo->cb_context = context;
	p_bo->p_osm_pool = p_mad_pool;

	/* obtain the hca name and port num from the guid */
	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"osm_vendor_bind: "
		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
		cl_ntoh64(p_bind_info->port_guid));

	status = osm_vendor_get_guid_ca_and_port(p_bo->p_vendor,
						 p_bind_info->port_guid,
						 &(p_bo->hca_hndl),
						 hca_id,
						 &hca_index, &(p_bo->port_num));
	if (status != IB_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7304: "
			"Fail to find port number of port guid:0x%016" PRIx64
			"\n", p_bind_info->port_guid);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* Initialize the magic_ptr to the pointer of the p_bo info.
	   This will be used to signal when the object is being destroyed, so no
	   real action will be done then. */
	p_bo->magic_ptr = p_bo;

	p_bo->is_closing = FALSE;

	cl_spinlock_construct(&(p_bo->lock));
	cl_st = cl_spinlock_init(&(p_bo->lock));
	if (cl_st != CL_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7305: "
			"could not initialize the spinlock ...\n");
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"osm_vendor_bind: osmv_txnmgr_init ... \n");
	if (osmv_txnmgr_init(&p_bo->txn_mgr, p_vend->p_log, &(p_bo->lock)) !=
	    IB_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7306: "
			"osmv_txnmgr_init failed \n");
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* Do the real job! (Transport-dependent) */
	if (IB_SUCCESS !=
	    osmv_transport_init(p_bind_info, hca_id, hca_index, p_bo)) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7307: "
			"osmv_transport_init failed \n");
		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* insert bind handle into db */
	p_obj = malloc(sizeof(cl_list_obj_t));
	if (NULL == p_obj) {

		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7308: "
			"osm_vendor_bind: could not allocate the list object\n");

		osmv_transport_done(p_bo->p_transp_mgr);
		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}
	memset(p_obj, 0, sizeof(cl_list_obj_t));
	cl_qlist_set_obj(p_obj, p_bo);

	cl_qlist_insert_head(&p_vend->bind_handles, &p_obj->list_item);

	return (osm_bind_handle_t) p_bo;
}