xref: /titanic_51/usr/src/cmd/syslogd/queue.c (revision 0ea5e3a571e3da934507bdd32924d11659c70704)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0ea5e3a5Sjjj  * Common Development and Distribution License (the "License").
6*0ea5e3a5Sjjj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*0ea5e3a5Sjjj  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <pthread.h>
297c478bd9Sstevel@tonic-gate #include <malloc.h>
307c478bd9Sstevel@tonic-gate #include <memory.h>
317c478bd9Sstevel@tonic-gate #include "dataq.h"
327c478bd9Sstevel@tonic-gate #include <assert.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifndef NDEBUG
357c478bd9Sstevel@tonic-gate static int
367c478bd9Sstevel@tonic-gate dataq_check(dataq_t *ptr)	/* call while holding lock! */
377c478bd9Sstevel@tonic-gate {
387c478bd9Sstevel@tonic-gate 	assert(ptr->num_data == ll_check(&ptr->data));
397c478bd9Sstevel@tonic-gate 	assert(ptr->num_waiters == ll_check(&ptr->waiters));
407c478bd9Sstevel@tonic-gate 	return (1);
417c478bd9Sstevel@tonic-gate }
427c478bd9Sstevel@tonic-gate #endif
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate int
457c478bd9Sstevel@tonic-gate dataq_init(dataq_t *ptr)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	ptr->num_data = 0;
487c478bd9Sstevel@tonic-gate 	ptr->num_waiters = 0;
497c478bd9Sstevel@tonic-gate 	ll_init(&ptr->data);
507c478bd9Sstevel@tonic-gate 	ll_init(&ptr->waiters);
51*0ea5e3a5Sjjj 	(void) pthread_mutex_init(&ptr->lock, NULL);
527c478bd9Sstevel@tonic-gate 	assert((pthread_mutex_lock(&ptr->lock) == 0) &&
537c478bd9Sstevel@tonic-gate 		(dataq_check(ptr) == 1) &&
547c478bd9Sstevel@tonic-gate 		(pthread_mutex_unlock(&ptr->lock) == 0));
557c478bd9Sstevel@tonic-gate 	return (0);
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate int
597c478bd9Sstevel@tonic-gate dataq_enqueue(dataq_t *dataq, void *in)
607c478bd9Sstevel@tonic-gate {
617c478bd9Sstevel@tonic-gate 	dataq_data_t *ptr = (dataq_data_t *)malloc(sizeof (*ptr));
627c478bd9Sstevel@tonic-gate 	dataq_waiter_t *sleeper;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
657c478bd9Sstevel@tonic-gate 		return (-1);
667c478bd9Sstevel@tonic-gate 	ptr->data = in;
67*0ea5e3a5Sjjj 	(void) pthread_mutex_lock(&dataq->lock);
687c478bd9Sstevel@tonic-gate 	assert(dataq_check(dataq));
697c478bd9Sstevel@tonic-gate 	ll_enqueue(&dataq->data, &ptr->list);
707c478bd9Sstevel@tonic-gate 	dataq->num_data++;
717c478bd9Sstevel@tonic-gate 	if (dataq->num_waiters) {
727c478bd9Sstevel@tonic-gate 		/*LINTED*/
737c478bd9Sstevel@tonic-gate 		sleeper = (dataq_waiter_t *)ll_peek(&dataq->waiters);
747c478bd9Sstevel@tonic-gate 		sleeper->wakeup = 1;
75*0ea5e3a5Sjjj 		(void) pthread_cond_signal(&sleeper->cv);
767c478bd9Sstevel@tonic-gate 	}
777c478bd9Sstevel@tonic-gate 	assert(dataq_check(dataq));
78*0ea5e3a5Sjjj 	(void) pthread_mutex_unlock(&dataq->lock);
797c478bd9Sstevel@tonic-gate 	return (0);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate int
837c478bd9Sstevel@tonic-gate dataq_dequeue(dataq_t *dataq, void **outptr, int try)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate 	dataq_data_t *dptr;
867c478bd9Sstevel@tonic-gate 	dataq_waiter_t *sleeper;
877c478bd9Sstevel@tonic-gate 
88*0ea5e3a5Sjjj 	(void) pthread_mutex_lock(&dataq->lock);
897c478bd9Sstevel@tonic-gate 	if ((dataq->num_waiters > 0) ||
907c478bd9Sstevel@tonic-gate 	    ((dptr = (dataq_data_t *)ll_dequeue(&dataq->data)) == NULL)) {
917c478bd9Sstevel@tonic-gate 		dataq_waiter_t wait;
927c478bd9Sstevel@tonic-gate 		if (try) {
93*0ea5e3a5Sjjj 			(void) pthread_mutex_unlock(&dataq->lock);
947c478bd9Sstevel@tonic-gate 			return (1);
957c478bd9Sstevel@tonic-gate 		}
967c478bd9Sstevel@tonic-gate 		wait.wakeup = 0;
97*0ea5e3a5Sjjj 		(void) pthread_cond_init(&wait.cv, NULL);
987c478bd9Sstevel@tonic-gate 		dataq->num_waiters++;
997c478bd9Sstevel@tonic-gate 		ll_enqueue(&dataq->waiters, &wait.list);
1007c478bd9Sstevel@tonic-gate 		while (wait.wakeup == 0)
101*0ea5e3a5Sjjj 			(void) pthread_cond_wait(&wait.cv, &dataq->lock);
102*0ea5e3a5Sjjj 		(void) ll_dequeue(&dataq->waiters);
1037c478bd9Sstevel@tonic-gate 		dataq->num_waiters--;
104*0ea5e3a5Sjjj 		(void) pthread_cond_destroy(&wait.cv);
1057c478bd9Sstevel@tonic-gate 		dptr = (dataq_data_t *)ll_dequeue(&dataq->data);
1067c478bd9Sstevel@tonic-gate 	}
1077c478bd9Sstevel@tonic-gate 	dataq->num_data--;
1087c478bd9Sstevel@tonic-gate 	if (dataq->num_data && dataq->num_waiters) {
1097c478bd9Sstevel@tonic-gate 		/*LINTED*/
1107c478bd9Sstevel@tonic-gate 		sleeper = (dataq_waiter_t *)ll_peek(&dataq->waiters);
1117c478bd9Sstevel@tonic-gate 		sleeper->wakeup = 1;
112*0ea5e3a5Sjjj 		(void) pthread_cond_signal(&sleeper->cv);
1137c478bd9Sstevel@tonic-gate 	}
114*0ea5e3a5Sjjj 	(void) pthread_mutex_unlock(&dataq->lock);
1157c478bd9Sstevel@tonic-gate 	*outptr = dptr->data;
1167c478bd9Sstevel@tonic-gate 	free(dptr);
1177c478bd9Sstevel@tonic-gate 	return (0);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate static void
1217c478bd9Sstevel@tonic-gate dataq_data_destroy(void * p)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate 	dataq_data_t *d = (dataq_data_t *)p;
1247c478bd9Sstevel@tonic-gate 	free(d->data);
1257c478bd9Sstevel@tonic-gate 	free(d);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static void
1297c478bd9Sstevel@tonic-gate dataq_waiters_destroy(void * p)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	dataq_waiter_t *d = (dataq_waiter_t *)p;
132*0ea5e3a5Sjjj 	(void) pthread_cond_destroy(&d->cv);
1337c478bd9Sstevel@tonic-gate 	free(d);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate int
1377c478bd9Sstevel@tonic-gate dataq_destroy(dataq_t *dataq)
1387c478bd9Sstevel@tonic-gate {
139*0ea5e3a5Sjjj 	(void) pthread_mutex_destroy(&dataq->lock);
1407c478bd9Sstevel@tonic-gate 	ll_mapf(&dataq->data, dataq_data_destroy);
1417c478bd9Sstevel@tonic-gate 	ll_mapf(&dataq->waiters, dataq_waiters_destroy);
1427c478bd9Sstevel@tonic-gate 	return (0);
1437c478bd9Sstevel@tonic-gate }
144