4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
36 dataq_check(dataq_t
*ptr
) /* call while holding lock! */
38 assert(ptr
->num_data
== ll_check(&ptr
->data
));
39 assert(ptr
->num_waiters
== ll_check(&ptr
->waiters
));
45 dataq_init(dataq_t
*ptr
)
50 ll_init(&ptr
->waiters
);
51 (void) pthread_mutex_init(&ptr
->lock
, NULL
);
52 assert((pthread_mutex_lock(&ptr
->lock
) == 0) &&
53 (dataq_check(ptr
) == 1) &&
54 (pthread_mutex_unlock(&ptr
->lock
) == 0));
59 dataq_enqueue(dataq_t
*dataq
, void *in
)
61 dataq_data_t
*ptr
= (dataq_data_t
*)malloc(sizeof (*ptr
));
62 dataq_waiter_t
*sleeper
;
67 (void) pthread_mutex_lock(&dataq
->lock
);
68 assert(dataq_check(dataq
));
69 ll_enqueue(&dataq
->data
, &ptr
->list
);
71 if (dataq
->num_waiters
) {
73 sleeper
= (dataq_waiter_t
*)ll_peek(&dataq
->waiters
);
75 (void) pthread_cond_signal(&sleeper
->cv
);
77 assert(dataq_check(dataq
));
78 (void) pthread_mutex_unlock(&dataq
->lock
);
83 dataq_dequeue(dataq_t
*dataq
, void **outptr
, int try)
86 dataq_waiter_t
*sleeper
;
88 (void) pthread_mutex_lock(&dataq
->lock
);
89 if ((dataq
->num_waiters
> 0) ||
90 ((dptr
= (dataq_data_t
*)ll_dequeue(&dataq
->data
)) == NULL
)) {
93 (void) pthread_mutex_unlock(&dataq
->lock
);
97 (void) pthread_cond_init(&wait
.cv
, NULL
);
99 ll_enqueue(&dataq
->waiters
, &wait
.list
);
100 while (wait
.wakeup
== 0)
101 (void) pthread_cond_wait(&wait
.cv
, &dataq
->lock
);
102 (void) ll_dequeue(&dataq
->waiters
);
103 dataq
->num_waiters
--;
104 (void) pthread_cond_destroy(&wait
.cv
);
105 dptr
= (dataq_data_t
*)ll_dequeue(&dataq
->data
);
108 if (dataq
->num_data
&& dataq
->num_waiters
) {
110 sleeper
= (dataq_waiter_t
*)ll_peek(&dataq
->waiters
);
112 (void) pthread_cond_signal(&sleeper
->cv
);
114 (void) pthread_mutex_unlock(&dataq
->lock
);
115 *outptr
= dptr
->data
;
121 dataq_data_destroy(void * p
)
123 dataq_data_t
*d
= (dataq_data_t
*)p
;
129 dataq_waiters_destroy(void * p
)
131 dataq_waiter_t
*d
= (dataq_waiter_t
*)p
;
132 (void) pthread_cond_destroy(&d
->cv
);
137 dataq_destroy(dataq_t
*dataq
)
139 (void) pthread_mutex_destroy(&dataq
->lock
);
140 ll_mapf(&dataq
->data
, dataq_data_destroy
);
141 ll_mapf(&dataq
->waiters
, dataq_waiters_destroy
);