1228904Sed/*-
2228904Sed * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
3228904Sed * All rights reserved.
4228904Sed *
5228904Sed * Redistribution and use in source and binary forms, with or without
6228904Sed * modification, are permitted provided that the following conditions
7228904Sed * are met:
8228904Sed * 1. Redistributions of source code must retain the above copyright
9228904Sed *    notice, this list of conditions and the following disclaimer.
10228904Sed * 2. Redistributions in binary form must reproduce the above copyright
11228904Sed *    notice, this list of conditions and the following disclaimer in the
12228904Sed *    documentation and/or other materials provided with the distribution.
13228904Sed *
14228904Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15228904Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16228904Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17228904Sed * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18228904Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19228904Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20228904Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21228904Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22228904Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23228904Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24228904Sed * SUCH DAMAGE.
25228904Sed *
26228904Sed * $FreeBSD$
27228904Sed */
28228904Sed
29228904Sed#ifndef _THREADS_H_
30228904Sed#define	_THREADS_H_
31228904Sed
32228904Sed#include <time.h>
33228904Sed
34228904Sed/*
35228904Sed * The C11 threads interface.
36228904Sed *
37228904Sed * This interface is implemented as a light-weight wrapper around
38228904Sed * <pthread.h>.  To prevent namespace pollution, the once_flag object,
39228904Sed * its corresponding ONCE_FLAG_INIT and TSS_DTOR_ITERATIONS have been
40228904Sed * copied from this header file.  They must be kept in sync.
41228904Sed */
42228904Sed
43228904Sedtypedef struct pthread_cond	*cnd_t;
44228904Sedtypedef struct pthread_mutex	*mtx_t;
45228904Sedtypedef struct pthread		*thrd_t;
46228904Sedtypedef int			 tss_t;
47228904Sed
48228904Sedtypedef struct {
49228904Sed	int	__state;
50228904Sed	mtx_t	__mutex;
51228904Sed} once_flag;
52228904Sed
53228904Sedtypedef void (*tss_dtor_t)(void *);
54228904Sedtypedef int (*thrd_start_t)(void *);
55228904Sed
56228904Sedenum {
57228904Sed	mtx_plain = 0x1,
58228904Sed	mtx_recursive = 0x2,
59228904Sed	mtx_timed = 0x4
60228904Sed};
61228904Sed
62228904Sedenum {
63228904Sed	thrd_busy = 1,
64228904Sed	thrd_error = 2,
65228904Sed	thrd_nomem = 3,
66228904Sed	thrd_success = 4,
67228904Sed	thrd_timedout = 5
68228904Sed};
69228904Sed
70228904Sed#if !defined(__cplusplus) || __cplusplus < 201103L
71228904Sed#define	thread_local		_Thread_local
72228904Sed#endif
73228904Sed#define	ONCE_FLAG_INIT		{ 0, NULL }
74228904Sed#define	TSS_DTOR_ITERATIONS	4
75228904Sed
76228904Sed__BEGIN_DECLS
77228904Sedvoid	call_once(once_flag *, void (*)(void));
78228904Sedint	cnd_broadcast(cnd_t *);
79228904Sedvoid	cnd_destroy(cnd_t *);
80228904Sedint	cnd_init(cnd_t *);
81228904Sedint	cnd_signal(cnd_t *);
82228904Sedint	cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict,
83228904Sed    const struct timespec *__restrict);
84228904Sedint	cnd_wait(cnd_t *, mtx_t *);
85228904Sedvoid	mtx_destroy(mtx_t *);
86228904Sedint	mtx_init(mtx_t *, int);
87228904Sedint	mtx_lock(mtx_t *);
88228904Sedint	mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict);
89228904Sedint	mtx_trylock(mtx_t *);
90228904Sedint	mtx_unlock(mtx_t *);
91228904Sedint	thrd_create(thrd_t *, thrd_start_t, void *);
92228904Sedthrd_t	thrd_current(void);
93228904Sedint	thrd_detach(thrd_t);
94228904Sedint	thrd_equal(thrd_t, thrd_t);
95228904Sed_Noreturn void
96228904Sed	thrd_exit(int);
97228904Sedint	thrd_join(thrd_t, int *);
98228904Sedint	thrd_sleep(const struct timespec *, struct timespec *);
99228904Sedvoid	thrd_yield(void);
100228904Sedint	tss_create(tss_t *, tss_dtor_t);
101228904Sedvoid	tss_delete(tss_t);
102228904Sedvoid *	tss_get(tss_t);
103228904Sedint	tss_set(tss_t, void *);
104228904Sed__END_DECLS
105228904Sed
106228904Sed#endif /* !_THREADS_H_ */
107