xref: /onnv-gate/usr/src/lib/udapl/udapl_tavor/common/dapl_osd.c (revision 9517:b4839b0aa7a4)
1*9517SBill.Taylor@Sun.COM /*
2*9517SBill.Taylor@Sun.COM  * CDDL HEADER START
3*9517SBill.Taylor@Sun.COM  *
4*9517SBill.Taylor@Sun.COM  * The contents of this file are subject to the terms of the
5*9517SBill.Taylor@Sun.COM  * Common Development and Distribution License (the "License").
6*9517SBill.Taylor@Sun.COM  * You may not use this file except in compliance with the License.
7*9517SBill.Taylor@Sun.COM  *
8*9517SBill.Taylor@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9517SBill.Taylor@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9517SBill.Taylor@Sun.COM  * See the License for the specific language governing permissions
11*9517SBill.Taylor@Sun.COM  * and limitations under the License.
12*9517SBill.Taylor@Sun.COM  *
13*9517SBill.Taylor@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9517SBill.Taylor@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9517SBill.Taylor@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9517SBill.Taylor@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9517SBill.Taylor@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9517SBill.Taylor@Sun.COM  *
19*9517SBill.Taylor@Sun.COM  * CDDL HEADER END
20*9517SBill.Taylor@Sun.COM  */
21*9517SBill.Taylor@Sun.COM 
22*9517SBill.Taylor@Sun.COM /*
23*9517SBill.Taylor@Sun.COM  * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
24*9517SBill.Taylor@Sun.COM  */
25*9517SBill.Taylor@Sun.COM 
26*9517SBill.Taylor@Sun.COM /*
27*9517SBill.Taylor@Sun.COM  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*9517SBill.Taylor@Sun.COM  * Use is subject to license terms.
29*9517SBill.Taylor@Sun.COM  */
30*9517SBill.Taylor@Sun.COM 
31*9517SBill.Taylor@Sun.COM /*
32*9517SBill.Taylor@Sun.COM  *
33*9517SBill.Taylor@Sun.COM  * MODULE: dapl_osd.c
34*9517SBill.Taylor@Sun.COM  *
35*9517SBill.Taylor@Sun.COM  * PURPOSE: Operating System Dependent layer
36*9517SBill.Taylor@Sun.COM  * Description:
37*9517SBill.Taylor@Sun.COM  *	Provide OS dependent functions with a canonical DAPL
38*9517SBill.Taylor@Sun.COM  *	interface. Designed to be portable and hide OS specific quirks
39*9517SBill.Taylor@Sun.COM  *	of common functions.
40*9517SBill.Taylor@Sun.COM  *
41*9517SBill.Taylor@Sun.COM  *
42*9517SBill.Taylor@Sun.COM  * $Id: dapl_osd.c,v 1.26 2003/07/31 14:04:18 jlentini Exp $
43*9517SBill.Taylor@Sun.COM  */
44*9517SBill.Taylor@Sun.COM 
45*9517SBill.Taylor@Sun.COM #include "dapl_osd.h"
46*9517SBill.Taylor@Sun.COM #include "dapl.h"
47*9517SBill.Taylor@Sun.COM #include "dapl_hca_util.h"
48*9517SBill.Taylor@Sun.COM #include "dapl_ia_util.h"
49*9517SBill.Taylor@Sun.COM #include "dapl_rmr_util.h"
50*9517SBill.Taylor@Sun.COM #include "dapl_lmr_util.h"
51*9517SBill.Taylor@Sun.COM #include "dapl_pz_util.h"
52*9517SBill.Taylor@Sun.COM #include "dapl_ep_util.h"
53*9517SBill.Taylor@Sun.COM #include "dapl_cr_util.h"
54*9517SBill.Taylor@Sun.COM #include "dapl_evd_util.h"
55*9517SBill.Taylor@Sun.COM #include "dapl_sp_util.h"
56*9517SBill.Taylor@Sun.COM #include "dapl_adapter_util.h"
57*9517SBill.Taylor@Sun.COM #include "dapl_provider.h"
58*9517SBill.Taylor@Sun.COM #include "dapl_hash.h"
59*9517SBill.Taylor@Sun.COM #include "dapl_debug.h"
60*9517SBill.Taylor@Sun.COM 
61*9517SBill.Taylor@Sun.COM #include <sys/time.h>
62*9517SBill.Taylor@Sun.COM #include <stdlib.h>			/* needed for getenv() */
63*9517SBill.Taylor@Sun.COM #include <pthread.h>			/* needed for pthread_atfork() */
64*9517SBill.Taylor@Sun.COM #include <signal.h>			/* needed for thread setup */
65*9517SBill.Taylor@Sun.COM 
66*9517SBill.Taylor@Sun.COM static void dapls_osd_fork_cleanup(void);
67*9517SBill.Taylor@Sun.COM 
68*9517SBill.Taylor@Sun.COM /*
69*9517SBill.Taylor@Sun.COM  * dapl_osd_init
70*9517SBill.Taylor@Sun.COM  *
71*9517SBill.Taylor@Sun.COM  * Do Linux initialization:
72*9517SBill.Taylor@Sun.COM  * - Set up fork handler to clean up DAPL resources in the child
73*9517SBill.Taylor@Sun.COM  *   process after a fork().
74*9517SBill.Taylor@Sun.COM  *
75*9517SBill.Taylor@Sun.COM  * Input:
76*9517SBill.Taylor@Sun.COM  *      none
77*9517SBill.Taylor@Sun.COM  *
78*9517SBill.Taylor@Sun.COM  * Returns:
79*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS
80*9517SBill.Taylor@Sun.COM  */
81*9517SBill.Taylor@Sun.COM void
dapl_os_init()82*9517SBill.Taylor@Sun.COM dapl_os_init()
83*9517SBill.Taylor@Sun.COM {
84*9517SBill.Taylor@Sun.COM 	int status;
85*9517SBill.Taylor@Sun.COM 
86*9517SBill.Taylor@Sun.COM 	/*
87*9517SBill.Taylor@Sun.COM 	 * Set up fork control
88*9517SBill.Taylor@Sun.COM 	 */
89*9517SBill.Taylor@Sun.COM 	status = pthread_atfork(NULL, NULL, dapls_osd_fork_cleanup);
90*9517SBill.Taylor@Sun.COM 	if (status != 0) {
91*9517SBill.Taylor@Sun.COM 		dapl_dbg_log(DAPL_DBG_TYPE_WARN,
92*9517SBill.Taylor@Sun.COM 		    "WARNING: pthread_atfork %d\n", status);
93*9517SBill.Taylor@Sun.COM 	}
94*9517SBill.Taylor@Sun.COM }
95*9517SBill.Taylor@Sun.COM 
96*9517SBill.Taylor@Sun.COM 
97*9517SBill.Taylor@Sun.COM /*
98*9517SBill.Taylor@Sun.COM  * dapl_os_get_time
99*9517SBill.Taylor@Sun.COM  *
100*9517SBill.Taylor@Sun.COM  * Return 64 bit value of current time in microseconds.
101*9517SBill.Taylor@Sun.COM  *
102*9517SBill.Taylor@Sun.COM  * Input:
103*9517SBill.Taylor@Sun.COM  *      loc       User location to place current time
104*9517SBill.Taylor@Sun.COM  *
105*9517SBill.Taylor@Sun.COM  * Returns:
106*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS
107*9517SBill.Taylor@Sun.COM  */
108*9517SBill.Taylor@Sun.COM 
109*9517SBill.Taylor@Sun.COM DAT_RETURN
dapl_os_get_time(OUT DAPL_OS_TIMEVAL * loc)110*9517SBill.Taylor@Sun.COM dapl_os_get_time(
111*9517SBill.Taylor@Sun.COM     OUT DAPL_OS_TIMEVAL * loc)
112*9517SBill.Taylor@Sun.COM {
113*9517SBill.Taylor@Sun.COM 	struct timeval	tv;
114*9517SBill.Taylor@Sun.COM 	struct timezone	tz;
115*9517SBill.Taylor@Sun.COM 
116*9517SBill.Taylor@Sun.COM 
117*9517SBill.Taylor@Sun.COM 	(void) gettimeofday(&tv, &tz);
118*9517SBill.Taylor@Sun.COM 	*loc = ((DAT_UINT64)(tv.tv_sec) * 1000000L) + (DAT_UINT64) tv.tv_usec;
119*9517SBill.Taylor@Sun.COM 
120*9517SBill.Taylor@Sun.COM 	return (DAT_SUCCESS);
121*9517SBill.Taylor@Sun.COM }
122*9517SBill.Taylor@Sun.COM 
123*9517SBill.Taylor@Sun.COM 
124*9517SBill.Taylor@Sun.COM /*
125*9517SBill.Taylor@Sun.COM  * dapl_os_get__env_bool
126*9517SBill.Taylor@Sun.COM  *
127*9517SBill.Taylor@Sun.COM  * Return boolean value of passed in environment variable: 1 if present,
128*9517SBill.Taylor@Sun.COM  * 0 if not
129*9517SBill.Taylor@Sun.COM  *
130*9517SBill.Taylor@Sun.COM  * Input:
131*9517SBill.Taylor@Sun.COM  *
132*9517SBill.Taylor@Sun.COM  *
133*9517SBill.Taylor@Sun.COM  * Returns:
134*9517SBill.Taylor@Sun.COM  *	TRUE or FALSE
135*9517SBill.Taylor@Sun.COM  */
136*9517SBill.Taylor@Sun.COM int
dapl_os_get_env_bool(char * env_str)137*9517SBill.Taylor@Sun.COM dapl_os_get_env_bool(
138*9517SBill.Taylor@Sun.COM 	char		*env_str)
139*9517SBill.Taylor@Sun.COM {
140*9517SBill.Taylor@Sun.COM 	char		*env_var;
141*9517SBill.Taylor@Sun.COM 
142*9517SBill.Taylor@Sun.COM 	env_var = getenv(env_str);
143*9517SBill.Taylor@Sun.COM 	if (env_var != NULL) {
144*9517SBill.Taylor@Sun.COM 		return (1);
145*9517SBill.Taylor@Sun.COM 	}
146*9517SBill.Taylor@Sun.COM 
147*9517SBill.Taylor@Sun.COM 	return (0);
148*9517SBill.Taylor@Sun.COM }
149*9517SBill.Taylor@Sun.COM 
150*9517SBill.Taylor@Sun.COM 
151*9517SBill.Taylor@Sun.COM /*
152*9517SBill.Taylor@Sun.COM  * dapl_os_get_env_val
153*9517SBill.Taylor@Sun.COM  *
154*9517SBill.Taylor@Sun.COM  * Update val to  value of passed in environment variable if present
155*9517SBill.Taylor@Sun.COM  *
156*9517SBill.Taylor@Sun.COM  * Input:
157*9517SBill.Taylor@Sun.COM  *      env_str
158*9517SBill.Taylor@Sun.COM  *	def_val		default value if environment variable does not exist
159*9517SBill.Taylor@Sun.COM  *
160*9517SBill.Taylor@Sun.COM  * Returns:
161*9517SBill.Taylor@Sun.COM  *	TRUE or FALSE
162*9517SBill.Taylor@Sun.COM  */
163*9517SBill.Taylor@Sun.COM int
dapl_os_get_env_val(char * env_str,int def_val)164*9517SBill.Taylor@Sun.COM dapl_os_get_env_val(
165*9517SBill.Taylor@Sun.COM 	char		*env_str,
166*9517SBill.Taylor@Sun.COM 	int		def_val)
167*9517SBill.Taylor@Sun.COM {
168*9517SBill.Taylor@Sun.COM 	char		*env_var;
169*9517SBill.Taylor@Sun.COM 
170*9517SBill.Taylor@Sun.COM 	env_var = getenv(env_str);
171*9517SBill.Taylor@Sun.COM 	if (env_var != NULL) {
172*9517SBill.Taylor@Sun.COM 		def_val = strtol(env_var, NULL, 0);
173*9517SBill.Taylor@Sun.COM 	}
174*9517SBill.Taylor@Sun.COM 
175*9517SBill.Taylor@Sun.COM 	return (def_val);
176*9517SBill.Taylor@Sun.COM }
177*9517SBill.Taylor@Sun.COM 
178*9517SBill.Taylor@Sun.COM 
179*9517SBill.Taylor@Sun.COM /*
180*9517SBill.Taylor@Sun.COM  * Wait object routines
181*9517SBill.Taylor@Sun.COM  */
182*9517SBill.Taylor@Sun.COM 
183*9517SBill.Taylor@Sun.COM /*
184*9517SBill.Taylor@Sun.COM  * dapl_os_wait_object_init
185*9517SBill.Taylor@Sun.COM  *
186*9517SBill.Taylor@Sun.COM  * Initialize a wait object
187*9517SBill.Taylor@Sun.COM  *
188*9517SBill.Taylor@Sun.COM  * Input:
189*9517SBill.Taylor@Sun.COM  *	wait_obj
190*9517SBill.Taylor@Sun.COM  *
191*9517SBill.Taylor@Sun.COM  * Returns:
192*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS
193*9517SBill.Taylor@Sun.COM  *	DAT_INTERNAL_ERROR
194*9517SBill.Taylor@Sun.COM  */
195*9517SBill.Taylor@Sun.COM DAT_RETURN
dapl_os_wait_object_init(IN DAPL_OS_WAIT_OBJECT * wait_obj)196*9517SBill.Taylor@Sun.COM dapl_os_wait_object_init(
197*9517SBill.Taylor@Sun.COM     IN DAPL_OS_WAIT_OBJECT *wait_obj)
198*9517SBill.Taylor@Sun.COM {
199*9517SBill.Taylor@Sun.COM 	wait_obj->signaled = DAT_FALSE;
200*9517SBill.Taylor@Sun.COM 	if (0 != pthread_cond_init(&wait_obj->cv, NULL)) {
201*9517SBill.Taylor@Sun.COM 		return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
202*9517SBill.Taylor@Sun.COM 	}
203*9517SBill.Taylor@Sun.COM 
204*9517SBill.Taylor@Sun.COM 	/* Always returns 0.  */
205*9517SBill.Taylor@Sun.COM 	(void) pthread_mutex_init(&wait_obj->lock, NULL);
206*9517SBill.Taylor@Sun.COM 
207*9517SBill.Taylor@Sun.COM 	return (DAT_SUCCESS);
208*9517SBill.Taylor@Sun.COM }
209*9517SBill.Taylor@Sun.COM 
210*9517SBill.Taylor@Sun.COM 
211*9517SBill.Taylor@Sun.COM /*
212*9517SBill.Taylor@Sun.COM  * Wait on the supplied wait object, up to the specified time_out.
213*9517SBill.Taylor@Sun.COM  * A timeout of DAT_TIMEOUT_INFINITE will wait indefinitely.
214*9517SBill.Taylor@Sun.COM  * Timeout should be specified in micro seconds.
215*9517SBill.Taylor@Sun.COM  *
216*9517SBill.Taylor@Sun.COM  * Functional returns:
217*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS -- another thread invoked dapl_os_wait object_wakeup
218*9517SBill.Taylor@Sun.COM  * 	DAT_INVALID_STATE -- someone else is already waiting in this wait
219*9517SBill.Taylor@Sun.COM  * 	object.
220*9517SBill.Taylor@Sun.COM  *			     only one waiter is allowed at a time.
221*9517SBill.Taylor@Sun.COM  *	DAT_ABORT -- another thread invoked dapl_os_wait_object_destroy
222*9517SBill.Taylor@Sun.COM  *	DAT_TIMEOUT -- the specified time limit was reached.
223*9517SBill.Taylor@Sun.COM  */
224*9517SBill.Taylor@Sun.COM 
225*9517SBill.Taylor@Sun.COM DAT_RETURN
dapl_os_wait_object_wait(IN DAPL_OS_WAIT_OBJECT * wait_obj,IN DAT_TIMEOUT timeout_val)226*9517SBill.Taylor@Sun.COM dapl_os_wait_object_wait(
227*9517SBill.Taylor@Sun.COM 	IN  DAPL_OS_WAIT_OBJECT *wait_obj,
228*9517SBill.Taylor@Sun.COM 	IN  DAT_TIMEOUT timeout_val)
229*9517SBill.Taylor@Sun.COM {
230*9517SBill.Taylor@Sun.COM 	DAT_RETURN 		dat_status;
231*9517SBill.Taylor@Sun.COM 	int			pthread_status;
232*9517SBill.Taylor@Sun.COM 	struct timespec 	future;
233*9517SBill.Taylor@Sun.COM 
234*9517SBill.Taylor@Sun.COM 	dat_status = DAT_SUCCESS;
235*9517SBill.Taylor@Sun.COM 	pthread_status = 0;
236*9517SBill.Taylor@Sun.COM 
237*9517SBill.Taylor@Sun.COM 	if (timeout_val != DAT_TIMEOUT_INFINITE) {
238*9517SBill.Taylor@Sun.COM 		struct timeval now;
239*9517SBill.Taylor@Sun.COM 		struct timezone tz;
240*9517SBill.Taylor@Sun.COM 		unsigned int microsecs;
241*9517SBill.Taylor@Sun.COM 
242*9517SBill.Taylor@Sun.COM 		(void) gettimeofday(&now, &tz);
243*9517SBill.Taylor@Sun.COM 		microsecs = now.tv_usec + (timeout_val % 1000000);
244*9517SBill.Taylor@Sun.COM 		if (microsecs > 1000000) {
245*9517SBill.Taylor@Sun.COM 			now.tv_sec = now.tv_sec + timeout_val / 1000000 + 1;
246*9517SBill.Taylor@Sun.COM 			now.tv_usec = microsecs - 1000000;
247*9517SBill.Taylor@Sun.COM 		} else {
248*9517SBill.Taylor@Sun.COM 			now.tv_sec = now.tv_sec + timeout_val / 1000000;
249*9517SBill.Taylor@Sun.COM 			now.tv_usec = microsecs;
250*9517SBill.Taylor@Sun.COM 		}
251*9517SBill.Taylor@Sun.COM 
252*9517SBill.Taylor@Sun.COM 		/* Convert timeval to timespec */
253*9517SBill.Taylor@Sun.COM 		future.tv_sec = now.tv_sec;
254*9517SBill.Taylor@Sun.COM 		future.tv_nsec = now.tv_usec * 1000;
255*9517SBill.Taylor@Sun.COM 
256*9517SBill.Taylor@Sun.COM 		(void) pthread_mutex_lock(&wait_obj->lock);
257*9517SBill.Taylor@Sun.COM 		while (wait_obj->signaled == DAT_FALSE && pthread_status == 0) {
258*9517SBill.Taylor@Sun.COM 			pthread_status = pthread_cond_timedwait(
259*9517SBill.Taylor@Sun.COM 			    &wait_obj->cv, &wait_obj->lock, &future);
260*9517SBill.Taylor@Sun.COM 
261*9517SBill.Taylor@Sun.COM 			/*
262*9517SBill.Taylor@Sun.COM 			 * No need to reset &future if we go around the loop;
263*9517SBill.Taylor@Sun.COM 			 * It's an absolute time.
264*9517SBill.Taylor@Sun.COM 			 */
265*9517SBill.Taylor@Sun.COM 		}
266*9517SBill.Taylor@Sun.COM 		/* Reset the signaled status if we were woken up.  */
267*9517SBill.Taylor@Sun.COM 		if (pthread_status == 0) {
268*9517SBill.Taylor@Sun.COM 			wait_obj->signaled = DAT_FALSE;
269*9517SBill.Taylor@Sun.COM 		}
270*9517SBill.Taylor@Sun.COM 		(void) pthread_mutex_unlock(&wait_obj->lock);
271*9517SBill.Taylor@Sun.COM 	} else {
272*9517SBill.Taylor@Sun.COM 		(void) pthread_mutex_lock(&wait_obj->lock);
273*9517SBill.Taylor@Sun.COM 		while (wait_obj->signaled == DAT_FALSE && pthread_status == 0) {
274*9517SBill.Taylor@Sun.COM 			pthread_status = pthread_cond_wait(
275*9517SBill.Taylor@Sun.COM 			    &wait_obj->cv, &wait_obj->lock);
276*9517SBill.Taylor@Sun.COM 		}
277*9517SBill.Taylor@Sun.COM 		/* Reset the signaled status if we were woken up.  */
278*9517SBill.Taylor@Sun.COM 		if (pthread_status == 0) {
279*9517SBill.Taylor@Sun.COM 			wait_obj->signaled = DAT_FALSE;
280*9517SBill.Taylor@Sun.COM 		}
281*9517SBill.Taylor@Sun.COM 		(void) pthread_mutex_unlock(&wait_obj->lock);
282*9517SBill.Taylor@Sun.COM 	}
283*9517SBill.Taylor@Sun.COM 
284*9517SBill.Taylor@Sun.COM 	if (ETIMEDOUT == pthread_status) {
285*9517SBill.Taylor@Sun.COM 		dat_status = DAT_ERROR(DAT_TIMEOUT_EXPIRED, 0);
286*9517SBill.Taylor@Sun.COM 	} else if (0 != pthread_status) {
287*9517SBill.Taylor@Sun.COM 		dat_status = DAT_ERROR(DAT_INTERNAL_ERROR, 0);
288*9517SBill.Taylor@Sun.COM 	}
289*9517SBill.Taylor@Sun.COM 
290*9517SBill.Taylor@Sun.COM 	return (dat_status);
291*9517SBill.Taylor@Sun.COM }
292*9517SBill.Taylor@Sun.COM 
293*9517SBill.Taylor@Sun.COM 
294*9517SBill.Taylor@Sun.COM /*
295*9517SBill.Taylor@Sun.COM  * dapl_os_wait_object_wakeup
296*9517SBill.Taylor@Sun.COM  *
297*9517SBill.Taylor@Sun.COM  * Wakeup a thread waiting on a wait object
298*9517SBill.Taylor@Sun.COM  *
299*9517SBill.Taylor@Sun.COM  * Input:
300*9517SBill.Taylor@Sun.COM  *      wait_obj
301*9517SBill.Taylor@Sun.COM  *
302*9517SBill.Taylor@Sun.COM  * Returns:
303*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS
304*9517SBill.Taylor@Sun.COM  *	DAT_INTERNAL_ERROR
305*9517SBill.Taylor@Sun.COM  */
306*9517SBill.Taylor@Sun.COM DAT_RETURN
dapl_os_wait_object_wakeup(IN DAPL_OS_WAIT_OBJECT * wait_obj)307*9517SBill.Taylor@Sun.COM dapl_os_wait_object_wakeup(
308*9517SBill.Taylor@Sun.COM     IN	DAPL_OS_WAIT_OBJECT *wait_obj)
309*9517SBill.Taylor@Sun.COM {
310*9517SBill.Taylor@Sun.COM 	(void) pthread_mutex_lock(&wait_obj->lock);
311*9517SBill.Taylor@Sun.COM 	wait_obj->signaled = DAT_TRUE;
312*9517SBill.Taylor@Sun.COM 	(void) pthread_mutex_unlock(&wait_obj->lock);
313*9517SBill.Taylor@Sun.COM 	if (0 != pthread_cond_signal(&wait_obj->cv)) {
314*9517SBill.Taylor@Sun.COM 		return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
315*9517SBill.Taylor@Sun.COM 	}
316*9517SBill.Taylor@Sun.COM 
317*9517SBill.Taylor@Sun.COM 	return (DAT_SUCCESS);
318*9517SBill.Taylor@Sun.COM }
319*9517SBill.Taylor@Sun.COM 
320*9517SBill.Taylor@Sun.COM 
321*9517SBill.Taylor@Sun.COM /*
322*9517SBill.Taylor@Sun.COM  * dapl_os_wait_object_destroy
323*9517SBill.Taylor@Sun.COM  *
324*9517SBill.Taylor@Sun.COM  * Destroy a wait object
325*9517SBill.Taylor@Sun.COM  *
326*9517SBill.Taylor@Sun.COM  * Input:
327*9517SBill.Taylor@Sun.COM  *      wait_obj
328*9517SBill.Taylor@Sun.COM  *
329*9517SBill.Taylor@Sun.COM  * Returns:
330*9517SBill.Taylor@Sun.COM  *	DAT_SUCCESS
331*9517SBill.Taylor@Sun.COM  *	DAT_INTERNAL_ERROR
332*9517SBill.Taylor@Sun.COM  */
333*9517SBill.Taylor@Sun.COM DAT_RETURN
dapl_os_wait_object_destroy(IN DAPL_OS_WAIT_OBJECT * wait_obj)334*9517SBill.Taylor@Sun.COM dapl_os_wait_object_destroy(
335*9517SBill.Taylor@Sun.COM     IN	DAPL_OS_WAIT_OBJECT *wait_obj)
336*9517SBill.Taylor@Sun.COM {
337*9517SBill.Taylor@Sun.COM 	if (0 != pthread_cond_destroy(&wait_obj->cv)) {
338*9517SBill.Taylor@Sun.COM 		return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
339*9517SBill.Taylor@Sun.COM 	}
340*9517SBill.Taylor@Sun.COM 	if (0 != pthread_mutex_destroy(&wait_obj->lock)) {
341*9517SBill.Taylor@Sun.COM 		return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
342*9517SBill.Taylor@Sun.COM 	}
343*9517SBill.Taylor@Sun.COM 
344*9517SBill.Taylor@Sun.COM 	return (DAT_SUCCESS);
345*9517SBill.Taylor@Sun.COM }
346*9517SBill.Taylor@Sun.COM 
347*9517SBill.Taylor@Sun.COM 
348*9517SBill.Taylor@Sun.COM /*
349*9517SBill.Taylor@Sun.COM  * dapls_osd_fork_cleanup
350*9517SBill.Taylor@Sun.COM  *
351*9517SBill.Taylor@Sun.COM  * Update val to  value of passed in environment variable if present
352*9517SBill.Taylor@Sun.COM  *
353*9517SBill.Taylor@Sun.COM  * Input:
354*9517SBill.Taylor@Sun.COM  *      env_str
355*9517SBill.Taylor@Sun.COM  *	val		Updated if environment variable exists
356*9517SBill.Taylor@Sun.COM  *
357*9517SBill.Taylor@Sun.COM  * Returns:
358*9517SBill.Taylor@Sun.COM  *	TRUE or FALSE
359*9517SBill.Taylor@Sun.COM  */
360*9517SBill.Taylor@Sun.COM void
dapls_osd_fork_cleanup(void)361*9517SBill.Taylor@Sun.COM dapls_osd_fork_cleanup(void)
362*9517SBill.Taylor@Sun.COM {
363*9517SBill.Taylor@Sun.COM 	DAPL_PROVIDER_LIST_NODE 	*cur_node;
364*9517SBill.Taylor@Sun.COM 	DAPL_HCA			*hca_ptr;
365*9517SBill.Taylor@Sun.COM 	DAPL_IA				*ia_ptr;
366*9517SBill.Taylor@Sun.COM 	DAPL_LMR 			*lmr_ptr;
367*9517SBill.Taylor@Sun.COM 	DAPL_RMR			*rmr_ptr;
368*9517SBill.Taylor@Sun.COM 	DAPL_PZ				*pz_ptr;
369*9517SBill.Taylor@Sun.COM 	DAPL_CR				*cr_ptr;
370*9517SBill.Taylor@Sun.COM 	DAPL_EP				*ep_ptr;
371*9517SBill.Taylor@Sun.COM 	DAPL_EVD			*evd_ptr;
372*9517SBill.Taylor@Sun.COM 	DAT_EP_PARAM			*param;
373*9517SBill.Taylor@Sun.COM 	DAPL_SP				*sp_ptr;
374*9517SBill.Taylor@Sun.COM 
375*9517SBill.Taylor@Sun.COM 	while (NULL != g_dapl_provider_list.head) {
376*9517SBill.Taylor@Sun.COM 		cur_node = g_dapl_provider_list.head;
377*9517SBill.Taylor@Sun.COM 		g_dapl_provider_list.head = cur_node->next;
378*9517SBill.Taylor@Sun.COM 
379*9517SBill.Taylor@Sun.COM 		hca_ptr = (DAPL_HCA *) cur_node->data.extension;
380*9517SBill.Taylor@Sun.COM 
381*9517SBill.Taylor@Sun.COM 		/*
382*9517SBill.Taylor@Sun.COM 		 * Walk the list of IA ptrs & clean up. This is purposely
383*9517SBill.Taylor@Sun.COM 		 * a destructive list walk, we really don't want to preserve
384*9517SBill.Taylor@Sun.COM 		 * any of it.
385*9517SBill.Taylor@Sun.COM 		 */
386*9517SBill.Taylor@Sun.COM 		while (!dapl_llist_is_empty(&hca_ptr->ia_list_head)) {
387*9517SBill.Taylor@Sun.COM 			ia_ptr = (DAPL_IA *)
388*9517SBill.Taylor@Sun.COM 			    dapl_llist_peek_head(&hca_ptr->ia_list_head);
389*9517SBill.Taylor@Sun.COM 
390*9517SBill.Taylor@Sun.COM 			/*
391*9517SBill.Taylor@Sun.COM 			 * The rest of the cleanup code is similar to
392*9517SBill.Taylor@Sun.COM 			 * dapl_ia_close, the big difference is that we don't
393*9517SBill.Taylor@Sun.COM 			 * release IB resources, only memory; the underlying IB
394*9517SBill.Taylor@Sun.COM 			 * subsystem doesn't deal with fork at all, so leave
395*9517SBill.Taylor@Sun.COM 			 * IB handles alone.
396*9517SBill.Taylor@Sun.COM 			 */
397*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->rmr_list_head)) {
398*9517SBill.Taylor@Sun.COM 				rmr_ptr = (DAPL_RMR *)
399*9517SBill.Taylor@Sun.COM 				    dapl_llist_peek_head(&ia_ptr->
400*9517SBill.Taylor@Sun.COM 				    rmr_list_head);
401*9517SBill.Taylor@Sun.COM 				if (rmr_ptr->param.lmr_triplet.
402*9517SBill.Taylor@Sun.COM 				    virtual_address != 0) {
403*9517SBill.Taylor@Sun.COM 					(void) dapl_os_atomic_dec(&rmr_ptr->
404*9517SBill.Taylor@Sun.COM 					    lmr->lmr_ref_count);
405*9517SBill.Taylor@Sun.COM 					rmr_ptr->param.lmr_triplet.
406*9517SBill.Taylor@Sun.COM 					    virtual_address = 0;
407*9517SBill.Taylor@Sun.COM 				}
408*9517SBill.Taylor@Sun.COM 				dapl_os_atomic_dec(&rmr_ptr->pz->pz_ref_count);
409*9517SBill.Taylor@Sun.COM 				dapl_ia_unlink_rmr(rmr_ptr->header.owner_ia,
410*9517SBill.Taylor@Sun.COM 				    rmr_ptr);
411*9517SBill.Taylor@Sun.COM 				dapl_rmr_dealloc(rmr_ptr);
412*9517SBill.Taylor@Sun.COM 			}
413*9517SBill.Taylor@Sun.COM 
414*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->rsp_list_head)) {
415*9517SBill.Taylor@Sun.COM 				sp_ptr = (DAPL_SP *) dapl_llist_peek_head(
416*9517SBill.Taylor@Sun.COM 				    &ia_ptr->rsp_list_head);
417*9517SBill.Taylor@Sun.COM 				dapl_os_atomic_dec(&((DAPL_EVD *)sp_ptr->
418*9517SBill.Taylor@Sun.COM 				    evd_handle)->evd_ref_count);
419*9517SBill.Taylor@Sun.COM 				dapls_ia_unlink_sp(ia_ptr, sp_ptr);
420*9517SBill.Taylor@Sun.COM 				dapls_sp_free_sp(sp_ptr);
421*9517SBill.Taylor@Sun.COM 			}
422*9517SBill.Taylor@Sun.COM 
423*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->ep_list_head)) {
424*9517SBill.Taylor@Sun.COM 				ep_ptr = (DAPL_EP *) dapl_llist_peek_head(
425*9517SBill.Taylor@Sun.COM 				    &ia_ptr->ep_list_head);
426*9517SBill.Taylor@Sun.COM 				param = &ep_ptr->param;
427*9517SBill.Taylor@Sun.COM 				if (param->pz_handle != NULL) {
428*9517SBill.Taylor@Sun.COM 					dapl_os_atomic_dec(&((DAPL_PZ *)param->
429*9517SBill.Taylor@Sun.COM 					    pz_handle)->pz_ref_count);
430*9517SBill.Taylor@Sun.COM 				}
431*9517SBill.Taylor@Sun.COM 				if (param->recv_evd_handle != NULL) {
432*9517SBill.Taylor@Sun.COM 					dapl_os_atomic_dec(&((DAPL_EVD *)param->
433*9517SBill.Taylor@Sun.COM 					    recv_evd_handle)->evd_ref_count);
434*9517SBill.Taylor@Sun.COM 				}
435*9517SBill.Taylor@Sun.COM 				if (param->request_evd_handle) {
436*9517SBill.Taylor@Sun.COM 					dapl_os_atomic_dec(&((DAPL_EVD *)param->
437*9517SBill.Taylor@Sun.COM 					    request_evd_handle)->evd_ref_count);
438*9517SBill.Taylor@Sun.COM 				}
439*9517SBill.Taylor@Sun.COM 				if (param->connect_evd_handle != NULL) {
440*9517SBill.Taylor@Sun.COM 					dapl_os_atomic_dec(&((DAPL_EVD *)param->
441*9517SBill.Taylor@Sun.COM 					    connect_evd_handle)->evd_ref_count);
442*9517SBill.Taylor@Sun.COM 				}
443*9517SBill.Taylor@Sun.COM 
444*9517SBill.Taylor@Sun.COM 				/* ...and free the resource */
445*9517SBill.Taylor@Sun.COM 				dapl_ia_unlink_ep(ia_ptr, ep_ptr);
446*9517SBill.Taylor@Sun.COM 				dapl_ep_dealloc(ep_ptr);
447*9517SBill.Taylor@Sun.COM 			}
448*9517SBill.Taylor@Sun.COM 
449*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->lmr_list_head)) {
450*9517SBill.Taylor@Sun.COM 				lmr_ptr = (DAPL_LMR *) dapl_llist_peek_head(
451*9517SBill.Taylor@Sun.COM 				    &ia_ptr->lmr_list_head);
452*9517SBill.Taylor@Sun.COM 
453*9517SBill.Taylor@Sun.COM 				(void) dapls_hash_remove(lmr_ptr->header.
454*9517SBill.Taylor@Sun.COM 				    owner_ia->hca_ptr->lmr_hash_table,
455*9517SBill.Taylor@Sun.COM 				    lmr_ptr->param.lmr_context, NULL);
456*9517SBill.Taylor@Sun.COM 
457*9517SBill.Taylor@Sun.COM 				pz_ptr = (DAPL_PZ *) lmr_ptr->param.pz_handle;
458*9517SBill.Taylor@Sun.COM 				dapl_os_atomic_dec(&pz_ptr->pz_ref_count);
459*9517SBill.Taylor@Sun.COM 				dapl_ia_unlink_lmr(lmr_ptr->header.owner_ia,
460*9517SBill.Taylor@Sun.COM 				    lmr_ptr);
461*9517SBill.Taylor@Sun.COM 				dapl_lmr_dealloc(lmr_ptr);
462*9517SBill.Taylor@Sun.COM 			}
463*9517SBill.Taylor@Sun.COM 
464*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->psp_list_head)) {
465*9517SBill.Taylor@Sun.COM 				sp_ptr = (DAPL_SP *) dapl_llist_peek_head(
466*9517SBill.Taylor@Sun.COM 				    &ia_ptr->psp_list_head);
467*9517SBill.Taylor@Sun.COM 				while (!dapl_llist_is_empty(&sp_ptr->
468*9517SBill.Taylor@Sun.COM 				    cr_list_head)) {
469*9517SBill.Taylor@Sun.COM 					cr_ptr = (DAPL_CR *)
470*9517SBill.Taylor@Sun.COM 					    dapl_llist_peek_head(
471*9517SBill.Taylor@Sun.COM 					    &sp_ptr->cr_list_head);
472*9517SBill.Taylor@Sun.COM 					dapl_sp_remove_cr(sp_ptr, cr_ptr);
473*9517SBill.Taylor@Sun.COM 					dapls_cr_free(cr_ptr);
474*9517SBill.Taylor@Sun.COM 				}
475*9517SBill.Taylor@Sun.COM 
476*9517SBill.Taylor@Sun.COM 				dapls_ia_unlink_sp(ia_ptr, sp_ptr);
477*9517SBill.Taylor@Sun.COM 				dapl_os_atomic_dec(&((DAPL_EVD *)sp_ptr->
478*9517SBill.Taylor@Sun.COM 				    evd_handle)->evd_ref_count);
479*9517SBill.Taylor@Sun.COM 				dapls_sp_free_sp(sp_ptr);
480*9517SBill.Taylor@Sun.COM 			}
481*9517SBill.Taylor@Sun.COM 
482*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->pz_list_head)) {
483*9517SBill.Taylor@Sun.COM 				pz_ptr = (DAPL_PZ *)
484*9517SBill.Taylor@Sun.COM 				    dapl_llist_peek_head(&ia_ptr->pz_list_head);
485*9517SBill.Taylor@Sun.COM 				dapl_ia_unlink_pz(pz_ptr->header.owner_ia,
486*9517SBill.Taylor@Sun.COM 				    pz_ptr);
487*9517SBill.Taylor@Sun.COM 				dapl_pz_dealloc(pz_ptr);
488*9517SBill.Taylor@Sun.COM 			}
489*9517SBill.Taylor@Sun.COM 
490*9517SBill.Taylor@Sun.COM 			while (!dapl_llist_is_empty(&ia_ptr->evd_list_head)) {
491*9517SBill.Taylor@Sun.COM 				evd_ptr = (DAPL_EVD *) dapl_llist_peek_head(
492*9517SBill.Taylor@Sun.COM 				    &ia_ptr->evd_list_head);
493*9517SBill.Taylor@Sun.COM 				dapl_ia_unlink_evd(evd_ptr->header.owner_ia,
494*9517SBill.Taylor@Sun.COM 				    evd_ptr);
495*9517SBill.Taylor@Sun.COM 				/*
496*9517SBill.Taylor@Sun.COM 				 * reset the cq_handle to avoid having it
497*9517SBill.Taylor@Sun.COM 				 * removed
498*9517SBill.Taylor@Sun.COM 				 */
499*9517SBill.Taylor@Sun.COM 				evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
500*9517SBill.Taylor@Sun.COM 				(void) dapls_evd_dealloc(evd_ptr);
501*9517SBill.Taylor@Sun.COM 			}
502*9517SBill.Taylor@Sun.COM 
503*9517SBill.Taylor@Sun.COM 			dapl_hca_unlink_ia(ia_ptr->hca_ptr, ia_ptr);
504*9517SBill.Taylor@Sun.COM 			/*
505*9517SBill.Taylor@Sun.COM 			 * asycn error evd was taken care of above, reset the
506*9517SBill.Taylor@Sun.COM 			 * pointer
507*9517SBill.Taylor@Sun.COM 			 */
508*9517SBill.Taylor@Sun.COM 			ia_ptr->async_error_evd = NULL;
509*9517SBill.Taylor@Sun.COM 			dapls_ia_free(ia_ptr);
510*9517SBill.Taylor@Sun.COM 		}	/* end while( ia_ptr != NULL ) */
511*9517SBill.Taylor@Sun.COM 
512*9517SBill.Taylor@Sun.COM 
513*9517SBill.Taylor@Sun.COM 		dapl_os_free(cur_node, sizeof (DAPL_PROVIDER_LIST_NODE));
514*9517SBill.Taylor@Sun.COM 	} /* end while (NULL != g_dapl_provider_list.head) */
515*9517SBill.Taylor@Sun.COM }
516*9517SBill.Taylor@Sun.COM 
517*9517SBill.Taylor@Sun.COM 
518*9517SBill.Taylor@Sun.COM /*
519*9517SBill.Taylor@Sun.COM  * Local variables:
520*9517SBill.Taylor@Sun.COM  *  c-indent-level: 4
521*9517SBill.Taylor@Sun.COM  *  c-basic-offset: 4
522*9517SBill.Taylor@Sun.COM  *  tab-width: 8
523*9517SBill.Taylor@Sun.COM  * End:
524*9517SBill.Taylor@Sun.COM  */
525