/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* MODULE: dapl_osd.c
*
* PURPOSE: Operating System Dependent layer
* Description:
* Provide OS dependent functions with a canonical DAPL
* interface. Designed to be portable and hide OS specific quirks
* of common functions.
*
*
* $Id: dapl_osd.c,v 1.26 2003/07/31 14:04:18 jlentini Exp $
*/
#include "dapl_osd.h"
#include "dapl.h"
#include "dapl_hca_util.h"
#include "dapl_ia_util.h"
#include "dapl_rmr_util.h"
#include "dapl_lmr_util.h"
#include "dapl_pz_util.h"
#include "dapl_ep_util.h"
#include "dapl_cr_util.h"
#include "dapl_evd_util.h"
#include "dapl_sp_util.h"
#include "dapl_adapter_util.h"
#include "dapl_provider.h"
#include "dapl_hash.h"
#include "dapl_debug.h"
#include <stdlib.h> /* needed for getenv() */
#include <pthread.h> /* needed for pthread_atfork() */
#include <signal.h> /* needed for thread setup */
static void dapls_osd_fork_cleanup(void);
/*
* dapl_osd_init
*
* Do Linux initialization:
* - Set up fork handler to clean up DAPL resources in the child
* process after a fork().
*
* Input:
* none
*
* Returns:
* DAT_SUCCESS
*/
void
{
int status;
/*
* Set up fork control
*/
if (status != 0) {
"WARNING: pthread_atfork %d\n", status);
}
}
/*
* dapl_os_get_time
*
* Return 64 bit value of current time in microseconds.
*
* Input:
* loc User location to place current time
*
* Returns:
* DAT_SUCCESS
*/
{
return (DAT_SUCCESS);
}
/*
* dapl_os_get__env_bool
*
* Return boolean value of passed in environment variable: 1 if present,
* 0 if not
*
* Input:
*
*
* Returns:
* TRUE or FALSE
*/
int
char *env_str)
{
char *env_var;
return (1);
}
return (0);
}
/*
* dapl_os_get_env_val
*
* Update val to value of passed in environment variable if present
*
* Input:
* env_str
* def_val default value if environment variable does not exist
*
* Returns:
* TRUE or FALSE
*/
int
char *env_str,
int def_val)
{
char *env_var;
}
return (def_val);
}
/*
* Wait object routines
*/
/*
* dapl_os_wait_object_init
*
* Initialize a wait object
*
* Input:
* wait_obj
*
* Returns:
* DAT_SUCCESS
* DAT_INTERNAL_ERROR
*/
{
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
/* Always returns 0. */
return (DAT_SUCCESS);
}
/*
* Wait on the supplied wait object, up to the specified time_out.
* A timeout of DAT_TIMEOUT_INFINITE will wait indefinitely.
* Timeout should be specified in micro seconds.
*
* Functional returns:
* DAT_SUCCESS -- another thread invoked dapl_os_wait object_wakeup
* DAT_INVALID_STATE -- someone else is already waiting in this wait
* object.
* only one waiter is allowed at a time.
* DAT_ABORT -- another thread invoked dapl_os_wait_object_destroy
* DAT_TIMEOUT -- the specified time limit was reached.
*/
{
int pthread_status;
pthread_status = 0;
if (timeout_val != DAT_TIMEOUT_INFINITE) {
unsigned int microsecs;
if (microsecs > 1000000) {
} else {
}
/* Convert timeval to timespec */
/*
* No need to reset &future if we go around the loop;
* It's an absolute time.
*/
}
/* Reset the signaled status if we were woken up. */
if (pthread_status == 0) {
}
} else {
}
/* Reset the signaled status if we were woken up. */
if (pthread_status == 0) {
}
}
if (ETIMEDOUT == pthread_status) {
} else if (0 != pthread_status) {
}
return (dat_status);
}
/*
* dapl_os_wait_object_wakeup
*
* Wakeup a thread waiting on a wait object
*
* Input:
* wait_obj
*
* Returns:
* DAT_SUCCESS
* DAT_INTERNAL_ERROR
*/
{
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
return (DAT_SUCCESS);
}
/*
* dapl_os_wait_object_destroy
*
* Destroy a wait object
*
* Input:
* wait_obj
*
* Returns:
* DAT_SUCCESS
* DAT_INTERNAL_ERROR
*/
{
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
return (DAT_SUCCESS);
}
/*
* dapls_osd_fork_cleanup
*
* Update val to value of passed in environment variable if present
*
* Input:
* env_str
* val Updated if environment variable exists
*
* Returns:
* TRUE or FALSE
*/
void
dapls_osd_fork_cleanup(void)
{
/*
* Walk the list of IA ptrs & clean up. This is purposely
* a destructive list walk, we really don't want to preserve
* any of it.
*/
/*
* The rest of the cleanup code is similar to
* dapl_ia_close, the big difference is that we don't
* release IB resources, only memory; the underlying IB
* subsystem doesn't deal with fork at all, so leave
* IB handles alone.
*/
virtual_address != 0) {
(void) dapl_os_atomic_dec(&rmr_ptr->
lmr->lmr_ref_count);
virtual_address = 0;
}
rmr_ptr);
}
&ia_ptr->rsp_list_head);
}
&ia_ptr->ep_list_head);
}
}
if (param->request_evd_handle) {
}
}
/* ...and free the resource */
}
&ia_ptr->lmr_list_head);
lmr_ptr);
}
&ia_ptr->psp_list_head);
while (!dapl_llist_is_empty(&sp_ptr->
cr_list_head)) {
&sp_ptr->cr_list_head);
}
}
pz_ptr);
}
&ia_ptr->evd_list_head);
evd_ptr);
/*
* reset the cq_handle to avoid having it
* removed
*/
(void) dapls_evd_dealloc(evd_ptr);
}
/*
* asycn error evd was taken care of above, reset the
* pointer
*/
} /* end while( ia_ptr != NULL ) */
} /* end while (NULL != g_dapl_provider_list.head) */
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 8
* End:
*/