xref: /onnv-gate/usr/src/cmd/ndmpd/tlm/tlm_buffers.c (revision 7917:5c4442486198)
1*7917SReza.Sabdar@Sun.COM /*
2*7917SReza.Sabdar@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*7917SReza.Sabdar@Sun.COM  * Use is subject to license terms.
4*7917SReza.Sabdar@Sun.COM  */
5*7917SReza.Sabdar@Sun.COM 
6*7917SReza.Sabdar@Sun.COM /*
7*7917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
8*7917SReza.Sabdar@Sun.COM  *
9*7917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
10*7917SReza.Sabdar@Sun.COM  *
11*7917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
12*7917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
13*7917SReza.Sabdar@Sun.COM  * are met:
14*7917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
15*7917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
16*7917SReza.Sabdar@Sun.COM  *
17*7917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
18*7917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
19*7917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
20*7917SReza.Sabdar@Sun.COM  *	  distribution.
21*7917SReza.Sabdar@Sun.COM  *
22*7917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23*7917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
24*7917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
25*7917SReza.Sabdar@Sun.COM  *	  permission.
26*7917SReza.Sabdar@Sun.COM  *
27*7917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*7917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*7917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*7917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*7917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*7917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*7917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*7917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*7917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*7917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*7917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
38*7917SReza.Sabdar@Sun.COM  */
39*7917SReza.Sabdar@Sun.COM #include <stdio.h>
40*7917SReza.Sabdar@Sun.COM #include <stdlib.h>
41*7917SReza.Sabdar@Sun.COM #include <sys/errno.h>
42*7917SReza.Sabdar@Sun.COM #include <string.h>
43*7917SReza.Sabdar@Sun.COM #include <unistd.h>
44*7917SReza.Sabdar@Sun.COM #include <pthread.h>
45*7917SReza.Sabdar@Sun.COM #include <synch.h>
46*7917SReza.Sabdar@Sun.COM #include <tlm_buffers.h>
47*7917SReza.Sabdar@Sun.COM #include <tlm.h>
48*7917SReza.Sabdar@Sun.COM #include "tlm_proto.h"
49*7917SReza.Sabdar@Sun.COM 
50*7917SReza.Sabdar@Sun.COM 
51*7917SReza.Sabdar@Sun.COM /*
52*7917SReza.Sabdar@Sun.COM  * tlm_allocate_buffers
53*7917SReza.Sabdar@Sun.COM  *
54*7917SReza.Sabdar@Sun.COM  * build a set of buffers
55*7917SReza.Sabdar@Sun.COM  */
56*7917SReza.Sabdar@Sun.COM tlm_buffers_t *
tlm_allocate_buffers(boolean_t write,long xfer_size)57*7917SReza.Sabdar@Sun.COM tlm_allocate_buffers(boolean_t write, long xfer_size)
58*7917SReza.Sabdar@Sun.COM {
59*7917SReza.Sabdar@Sun.COM 	tlm_buffers_t *buffers = ndmp_malloc(sizeof (tlm_buffers_t));
60*7917SReza.Sabdar@Sun.COM 	int	buf;
61*7917SReza.Sabdar@Sun.COM 
62*7917SReza.Sabdar@Sun.COM 	if (buffers == 0)
63*7917SReza.Sabdar@Sun.COM 		return (0);
64*7917SReza.Sabdar@Sun.COM 
65*7917SReza.Sabdar@Sun.COM 	for (buf = 0; buf < TLM_TAPE_BUFFERS; buf++) {
66*7917SReza.Sabdar@Sun.COM 		buffers->tbs_buffer[buf].tb_buffer_data =
67*7917SReza.Sabdar@Sun.COM 		    ndmp_malloc(xfer_size);
68*7917SReza.Sabdar@Sun.COM 		if (buffers->tbs_buffer[buf].tb_buffer_data == 0) {
69*7917SReza.Sabdar@Sun.COM 			int	i;
70*7917SReza.Sabdar@Sun.COM 
71*7917SReza.Sabdar@Sun.COM 			/* Memory allocation failed. Give everything back */
72*7917SReza.Sabdar@Sun.COM 			for (i = 0; i < buf; i++)
73*7917SReza.Sabdar@Sun.COM 				free(buffers->tbs_buffer[i].tb_buffer_data);
74*7917SReza.Sabdar@Sun.COM 
75*7917SReza.Sabdar@Sun.COM 			free(buffers);
76*7917SReza.Sabdar@Sun.COM 			return (0);
77*7917SReza.Sabdar@Sun.COM 		} else {
78*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_buffer_size = (write)
79*7917SReza.Sabdar@Sun.COM 			    ? xfer_size : 0;
80*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_full = FALSE;
81*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_eof = FALSE;
82*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_eot = FALSE;
83*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_errno = 0;
84*7917SReza.Sabdar@Sun.COM 			buffers->tbs_buffer[buf].tb_buffer_spot = 0;
85*7917SReza.Sabdar@Sun.COM 		}
86*7917SReza.Sabdar@Sun.COM 
87*7917SReza.Sabdar@Sun.COM 	}
88*7917SReza.Sabdar@Sun.COM 
89*7917SReza.Sabdar@Sun.COM 	(void) mutex_init(&buffers->tbs_mtx, 0, NULL);
90*7917SReza.Sabdar@Sun.COM 	(void) cond_init(&buffers->tbs_in_cv, 0, NULL);
91*7917SReza.Sabdar@Sun.COM 	(void) cond_init(&buffers->tbs_out_cv, 0, NULL);
92*7917SReza.Sabdar@Sun.COM 
93*7917SReza.Sabdar@Sun.COM 	buffers->tbs_data_transfer_size = xfer_size;
94*7917SReza.Sabdar@Sun.COM 	buffers->tbs_ref = 1;
95*7917SReza.Sabdar@Sun.COM 	return (buffers);
96*7917SReza.Sabdar@Sun.COM }
97*7917SReza.Sabdar@Sun.COM 
98*7917SReza.Sabdar@Sun.COM /*
99*7917SReza.Sabdar@Sun.COM  * tlm_release_buffers
100*7917SReza.Sabdar@Sun.COM  *
101*7917SReza.Sabdar@Sun.COM  * give all memory back to the OS
102*7917SReza.Sabdar@Sun.COM  */
103*7917SReza.Sabdar@Sun.COM void
tlm_release_buffers(tlm_buffers_t * buffers)104*7917SReza.Sabdar@Sun.COM tlm_release_buffers(tlm_buffers_t *buffers)
105*7917SReza.Sabdar@Sun.COM {
106*7917SReza.Sabdar@Sun.COM 	int i;
107*7917SReza.Sabdar@Sun.COM 
108*7917SReza.Sabdar@Sun.COM 	if (buffers != NULL) {
109*7917SReza.Sabdar@Sun.COM 		tlm_buffer_release_in_buf(buffers);
110*7917SReza.Sabdar@Sun.COM 		tlm_buffer_release_out_buf(buffers);
111*7917SReza.Sabdar@Sun.COM 
112*7917SReza.Sabdar@Sun.COM 		(void) mutex_lock(&buffers->tbs_mtx);
113*7917SReza.Sabdar@Sun.COM 
114*7917SReza.Sabdar@Sun.COM 		if (--buffers->tbs_ref <= 0) {
115*7917SReza.Sabdar@Sun.COM 			for (i = 0; i < TLM_TAPE_BUFFERS; i++)
116*7917SReza.Sabdar@Sun.COM 				free(buffers->tbs_buffer[i].tb_buffer_data);
117*7917SReza.Sabdar@Sun.COM 
118*7917SReza.Sabdar@Sun.COM 		}
119*7917SReza.Sabdar@Sun.COM 
120*7917SReza.Sabdar@Sun.COM 		(void) cond_destroy(&buffers->tbs_in_cv);
121*7917SReza.Sabdar@Sun.COM 		(void) cond_destroy(&buffers->tbs_out_cv);
122*7917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&buffers->tbs_mtx);
123*7917SReza.Sabdar@Sun.COM 		(void) mutex_destroy(&buffers->tbs_mtx);
124*7917SReza.Sabdar@Sun.COM 		free(buffers);
125*7917SReza.Sabdar@Sun.COM 	}
126*7917SReza.Sabdar@Sun.COM }
127*7917SReza.Sabdar@Sun.COM 
128*7917SReza.Sabdar@Sun.COM /*
129*7917SReza.Sabdar@Sun.COM  * tlm_buffer_mark_empty
130*7917SReza.Sabdar@Sun.COM  *
131*7917SReza.Sabdar@Sun.COM  * Mark a buffer empty and clear its flags. No lock is take here:
132*7917SReza.Sabdar@Sun.COM  * the buffer should be marked empty before it is released for use
133*7917SReza.Sabdar@Sun.COM  * by another thread.
134*7917SReza.Sabdar@Sun.COM  */
135*7917SReza.Sabdar@Sun.COM void
tlm_buffer_mark_empty(tlm_buffer_t * buf)136*7917SReza.Sabdar@Sun.COM tlm_buffer_mark_empty(tlm_buffer_t *buf)
137*7917SReza.Sabdar@Sun.COM {
138*7917SReza.Sabdar@Sun.COM 	if (buf == NULL)
139*7917SReza.Sabdar@Sun.COM 		return;
140*7917SReza.Sabdar@Sun.COM 
141*7917SReza.Sabdar@Sun.COM 	buf->tb_full = buf->tb_eof = buf->tb_eot = FALSE;
142*7917SReza.Sabdar@Sun.COM 	buf->tb_errno = 0;
143*7917SReza.Sabdar@Sun.COM }
144*7917SReza.Sabdar@Sun.COM 
145*7917SReza.Sabdar@Sun.COM 
146*7917SReza.Sabdar@Sun.COM /*
147*7917SReza.Sabdar@Sun.COM  * tlm_buffer_advance_in_idx
148*7917SReza.Sabdar@Sun.COM  *
149*7917SReza.Sabdar@Sun.COM  * Advance the input index of the buffers(round-robin) and return pointer
150*7917SReza.Sabdar@Sun.COM  * to the next buffer in the buffer pool.
151*7917SReza.Sabdar@Sun.COM  */
152*7917SReza.Sabdar@Sun.COM tlm_buffer_t *
tlm_buffer_advance_in_idx(tlm_buffers_t * bufs)153*7917SReza.Sabdar@Sun.COM tlm_buffer_advance_in_idx(tlm_buffers_t *bufs)
154*7917SReza.Sabdar@Sun.COM {
155*7917SReza.Sabdar@Sun.COM 	if (bufs == NULL)
156*7917SReza.Sabdar@Sun.COM 		return (NULL);
157*7917SReza.Sabdar@Sun.COM 
158*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
159*7917SReza.Sabdar@Sun.COM 	if (++bufs->tbs_buffer_in >= TLM_TAPE_BUFFERS)
160*7917SReza.Sabdar@Sun.COM 		bufs->tbs_buffer_in = 0;
161*7917SReza.Sabdar@Sun.COM 
162*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
163*7917SReza.Sabdar@Sun.COM 	return (&bufs->tbs_buffer[bufs->tbs_buffer_in]);
164*7917SReza.Sabdar@Sun.COM }
165*7917SReza.Sabdar@Sun.COM 
166*7917SReza.Sabdar@Sun.COM 
167*7917SReza.Sabdar@Sun.COM /*
168*7917SReza.Sabdar@Sun.COM  * tlm_buffer_advance_out_idx
169*7917SReza.Sabdar@Sun.COM  *
170*7917SReza.Sabdar@Sun.COM  * Advance the output index of the buffers(round-robin) and return pointer
171*7917SReza.Sabdar@Sun.COM  * to the next buffer in the buffer pool.
172*7917SReza.Sabdar@Sun.COM  */
173*7917SReza.Sabdar@Sun.COM tlm_buffer_t *
tlm_buffer_advance_out_idx(tlm_buffers_t * bufs)174*7917SReza.Sabdar@Sun.COM tlm_buffer_advance_out_idx(tlm_buffers_t *bufs)
175*7917SReza.Sabdar@Sun.COM {
176*7917SReza.Sabdar@Sun.COM 	if (bufs == NULL)
177*7917SReza.Sabdar@Sun.COM 		return (NULL);
178*7917SReza.Sabdar@Sun.COM 
179*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
180*7917SReza.Sabdar@Sun.COM 	if (++bufs->tbs_buffer_out >= TLM_TAPE_BUFFERS)
181*7917SReza.Sabdar@Sun.COM 		bufs->tbs_buffer_out = 0;
182*7917SReza.Sabdar@Sun.COM 
183*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
184*7917SReza.Sabdar@Sun.COM 	return (&bufs->tbs_buffer[bufs->tbs_buffer_out]);
185*7917SReza.Sabdar@Sun.COM }
186*7917SReza.Sabdar@Sun.COM 
187*7917SReza.Sabdar@Sun.COM 
188*7917SReza.Sabdar@Sun.COM /*
189*7917SReza.Sabdar@Sun.COM  * tlm_buffer_in_buf
190*7917SReza.Sabdar@Sun.COM  *
191*7917SReza.Sabdar@Sun.COM  * Return pointer to the next buffer in the buffer pool.
192*7917SReza.Sabdar@Sun.COM  */
193*7917SReza.Sabdar@Sun.COM tlm_buffer_t *
tlm_buffer_in_buf(tlm_buffers_t * bufs,int * idx)194*7917SReza.Sabdar@Sun.COM tlm_buffer_in_buf(tlm_buffers_t *bufs, int *idx)
195*7917SReza.Sabdar@Sun.COM {
196*7917SReza.Sabdar@Sun.COM 	tlm_buffer_t *ret;
197*7917SReza.Sabdar@Sun.COM 
198*7917SReza.Sabdar@Sun.COM 	if (bufs == NULL)
199*7917SReza.Sabdar@Sun.COM 		return (NULL);
200*7917SReza.Sabdar@Sun.COM 
201*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
202*7917SReza.Sabdar@Sun.COM 	ret = &bufs->tbs_buffer[bufs->tbs_buffer_in];
203*7917SReza.Sabdar@Sun.COM 	if (idx)
204*7917SReza.Sabdar@Sun.COM 		*idx = bufs->tbs_buffer_in;
205*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
206*7917SReza.Sabdar@Sun.COM 	return (ret);
207*7917SReza.Sabdar@Sun.COM }
208*7917SReza.Sabdar@Sun.COM 
209*7917SReza.Sabdar@Sun.COM 
210*7917SReza.Sabdar@Sun.COM /*
211*7917SReza.Sabdar@Sun.COM  * tlm_buffer_out_buf
212*7917SReza.Sabdar@Sun.COM  *
213*7917SReza.Sabdar@Sun.COM  * Return pointer to the next buffer in the buffer pool.
214*7917SReza.Sabdar@Sun.COM  */
215*7917SReza.Sabdar@Sun.COM tlm_buffer_t *
tlm_buffer_out_buf(tlm_buffers_t * bufs,int * idx)216*7917SReza.Sabdar@Sun.COM tlm_buffer_out_buf(tlm_buffers_t *bufs, int *idx)
217*7917SReza.Sabdar@Sun.COM {
218*7917SReza.Sabdar@Sun.COM 	tlm_buffer_t *ret;
219*7917SReza.Sabdar@Sun.COM 
220*7917SReza.Sabdar@Sun.COM 	if (bufs == NULL)
221*7917SReza.Sabdar@Sun.COM 		return (NULL);
222*7917SReza.Sabdar@Sun.COM 
223*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
224*7917SReza.Sabdar@Sun.COM 	ret = &bufs->tbs_buffer[bufs->tbs_buffer_out];
225*7917SReza.Sabdar@Sun.COM 	if (idx)
226*7917SReza.Sabdar@Sun.COM 		*idx = bufs->tbs_buffer_out;
227*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
228*7917SReza.Sabdar@Sun.COM 	return (ret);
229*7917SReza.Sabdar@Sun.COM }
230*7917SReza.Sabdar@Sun.COM 
231*7917SReza.Sabdar@Sun.COM 
232*7917SReza.Sabdar@Sun.COM /*
233*7917SReza.Sabdar@Sun.COM  * tlm_buffer_release_in_buf
234*7917SReza.Sabdar@Sun.COM  *
235*7917SReza.Sabdar@Sun.COM  * Another buffer is filled. Wake up the consumer if it's waiting for it.
236*7917SReza.Sabdar@Sun.COM  */
237*7917SReza.Sabdar@Sun.COM void
tlm_buffer_release_in_buf(tlm_buffers_t * bufs)238*7917SReza.Sabdar@Sun.COM tlm_buffer_release_in_buf(tlm_buffers_t *bufs)
239*7917SReza.Sabdar@Sun.COM {
240*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
241*7917SReza.Sabdar@Sun.COM 	bufs->tbs_flags |= TLM_BUF_IN_READY;
242*7917SReza.Sabdar@Sun.COM 	(void) cond_signal(&bufs->tbs_in_cv);
243*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
244*7917SReza.Sabdar@Sun.COM }
245*7917SReza.Sabdar@Sun.COM 
246*7917SReza.Sabdar@Sun.COM 
247*7917SReza.Sabdar@Sun.COM /*
248*7917SReza.Sabdar@Sun.COM  * tlm_buffer_release_out_buf
249*7917SReza.Sabdar@Sun.COM  *
250*7917SReza.Sabdar@Sun.COM  * A buffer is used. Wake up the producer to re-fill a buffer if it's waiting
251*7917SReza.Sabdar@Sun.COM  * for the buffer to be used.
252*7917SReza.Sabdar@Sun.COM  */
253*7917SReza.Sabdar@Sun.COM void
tlm_buffer_release_out_buf(tlm_buffers_t * bufs)254*7917SReza.Sabdar@Sun.COM tlm_buffer_release_out_buf(tlm_buffers_t *bufs)
255*7917SReza.Sabdar@Sun.COM {
256*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
257*7917SReza.Sabdar@Sun.COM 	bufs->tbs_flags |= TLM_BUF_OUT_READY;
258*7917SReza.Sabdar@Sun.COM 	(void) cond_signal(&bufs->tbs_out_cv);
259*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
260*7917SReza.Sabdar@Sun.COM }
261*7917SReza.Sabdar@Sun.COM 
262*7917SReza.Sabdar@Sun.COM /*
263*7917SReza.Sabdar@Sun.COM  * tlm_buffer_in_buf_wait
264*7917SReza.Sabdar@Sun.COM  *
265*7917SReza.Sabdar@Sun.COM  * Wait for the input buffer to get available.
266*7917SReza.Sabdar@Sun.COM  */
267*7917SReza.Sabdar@Sun.COM void
tlm_buffer_in_buf_wait(tlm_buffers_t * bufs)268*7917SReza.Sabdar@Sun.COM tlm_buffer_in_buf_wait(tlm_buffers_t *bufs)
269*7917SReza.Sabdar@Sun.COM 
270*7917SReza.Sabdar@Sun.COM {
271*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
272*7917SReza.Sabdar@Sun.COM 
273*7917SReza.Sabdar@Sun.COM 	while ((bufs->tbs_flags & TLM_BUF_IN_READY) == 0)
274*7917SReza.Sabdar@Sun.COM 		(void) cond_wait(&bufs->tbs_in_cv, &bufs->tbs_mtx);
275*7917SReza.Sabdar@Sun.COM 
276*7917SReza.Sabdar@Sun.COM 	bufs->tbs_flags &= ~TLM_BUF_IN_READY;
277*7917SReza.Sabdar@Sun.COM 
278*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
279*7917SReza.Sabdar@Sun.COM }
280*7917SReza.Sabdar@Sun.COM 
281*7917SReza.Sabdar@Sun.COM /*
282*7917SReza.Sabdar@Sun.COM  * tlm_buffer_setup_timer
283*7917SReza.Sabdar@Sun.COM  *
284*7917SReza.Sabdar@Sun.COM  * Set up the time out value.
285*7917SReza.Sabdar@Sun.COM  */
286*7917SReza.Sabdar@Sun.COM static inline void
tlm_buffer_setup_timer(timestruc_t * timo,unsigned milli_timo)287*7917SReza.Sabdar@Sun.COM tlm_buffer_setup_timer(timestruc_t *timo, unsigned milli_timo)
288*7917SReza.Sabdar@Sun.COM {
289*7917SReza.Sabdar@Sun.COM 	if (milli_timo == 0)
290*7917SReza.Sabdar@Sun.COM 		milli_timo = 1;
291*7917SReza.Sabdar@Sun.COM 
292*7917SReza.Sabdar@Sun.COM 	if (milli_timo / 1000)
293*7917SReza.Sabdar@Sun.COM 		timo->tv_sec = (milli_timo / 1000);
294*7917SReza.Sabdar@Sun.COM 	else
295*7917SReza.Sabdar@Sun.COM 		timo->tv_sec = 0;
296*7917SReza.Sabdar@Sun.COM 	timo->tv_nsec = (milli_timo % 1000) * 1000000L;
297*7917SReza.Sabdar@Sun.COM }
298*7917SReza.Sabdar@Sun.COM 
299*7917SReza.Sabdar@Sun.COM 
300*7917SReza.Sabdar@Sun.COM /*
301*7917SReza.Sabdar@Sun.COM  * tlm_buffer_in_buf_timed_wait
302*7917SReza.Sabdar@Sun.COM  *
303*7917SReza.Sabdar@Sun.COM  * Wait for the input buffer to get ready with a time out.
304*7917SReza.Sabdar@Sun.COM  */
305*7917SReza.Sabdar@Sun.COM void
tlm_buffer_in_buf_timed_wait(tlm_buffers_t * bufs,unsigned int milli_timo)306*7917SReza.Sabdar@Sun.COM tlm_buffer_in_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo)
307*7917SReza.Sabdar@Sun.COM 
308*7917SReza.Sabdar@Sun.COM {
309*7917SReza.Sabdar@Sun.COM 	timestruc_t timo;
310*7917SReza.Sabdar@Sun.COM 
311*7917SReza.Sabdar@Sun.COM 	tlm_buffer_setup_timer(&timo, milli_timo);
312*7917SReza.Sabdar@Sun.COM 
313*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
314*7917SReza.Sabdar@Sun.COM 
315*7917SReza.Sabdar@Sun.COM 	(void) cond_reltimedwait(&bufs->tbs_in_cv, &bufs->tbs_mtx, &timo);
316*7917SReza.Sabdar@Sun.COM 
317*7917SReza.Sabdar@Sun.COM 	/*
318*7917SReza.Sabdar@Sun.COM 	 * TLM_BUF_IN_READY doesn't matter for timedwait but clear
319*7917SReza.Sabdar@Sun.COM 	 * it here so that cond_wait doesn't get the wrong result.
320*7917SReza.Sabdar@Sun.COM 	 */
321*7917SReza.Sabdar@Sun.COM 	bufs->tbs_flags &= ~TLM_BUF_IN_READY;
322*7917SReza.Sabdar@Sun.COM 
323*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
324*7917SReza.Sabdar@Sun.COM }
325*7917SReza.Sabdar@Sun.COM 
326*7917SReza.Sabdar@Sun.COM 
327*7917SReza.Sabdar@Sun.COM /*
328*7917SReza.Sabdar@Sun.COM  * tlm_buffer_out_buf_timed_wait
329*7917SReza.Sabdar@Sun.COM  *
330*7917SReza.Sabdar@Sun.COM  * Wait for the output buffer to get ready with a time out.
331*7917SReza.Sabdar@Sun.COM  */
332*7917SReza.Sabdar@Sun.COM void
tlm_buffer_out_buf_timed_wait(tlm_buffers_t * bufs,unsigned int milli_timo)333*7917SReza.Sabdar@Sun.COM tlm_buffer_out_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo)
334*7917SReza.Sabdar@Sun.COM {
335*7917SReza.Sabdar@Sun.COM 	timestruc_t timo;
336*7917SReza.Sabdar@Sun.COM 
337*7917SReza.Sabdar@Sun.COM 	tlm_buffer_setup_timer(&timo, milli_timo);
338*7917SReza.Sabdar@Sun.COM 
339*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&bufs->tbs_mtx);
340*7917SReza.Sabdar@Sun.COM 
341*7917SReza.Sabdar@Sun.COM 	(void) cond_reltimedwait(&bufs->tbs_out_cv, &bufs->tbs_mtx, &timo);
342*7917SReza.Sabdar@Sun.COM 
343*7917SReza.Sabdar@Sun.COM 	/*
344*7917SReza.Sabdar@Sun.COM 	 * TLM_BUF_OUT_READY doesn't matter for timedwait but clear
345*7917SReza.Sabdar@Sun.COM 	 * it here so that cond_wait doesn't get the wrong result.
346*7917SReza.Sabdar@Sun.COM 	 */
347*7917SReza.Sabdar@Sun.COM 	bufs->tbs_flags &= ~TLM_BUF_OUT_READY;
348*7917SReza.Sabdar@Sun.COM 
349*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&bufs->tbs_mtx);
350*7917SReza.Sabdar@Sun.COM }
351*7917SReza.Sabdar@Sun.COM 
352*7917SReza.Sabdar@Sun.COM 
353*7917SReza.Sabdar@Sun.COM /*
354*7917SReza.Sabdar@Sun.COM  * tlm_cmd_wait
355*7917SReza.Sabdar@Sun.COM  *
356*7917SReza.Sabdar@Sun.COM  * TLM command synchronization typically use by command
357*7917SReza.Sabdar@Sun.COM  * parent threads to wait for launched threads to initialize.
358*7917SReza.Sabdar@Sun.COM  */
359*7917SReza.Sabdar@Sun.COM void
tlm_cmd_wait(tlm_cmd_t * cmd,uint32_t event_type)360*7917SReza.Sabdar@Sun.COM tlm_cmd_wait(tlm_cmd_t *cmd, uint32_t event_type)
361*7917SReza.Sabdar@Sun.COM {
362*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cmd->tc_mtx);
363*7917SReza.Sabdar@Sun.COM 
364*7917SReza.Sabdar@Sun.COM 	while ((cmd->tc_flags & event_type) == 0)
365*7917SReza.Sabdar@Sun.COM 		(void) cond_wait(&cmd->tc_cv, &cmd->tc_mtx);
366*7917SReza.Sabdar@Sun.COM 
367*7917SReza.Sabdar@Sun.COM 	cmd->tc_flags &= ~event_type;
368*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cmd->tc_mtx);
369*7917SReza.Sabdar@Sun.COM }
370*7917SReza.Sabdar@Sun.COM 
371*7917SReza.Sabdar@Sun.COM 
372*7917SReza.Sabdar@Sun.COM /*
373*7917SReza.Sabdar@Sun.COM  * tlm_cmd_signal
374*7917SReza.Sabdar@Sun.COM  *
375*7917SReza.Sabdar@Sun.COM  * TLM command synchronization typically use by launched threads
376*7917SReza.Sabdar@Sun.COM  * to unleash the parent thread.
377*7917SReza.Sabdar@Sun.COM  */
378*7917SReza.Sabdar@Sun.COM void
tlm_cmd_signal(tlm_cmd_t * cmd,uint32_t event_type)379*7917SReza.Sabdar@Sun.COM tlm_cmd_signal(tlm_cmd_t *cmd, uint32_t event_type)
380*7917SReza.Sabdar@Sun.COM {
381*7917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cmd->tc_mtx);
382*7917SReza.Sabdar@Sun.COM 
383*7917SReza.Sabdar@Sun.COM 	cmd->tc_flags |= event_type;
384*7917SReza.Sabdar@Sun.COM 	(void) cond_signal(&cmd->tc_cv);
385*7917SReza.Sabdar@Sun.COM 
386*7917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cmd->tc_mtx);
387*7917SReza.Sabdar@Sun.COM }
388