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 */
29243730Srwatson
30243730Srwatson#ifndef	_SYNCH_H_
31243730Srwatson#define	_SYNCH_H_
32243730Srwatson
33243730Srwatson#include <errno.h>
34243730Srwatson#include <pthread.h>
35243730Srwatson#ifdef HAVE_PTHREAD_NP_H
36243730Srwatson#include <pthread_np.h>
37243730Srwatson#endif
38243730Srwatson#include <stdbool.h>
39243730Srwatson#include <time.h>
40243730Srwatson
41243734Srwatson#include "pjdlog.h"
42243730Srwatson
43243730Srwatson#ifndef	PJDLOG_ASSERT
44243730Srwatson#include <assert.h>
45243730Srwatson#define	PJDLOG_ASSERT(...)	assert(__VA_ARGS__)
46243730Srwatson#endif
47243730Srwatson
48243730Srwatsonstatic __inline void
49243730Srwatsonmtx_init(pthread_mutex_t *lock)
50243730Srwatson{
51243730Srwatson	int error;
52243730Srwatson
53243730Srwatson	error = pthread_mutex_init(lock, NULL);
54243730Srwatson	PJDLOG_ASSERT(error == 0);
55243730Srwatson}
56243730Srwatsonstatic __inline void
57243730Srwatsonmtx_destroy(pthread_mutex_t *lock)
58243730Srwatson{
59243730Srwatson	int error;
60243730Srwatson
61243730Srwatson	error = pthread_mutex_destroy(lock);
62243730Srwatson	PJDLOG_ASSERT(error == 0);
63243730Srwatson}
64243730Srwatsonstatic __inline void
65243730Srwatsonmtx_lock(pthread_mutex_t *lock)
66243730Srwatson{
67243730Srwatson	int error;
68243730Srwatson
69243730Srwatson	error = pthread_mutex_lock(lock);
70243730Srwatson	PJDLOG_ASSERT(error == 0);
71243730Srwatson}
72243730Srwatsonstatic __inline bool
73243730Srwatsonmtx_trylock(pthread_mutex_t *lock)
74243730Srwatson{
75243730Srwatson	int error;
76243730Srwatson
77243730Srwatson	error = pthread_mutex_trylock(lock);
78243730Srwatson	PJDLOG_ASSERT(error == 0 || error == EBUSY);
79243730Srwatson	return (error == 0);
80243730Srwatson}
81243730Srwatsonstatic __inline void
82243730Srwatsonmtx_unlock(pthread_mutex_t *lock)
83243730Srwatson{
84243730Srwatson	int error;
85243730Srwatson
86243730Srwatson	error = pthread_mutex_unlock(lock);
87243730Srwatson	PJDLOG_ASSERT(error == 0);
88243730Srwatson}
89243730Srwatsonstatic __inline bool
90243730Srwatsonmtx_owned(pthread_mutex_t *lock)
91243730Srwatson{
92243730Srwatson
93243730Srwatson	return (pthread_mutex_isowned_np(lock) != 0);
94243730Srwatson}
95243730Srwatson
96243730Srwatsonstatic __inline void
97243730Srwatsonrw_init(pthread_rwlock_t *lock)
98243730Srwatson{
99243730Srwatson	int error;
100243730Srwatson
101243730Srwatson	error = pthread_rwlock_init(lock, NULL);
102243730Srwatson	PJDLOG_ASSERT(error == 0);
103243730Srwatson}
104243730Srwatsonstatic __inline void
105243730Srwatsonrw_destroy(pthread_rwlock_t *lock)
106243730Srwatson{
107243730Srwatson	int error;
108243730Srwatson
109243730Srwatson	error = pthread_rwlock_destroy(lock);
110243730Srwatson	PJDLOG_ASSERT(error == 0);
111243730Srwatson}
112243730Srwatsonstatic __inline void
113243730Srwatsonrw_rlock(pthread_rwlock_t *lock)
114243730Srwatson{
115243730Srwatson	int error;
116243730Srwatson
117243730Srwatson	error = pthread_rwlock_rdlock(lock);
118243730Srwatson	PJDLOG_ASSERT(error == 0);
119243730Srwatson}
120243730Srwatsonstatic __inline void
121243730Srwatsonrw_wlock(pthread_rwlock_t *lock)
122243730Srwatson{
123243730Srwatson	int error;
124243730Srwatson
125243730Srwatson	error = pthread_rwlock_wrlock(lock);
126243730Srwatson	PJDLOG_ASSERT(error == 0);
127243730Srwatson}
128243730Srwatsonstatic __inline void
129243730Srwatsonrw_unlock(pthread_rwlock_t *lock)
130243730Srwatson{
131243730Srwatson	int error;
132243730Srwatson
133243730Srwatson	error = pthread_rwlock_unlock(lock);
134243730Srwatson	PJDLOG_ASSERT(error == 0);
135243730Srwatson}
136243730Srwatson
137243730Srwatsonstatic __inline void
138243730Srwatsoncv_init(pthread_cond_t *cv)
139243730Srwatson{
140243730Srwatson	pthread_condattr_t attr;
141243730Srwatson	int error;
142243730Srwatson
143243730Srwatson	error = pthread_condattr_init(&attr);
144243730Srwatson	PJDLOG_ASSERT(error == 0);
145243730Srwatson#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
146243730Srwatson	error = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
147243730Srwatson	PJDLOG_ASSERT(error == 0);
148243730Srwatson#endif
149243730Srwatson	error = pthread_cond_init(cv, &attr);
150243730Srwatson	PJDLOG_ASSERT(error == 0);
151243730Srwatson	error = pthread_condattr_destroy(&attr);
152243730Srwatson	PJDLOG_ASSERT(error == 0);
153243730Srwatson}
154243730Srwatsonstatic __inline void
155243730Srwatsoncv_wait(pthread_cond_t *cv, pthread_mutex_t *lock)
156243730Srwatson{
157243730Srwatson	int error;
158243730Srwatson
159243730Srwatson	error = pthread_cond_wait(cv, lock);
160243730Srwatson	PJDLOG_ASSERT(error == 0);
161243730Srwatson}
162243730Srwatsonstatic __inline bool
163243730Srwatsoncv_timedwait(pthread_cond_t *cv, pthread_mutex_t *lock, int timeout)
164243730Srwatson{
165243730Srwatson	struct timespec ts;
166243730Srwatson	int error;
167243730Srwatson
168243730Srwatson	if (timeout == 0) {
169243730Srwatson		cv_wait(cv, lock);
170243730Srwatson		return (false);
171243730Srwatson	}
172243730Srwatson
173243730Srwatson#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
174243730Srwatson	error = clock_gettime(CLOCK_MONOTONIC, &ts);
175243730Srwatson	PJDLOG_ASSERT(error == 0);
176243730Srwatson	ts.tv_sec += timeout;
177243730Srwatson	error = pthread_cond_timedwait(cv, lock, &ts);
178243730Srwatson#elif HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
179243730Srwatson	ts.tv_sec = timeout;
180243730Srwatson	ts.tv_nsec = 0;
181243730Srwatson	error = pthread_cond_timedwait_relative_np(cv, lock, &ts);
182243730Srwatson#else
183243730Srwatson#error Neither pthread_condattr_setclock nor pthread_cond_timedwait_relative_np is available.
184243730Srwatson#endif
185243730Srwatson	PJDLOG_ASSERT(error == 0 || error == ETIMEDOUT);
186243730Srwatson	return (error == ETIMEDOUT);
187243730Srwatson}
188243730Srwatsonstatic __inline void
189243730Srwatsoncv_signal(pthread_cond_t *cv)
190243730Srwatson{
191243730Srwatson	int error;
192243730Srwatson
193243730Srwatson	error = pthread_cond_signal(cv);
194243730Srwatson	PJDLOG_ASSERT(error == 0);
195243730Srwatson}
196243730Srwatsonstatic __inline void
197243730Srwatsoncv_broadcast(pthread_cond_t *cv)
198243730Srwatson{
199243730Srwatson	int error;
200243730Srwatson
201243730Srwatson	error = pthread_cond_broadcast(cv);
202243730Srwatson	PJDLOG_ASSERT(error == 0);
203243730Srwatson}
204243730Srwatson#endif	/* !_SYNCH_H_ */
205