synch.h revision 236909
1139749Simp/*-
253790Sobrien * Copyright (c) 2009-2010 The FreeBSD Foundation
353790Sobrien * All rights reserved.
453790Sobrien *
586266Sgroudier * This software was developed by Pawel Jakub Dawidek under sponsorship from
653790Sobrien * the FreeBSD Foundation.
753790Sobrien *
859743Sgroudier * Redistribution and use in source and binary forms, with or without
959743Sgroudier * modification, are permitted provided that the following conditions
1053790Sobrien * are met:
1153790Sobrien * 1. Redistributions of source code must retain the above copyright
1253790Sobrien *    notice, this list of conditions and the following disclaimer.
1353790Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1453790Sobrien *    notice, this list of conditions and the following disclaimer in the
1553790Sobrien *    documentation and/or other materials provided with the distribution.
1653790Sobrien *
1753790Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1853790Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1953790Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2053790Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
2153790Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2253790Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2353790Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2453790Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2553790Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2653790Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2753790Sobrien * SUCH DAMAGE.
2853790Sobrien *
2953790Sobrien * $FreeBSD: head/sbin/hastd/synch.h 236909 2012-06-11 19:20:59Z hselasky $
3053790Sobrien */
3153790Sobrien
3253790Sobrien#ifndef	_SYNCH_H_
3353790Sobrien#define	_SYNCH_H_
3453790Sobrien
3553790Sobrien#include <errno.h>
3653790Sobrien#include <pthread.h>
3753790Sobrien#include <pthread_np.h>
3853790Sobrien#include <stdbool.h>
3953790Sobrien#include <time.h>
4053790Sobrien
4153790Sobrien#include <pjdlog.h>
4253790Sobrien
4353790Sobrien#ifndef	PJDLOG_ASSERT
4453790Sobrien#include <assert.h>
4553790Sobrien#define	PJDLOG_ASSERT(...)	assert(__VA_ARGS__)
4653790Sobrien#endif
4753790Sobrien
4853790Sobrienstatic __inline void
4953790Sobrienmtx_init(pthread_mutex_t *lock)
5053790Sobrien{
5153790Sobrien	int error;
5253790Sobrien
5353790Sobrien	error = pthread_mutex_init(lock, NULL);
5453790Sobrien	PJDLOG_ASSERT(error == 0);
5553790Sobrien}
5653790Sobrienstatic __inline void
5755258Sobrienmtx_destroy(pthread_mutex_t *lock)
5855258Sobrien{
5955258Sobrien	int error;
6053790Sobrien
6153790Sobrien	error = pthread_mutex_destroy(lock);
6253790Sobrien	PJDLOG_ASSERT(error == 0);
6353790Sobrien}
6453790Sobrienstatic __inline void
6553790Sobrienmtx_lock(pthread_mutex_t *lock)
6653790Sobrien{
6753790Sobrien	int error;
6853790Sobrien
6959743Sgroudier	error = pthread_mutex_lock(lock);
7059743Sgroudier	PJDLOG_ASSERT(error == 0);
7159743Sgroudier}
7259743Sgroudierstatic __inline bool
7359743Sgroudiermtx_trylock(pthread_mutex_t *lock)
7453790Sobrien{
7553790Sobrien	int error;
7654690Sobrien
7753790Sobrien	error = pthread_mutex_trylock(lock);
7853790Sobrien	PJDLOG_ASSERT(error == 0 || error == EBUSY);
7953790Sobrien	return (error == 0);
8053790Sobrien}
8153790Sobrienstatic __inline void
8253790Sobrienmtx_unlock(pthread_mutex_t *lock)
8354690Sobrien{
8453790Sobrien	int error;
8553790Sobrien
86236468Smarius	error = pthread_mutex_unlock(lock);
87236468Smarius	PJDLOG_ASSERT(error == 0);
88236468Smarius}
89236468Smariusstatic __inline bool
90236468Smariusmtx_owned(pthread_mutex_t *lock)
91236468Smarius{
92236468Smarius
93237186Smarius	return (pthread_mutex_isowned_np(lock) != 0);
9453790Sobrien}
95237186Smarius
96237186Smariusstatic __inline void
9753790Sobrienrw_init(pthread_rwlock_t *lock)
98237186Smarius{
9953790Sobrien	int error;
10053790Sobrien
10153790Sobrien	error = pthread_rwlock_init(lock, NULL);
10253790Sobrien	PJDLOG_ASSERT(error == 0);
10353790Sobrien}
10454690Sobrienstatic __inline void
10553790Sobrienrw_destroy(pthread_rwlock_t *lock)
10653790Sobrien{
10753790Sobrien	int error;
10853790Sobrien
10953790Sobrien	error = pthread_rwlock_destroy(lock);
11053790Sobrien	PJDLOG_ASSERT(error == 0);
11153790Sobrien}
11253790Sobrienstatic __inline void
11354690Sobrienrw_rlock(pthread_rwlock_t *lock)
11453790Sobrien{
11553790Sobrien	int error;
11653790Sobrien
11753790Sobrien	error = pthread_rwlock_rdlock(lock);
11853790Sobrien	PJDLOG_ASSERT(error == 0);
11953790Sobrien}
12053790Sobrienstatic __inline void
12153790Sobrienrw_wlock(pthread_rwlock_t *lock)
12253790Sobrien{
12353790Sobrien	int error;
12454690Sobrien
12553790Sobrien	error = pthread_rwlock_wrlock(lock);
12653790Sobrien	PJDLOG_ASSERT(error == 0);
12753790Sobrien}
12853790Sobrienstatic __inline void
12954690Sobrienrw_unlock(pthread_rwlock_t *lock)
13059743Sgroudier{
13153790Sobrien	int error;
13253790Sobrien
13353790Sobrien	error = pthread_rwlock_unlock(lock);
13453790Sobrien	PJDLOG_ASSERT(error == 0);
13553790Sobrien}
13654690Sobrien
13753790Sobrienstatic __inline void
13853790Sobriencv_init(pthread_cond_t *cv)
13953790Sobrien{
14053790Sobrien	pthread_condattr_t attr;
14153790Sobrien	int error;
14253790Sobrien
14353790Sobrien	error = pthread_condattr_init(&attr);
14453790Sobrien	PJDLOG_ASSERT(error == 0);
14553790Sobrien	error = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
14653790Sobrien	PJDLOG_ASSERT(error == 0);
14754690Sobrien	error = pthread_cond_init(cv, &attr);
14853790Sobrien	PJDLOG_ASSERT(error == 0);
14953790Sobrien	error = pthread_condattr_destroy(&attr);
15053790Sobrien	PJDLOG_ASSERT(error == 0);
15153790Sobrien}
15254690Sobrienstatic __inline void
15353790Sobriencv_wait(pthread_cond_t *cv, pthread_mutex_t *lock)
15453790Sobrien{
15553790Sobrien	int error;
15653790Sobrien
15754690Sobrien	error = pthread_cond_wait(cv, lock);
15853790Sobrien	PJDLOG_ASSERT(error == 0);
15953790Sobrien}
16053790Sobrienstatic __inline bool
16153790Sobriencv_timedwait(pthread_cond_t *cv, pthread_mutex_t *lock, int timeout)
16255628Sgroudier{
16354690Sobrien	struct timespec ts;
16453790Sobrien	int error;
16553790Sobrien
16653790Sobrien	if (timeout == 0) {
16754690Sobrien		cv_wait(cv, lock);
16853790Sobrien		return (false);
16953790Sobrien	}
17053790Sobrien
17153790Sobrien	error = clock_gettime(CLOCK_REALTIME, &ts);
17254690Sobrien	PJDLOG_ASSERT(error == 0);
17353790Sobrien	ts.tv_sec += timeout;
17453790Sobrien	error = pthread_cond_timedwait(cv, lock, &ts);
17553790Sobrien	PJDLOG_ASSERT(error == 0 || error == ETIMEDOUT);
17653790Sobrien	return (error == ETIMEDOUT);
17754690Sobrien}
17853790Sobrienstatic __inline void
17953790Sobriencv_signal(pthread_cond_t *cv)
18053790Sobrien{
18154690Sobrien	int error;
18254690Sobrien
18354690Sobrien	error = pthread_cond_signal(cv);
18454690Sobrien	PJDLOG_ASSERT(error == 0);
18554690Sobrien}
18653790Sobrienstatic __inline void
18754690Sobriencv_broadcast(pthread_cond_t *cv)
18854690Sobrien{
18954690Sobrien	int error;
19053790Sobrien
19153790Sobrien	error = pthread_cond_broadcast(cv);
19253790Sobrien	PJDLOG_ASSERT(error == 0);
19353790Sobrien}
19454690Sobrien#endif	/* !_SYNCH_H_ */
19553790Sobrien