1204076Spjd/*-
2204076Spjd * Copyright (c) 2009-2010 The FreeBSD Foundation
3204076Spjd * All rights reserved.
4204076Spjd *
5204076Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from
6204076Spjd * the FreeBSD Foundation.
7204076Spjd *
8204076Spjd * Redistribution and use in source and binary forms, with or without
9204076Spjd * modification, are permitted provided that the following conditions
10204076Spjd * are met:
11204076Spjd * 1. Redistributions of source code must retain the above copyright
12204076Spjd *    notice, this list of conditions and the following disclaimer.
13204076Spjd * 2. Redistributions in binary form must reproduce the above copyright
14204076Spjd *    notice, this list of conditions and the following disclaimer in the
15204076Spjd *    documentation and/or other materials provided with the distribution.
16204076Spjd *
17204076Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20204076Spjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27204076Spjd * SUCH DAMAGE.
28204076Spjd *
29204076Spjd * $FreeBSD$
30204076Spjd */
31204076Spjd
32204076Spjd#ifndef	_SYNCH_H_
33204076Spjd#define	_SYNCH_H_
34204076Spjd
35211876Spjd#include <errno.h>
36204076Spjd#include <pthread.h>
37211876Spjd#include <pthread_np.h>
38204076Spjd#include <stdbool.h>
39204076Spjd#include <time.h>
40204076Spjd
41229509Strociny#include <pjdlog.h>
42229509Strociny
43229509Strociny#ifndef	PJDLOG_ASSERT
44229509Strociny#include <assert.h>
45229509Strociny#define	PJDLOG_ASSERT(...)	assert(__VA_ARGS__)
46229509Strociny#endif
47229509Strociny
48204076Spjdstatic __inline void
49204076Spjdmtx_init(pthread_mutex_t *lock)
50204076Spjd{
51204076Spjd	int error;
52204076Spjd
53204076Spjd	error = pthread_mutex_init(lock, NULL);
54229509Strociny	PJDLOG_ASSERT(error == 0);
55204076Spjd}
56204076Spjdstatic __inline void
57211975Spjdmtx_destroy(pthread_mutex_t *lock)
58211975Spjd{
59211975Spjd	int error;
60211975Spjd
61211975Spjd	error = pthread_mutex_destroy(lock);
62229509Strociny	PJDLOG_ASSERT(error == 0);
63211975Spjd}
64211975Spjdstatic __inline void
65204076Spjdmtx_lock(pthread_mutex_t *lock)
66204076Spjd{
67204076Spjd	int error;
68204076Spjd
69204076Spjd	error = pthread_mutex_lock(lock);
70229509Strociny	PJDLOG_ASSERT(error == 0);
71204076Spjd}
72204076Spjdstatic __inline bool
73204076Spjdmtx_trylock(pthread_mutex_t *lock)
74204076Spjd{
75204076Spjd	int error;
76204076Spjd
77204076Spjd	error = pthread_mutex_trylock(lock);
78229509Strociny	PJDLOG_ASSERT(error == 0 || error == EBUSY);
79204076Spjd	return (error == 0);
80204076Spjd}
81204076Spjdstatic __inline void
82204076Spjdmtx_unlock(pthread_mutex_t *lock)
83204076Spjd{
84204076Spjd	int error;
85204076Spjd
86204076Spjd	error = pthread_mutex_unlock(lock);
87229509Strociny	PJDLOG_ASSERT(error == 0);
88204076Spjd}
89211876Spjdstatic __inline bool
90211876Spjdmtx_owned(pthread_mutex_t *lock)
91211876Spjd{
92204076Spjd
93211876Spjd	return (pthread_mutex_isowned_np(lock) != 0);
94211876Spjd}
95211876Spjd
96204076Spjdstatic __inline void
97204076Spjdrw_init(pthread_rwlock_t *lock)
98204076Spjd{
99204076Spjd	int error;
100204076Spjd
101204076Spjd	error = pthread_rwlock_init(lock, NULL);
102229509Strociny	PJDLOG_ASSERT(error == 0);
103204076Spjd}
104204076Spjdstatic __inline void
105211975Spjdrw_destroy(pthread_rwlock_t *lock)
106211975Spjd{
107211975Spjd	int error;
108211975Spjd
109211975Spjd	error = pthread_rwlock_destroy(lock);
110229509Strociny	PJDLOG_ASSERT(error == 0);
111211975Spjd}
112211975Spjdstatic __inline void
113204076Spjdrw_rlock(pthread_rwlock_t *lock)
114204076Spjd{
115204076Spjd	int error;
116204076Spjd
117204076Spjd	error = pthread_rwlock_rdlock(lock);
118229509Strociny	PJDLOG_ASSERT(error == 0);
119204076Spjd}
120204076Spjdstatic __inline void
121204076Spjdrw_wlock(pthread_rwlock_t *lock)
122204076Spjd{
123204076Spjd	int error;
124204076Spjd
125204076Spjd	error = pthread_rwlock_wrlock(lock);
126229509Strociny	PJDLOG_ASSERT(error == 0);
127204076Spjd}
128204076Spjdstatic __inline void
129204076Spjdrw_unlock(pthread_rwlock_t *lock)
130204076Spjd{
131204076Spjd	int error;
132204076Spjd
133204076Spjd	error = pthread_rwlock_unlock(lock);
134229509Strociny	PJDLOG_ASSERT(error == 0);
135204076Spjd}
136204076Spjd
137204076Spjdstatic __inline void
138204076Spjdcv_init(pthread_cond_t *cv)
139204076Spjd{
140204076Spjd	pthread_condattr_t attr;
141204076Spjd	int error;
142204076Spjd
143204076Spjd	error = pthread_condattr_init(&attr);
144229509Strociny	PJDLOG_ASSERT(error == 0);
145204076Spjd	error = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
146229509Strociny	PJDLOG_ASSERT(error == 0);
147204076Spjd	error = pthread_cond_init(cv, &attr);
148229509Strociny	PJDLOG_ASSERT(error == 0);
149214274Spjd	error = pthread_condattr_destroy(&attr);
150229509Strociny	PJDLOG_ASSERT(error == 0);
151204076Spjd}
152204076Spjdstatic __inline void
153204076Spjdcv_wait(pthread_cond_t *cv, pthread_mutex_t *lock)
154204076Spjd{
155204076Spjd	int error;
156204076Spjd
157204076Spjd	error = pthread_cond_wait(cv, lock);
158229509Strociny	PJDLOG_ASSERT(error == 0);
159204076Spjd}
160204076Spjdstatic __inline bool
161204076Spjdcv_timedwait(pthread_cond_t *cv, pthread_mutex_t *lock, int timeout)
162204076Spjd{
163204076Spjd	struct timespec ts;
164204076Spjd	int error;
165204076Spjd
166204076Spjd	if (timeout == 0) {
167204076Spjd		cv_wait(cv, lock);
168204076Spjd		return (false);
169204076Spjd	}
170204076Spjd
171204076Spjd        error = clock_gettime(CLOCK_MONOTONIC, &ts);
172229509Strociny	PJDLOG_ASSERT(error == 0);
173204076Spjd	ts.tv_sec += timeout;
174204076Spjd	error = pthread_cond_timedwait(cv, lock, &ts);
175229509Strociny	PJDLOG_ASSERT(error == 0 || error == ETIMEDOUT);
176204076Spjd	return (error == ETIMEDOUT);
177204076Spjd}
178204076Spjdstatic __inline void
179204076Spjdcv_signal(pthread_cond_t *cv)
180204076Spjd{
181204076Spjd	int error;
182204076Spjd
183204076Spjd	error = pthread_cond_signal(cv);
184229509Strociny	PJDLOG_ASSERT(error == 0);
185204076Spjd}
186204076Spjdstatic __inline void
187204076Spjdcv_broadcast(pthread_cond_t *cv)
188204076Spjd{
189204076Spjd	int error;
190204076Spjd
191204076Spjd	error = pthread_cond_broadcast(cv);
192229509Strociny	PJDLOG_ASSERT(error == 0);
193204076Spjd}
194204076Spjd#endif	/* !_SYNCH_H_ */
195