1243730Srwatson/*-
2243730Srwatson * Copyright (c) 2009-2010 The FreeBSD Foundation
3243730Srwatson * All rights reserved.
4243730Srwatson *
5243730Srwatson * This software was developed by Pawel Jakub Dawidek under sponsorship from
6243730Srwatson * the FreeBSD Foundation.
7243730Srwatson *
8243730Srwatson * Redistribution and use in source and binary forms, with or without
9243730Srwatson * modification, are permitted provided that the following conditions
10243730Srwatson * are met:
11243730Srwatson * 1. Redistributions of source code must retain the above copyright
12243730Srwatson *    notice, this list of conditions and the following disclaimer.
13243730Srwatson * 2. Redistributions in binary form must reproduce the above copyright
14243730Srwatson *    notice, this list of conditions and the following disclaimer in the
15243730Srwatson *    documentation and/or other materials provided with the distribution.
16243730Srwatson *
17243730Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18243730Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19243730Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20243730Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21243730Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22243730Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23243730Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24243730Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25243730Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26243730Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27243730Srwatson * SUCH DAMAGE.
28243730Srwatson *
29243734Srwatson * $P4: //depot/projects/trustedbsd/openbsm/bin/auditdistd/synch.h#3 $
30243730Srwatson */
31243730Srwatson
32243730Srwatson#ifndef	_SYNCH_H_
33243730Srwatson#define	_SYNCH_H_
34243730Srwatson
35243730Srwatson#include <errno.h>
36243730Srwatson#include <pthread.h>
37243730Srwatson#ifdef HAVE_PTHREAD_NP_H
38243730Srwatson#include <pthread_np.h>
39243730Srwatson#endif
40243730Srwatson#include <stdbool.h>
41243730Srwatson#include <time.h>
42243730Srwatson
43243734Srwatson#include "pjdlog.h"
44243730Srwatson
45243730Srwatson#ifndef	PJDLOG_ASSERT
46243730Srwatson#include <assert.h>
47243730Srwatson#define	PJDLOG_ASSERT(...)	assert(__VA_ARGS__)
48243730Srwatson#endif
49243730Srwatson
50243730Srwatsonstatic __inline void
51243730Srwatsonmtx_init(pthread_mutex_t *lock)
52243730Srwatson{
53243730Srwatson	int error;
54243730Srwatson
55243730Srwatson	error = pthread_mutex_init(lock, NULL);
56243730Srwatson	PJDLOG_ASSERT(error == 0);
57243730Srwatson}
58243730Srwatsonstatic __inline void
59243730Srwatsonmtx_destroy(pthread_mutex_t *lock)
60243730Srwatson{
61243730Srwatson	int error;
62243730Srwatson
63243730Srwatson	error = pthread_mutex_destroy(lock);
64243730Srwatson	PJDLOG_ASSERT(error == 0);
65243730Srwatson}
66243730Srwatsonstatic __inline void
67243730Srwatsonmtx_lock(pthread_mutex_t *lock)
68243730Srwatson{
69243730Srwatson	int error;
70243730Srwatson
71243730Srwatson	error = pthread_mutex_lock(lock);
72243730Srwatson	PJDLOG_ASSERT(error == 0);
73243730Srwatson}
74243730Srwatsonstatic __inline bool
75243730Srwatsonmtx_trylock(pthread_mutex_t *lock)
76243730Srwatson{
77243730Srwatson	int error;
78243730Srwatson
79243730Srwatson	error = pthread_mutex_trylock(lock);
80243730Srwatson	PJDLOG_ASSERT(error == 0 || error == EBUSY);
81243730Srwatson	return (error == 0);
82243730Srwatson}
83243730Srwatsonstatic __inline void
84243730Srwatsonmtx_unlock(pthread_mutex_t *lock)
85243730Srwatson{
86243730Srwatson	int error;
87243730Srwatson
88243730Srwatson	error = pthread_mutex_unlock(lock);
89243730Srwatson	PJDLOG_ASSERT(error == 0);
90243730Srwatson}
91243730Srwatsonstatic __inline bool
92243730Srwatsonmtx_owned(pthread_mutex_t *lock)
93243730Srwatson{
94243730Srwatson
95243730Srwatson	return (pthread_mutex_isowned_np(lock) != 0);
96243730Srwatson}
97243730Srwatson
98243730Srwatsonstatic __inline void
99243730Srwatsonrw_init(pthread_rwlock_t *lock)
100243730Srwatson{
101243730Srwatson	int error;
102243730Srwatson
103243730Srwatson	error = pthread_rwlock_init(lock, NULL);
104243730Srwatson	PJDLOG_ASSERT(error == 0);
105243730Srwatson}
106243730Srwatsonstatic __inline void
107243730Srwatsonrw_destroy(pthread_rwlock_t *lock)
108243730Srwatson{
109243730Srwatson	int error;
110243730Srwatson
111243730Srwatson	error = pthread_rwlock_destroy(lock);
112243730Srwatson	PJDLOG_ASSERT(error == 0);
113243730Srwatson}
114243730Srwatsonstatic __inline void
115243730Srwatsonrw_rlock(pthread_rwlock_t *lock)
116243730Srwatson{
117243730Srwatson	int error;
118243730Srwatson
119243730Srwatson	error = pthread_rwlock_rdlock(lock);
120243730Srwatson	PJDLOG_ASSERT(error == 0);
121243730Srwatson}
122243730Srwatsonstatic __inline void
123243730Srwatsonrw_wlock(pthread_rwlock_t *lock)
124243730Srwatson{
125243730Srwatson	int error;
126243730Srwatson
127243730Srwatson	error = pthread_rwlock_wrlock(lock);
128243730Srwatson	PJDLOG_ASSERT(error == 0);
129243730Srwatson}
130243730Srwatsonstatic __inline void
131243730Srwatsonrw_unlock(pthread_rwlock_t *lock)
132243730Srwatson{
133243730Srwatson	int error;
134243730Srwatson
135243730Srwatson	error = pthread_rwlock_unlock(lock);
136243730Srwatson	PJDLOG_ASSERT(error == 0);
137243730Srwatson}
138243730Srwatson
139243730Srwatsonstatic __inline void
140243730Srwatsoncv_init(pthread_cond_t *cv)
141243730Srwatson{
142243730Srwatson	pthread_condattr_t attr;
143243730Srwatson	int error;
144243730Srwatson
145243730Srwatson	error = pthread_condattr_init(&attr);
146243730Srwatson	PJDLOG_ASSERT(error == 0);
147243730Srwatson#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
148243730Srwatson	error = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
149243730Srwatson	PJDLOG_ASSERT(error == 0);
150243730Srwatson#endif
151243730Srwatson	error = pthread_cond_init(cv, &attr);
152243730Srwatson	PJDLOG_ASSERT(error == 0);
153243730Srwatson	error = pthread_condattr_destroy(&attr);
154243730Srwatson	PJDLOG_ASSERT(error == 0);
155243730Srwatson}
156243730Srwatsonstatic __inline void
157243730Srwatsoncv_wait(pthread_cond_t *cv, pthread_mutex_t *lock)
158243730Srwatson{
159243730Srwatson	int error;
160243730Srwatson
161243730Srwatson	error = pthread_cond_wait(cv, lock);
162243730Srwatson	PJDLOG_ASSERT(error == 0);
163243730Srwatson}
164243730Srwatsonstatic __inline bool
165243730Srwatsoncv_timedwait(pthread_cond_t *cv, pthread_mutex_t *lock, int timeout)
166243730Srwatson{
167243730Srwatson	struct timespec ts;
168243730Srwatson	int error;
169243730Srwatson
170243730Srwatson	if (timeout == 0) {
171243730Srwatson		cv_wait(cv, lock);
172243730Srwatson		return (false);
173243730Srwatson	}
174243730Srwatson
175243730Srwatson#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
176243730Srwatson	error = clock_gettime(CLOCK_MONOTONIC, &ts);
177243730Srwatson	PJDLOG_ASSERT(error == 0);
178243730Srwatson	ts.tv_sec += timeout;
179243730Srwatson	error = pthread_cond_timedwait(cv, lock, &ts);
180243730Srwatson#elif HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
181243730Srwatson	ts.tv_sec = timeout;
182243730Srwatson	ts.tv_nsec = 0;
183243730Srwatson	error = pthread_cond_timedwait_relative_np(cv, lock, &ts);
184243730Srwatson#else
185243730Srwatson#error Neither pthread_condattr_setclock nor pthread_cond_timedwait_relative_np is available.
186243730Srwatson#endif
187243730Srwatson	PJDLOG_ASSERT(error == 0 || error == ETIMEDOUT);
188243730Srwatson	return (error == ETIMEDOUT);
189243730Srwatson}
190243730Srwatsonstatic __inline void
191243730Srwatsoncv_signal(pthread_cond_t *cv)
192243730Srwatson{
193243730Srwatson	int error;
194243730Srwatson
195243730Srwatson	error = pthread_cond_signal(cv);
196243730Srwatson	PJDLOG_ASSERT(error == 0);
197243730Srwatson}
198243730Srwatsonstatic __inline void
199243730Srwatsoncv_broadcast(pthread_cond_t *cv)
200243730Srwatson{
201243730Srwatson	int error;
202243730Srwatson
203243730Srwatson	error = pthread_cond_broadcast(cv);
204243730Srwatson	PJDLOG_ASSERT(error == 0);
205243730Srwatson}
206243730Srwatson#endif	/* !_SYNCH_H_ */
207