summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/inc/mtlib.h
blob: 5d3fbf14513fa17d8d983c4a3f8b7031191e3f63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_MTLIB_H
#define	_MTLIB_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <thread.h>

#ifdef	__cplusplus
extern "C" {
#endif

/* these are private to the library */
extern	int	primary_link_map;
extern	int	_private_mutex_init(mutex_t *, int, void *);
extern	int	_private_mutex_destroy(mutex_t *);
extern	int	_private_mutex_lock(mutex_t *);
extern	int	_private_mutex_trylock(mutex_t *);
extern	int	_private_mutex_unlock(mutex_t *);
#define	rmutex_lock	_private_mutex_lock
#define	rmutex_trylock	_private_mutex_trylock
#define	rmutex_unlock	_private_mutex_unlock
extern	void	lmutex_lock(mutex_t *);
extern	void	lmutex_unlock(mutex_t *);
extern	int	__rwlock_init(rwlock_t *, int, void *);
extern	int	__rwlock_destroy(rwlock_t *);
extern	int	__rw_rdlock(rwlock_t *);
extern	int	__rw_wrlock(rwlock_t *);
extern	int	__rw_tryrdlock(rwlock_t *);
extern	int	__rw_trywrlock(rwlock_t *);
extern	int	__rw_unlock(rwlock_t *);
extern	void	lrw_rdlock(rwlock_t *);
extern	void	lrw_wrlock(rwlock_t *);
extern	void	lrw_unlock(rwlock_t *);
extern	void	sig_mutex_lock(mutex_t *);
extern	void	sig_mutex_unlock(mutex_t *);
extern	int	sig_mutex_trylock(mutex_t *);
extern	int	sig_cond_wait(cond_t *, mutex_t *);
extern	int	sig_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);

/* the private libc thread-safe allocator */
extern	void	*lmalloc(size_t);
extern	void	lfree(void *, size_t);

/* the rest are public functions */
extern	int	_mutex_init(mutex_t *, int, void *);
extern	int	_mutex_destroy(mutex_t *);
extern	int	_mutex_lock(mutex_t *);
extern	int	_mutex_trylock(mutex_t *);
extern	int	_mutex_unlock(mutex_t *);
extern	int	__mutex_init(mutex_t *, int, void *);
extern	int	__mutex_destroy(mutex_t *);
extern	int	__mutex_lock(mutex_t *);
extern	int	__mutex_trylock(mutex_t *);
extern	int	__mutex_unlock(mutex_t *);

extern	int	_cond_init(cond_t *, int, void *);
extern	int	_cond_destroy(cond_t *);
extern	int	_cond_wait(cond_t *, mutex_t *);
extern	int	_cond_timedwait(cond_t *, mutex_t *, const timespec_t *);
extern	int	_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
extern	int	_cond_signal(cond_t *);
extern	int	_cond_broadcast(cond_t *);

extern	int	_rwlock_init(rwlock_t *, int, void *);
extern	int	_rwlock_destroy(rwlock_t *);
extern	int	_rw_rdlock(rwlock_t *);
extern	int	_rw_wrlock(rwlock_t *);
extern	int	_rw_tryrdlock(rwlock_t *);
extern	int	_rw_trywrlock(rwlock_t *);
extern	int	_rw_unlock(rwlock_t *);

extern	int	_thr_main(void);
extern	thread_t _thr_self(void);
extern	int	_thrp_cancelled(void);
extern	void	_thr_exit(void *);
extern	size_t	_thr_min_stack(void);
extern	int	_thr_kill(thread_t, int);
extern	int	_thr_create(void *, size_t, void *(*)(void *), void *, long,
			thread_t *);
extern	int	_thr_keycreate(thread_key_t *, void (*)(void *));
extern	int	_thr_keycreate_once(thread_key_t *, void (*)(void *));
extern	int	_thr_setspecific(thread_key_t, void *);
extern	int	_thr_getspecific(thread_key_t, void **);
extern	void	*_pthread_getspecific(thread_key_t);

#if defined(THREAD_DEBUG)
extern	void	assert_no_libc_locks_held(void);
#else
#define	assert_no_libc_locks_held()
#endif

#define	_FWRITE _fwrite_unlocked
#define	FILENO(s) _fileno(s)
#define	FERROR(s) ferror(s)
#define	GETC(s) _getc_unlocked(s)
#define	UNGETC(c, s) _ungetc_unlocked(c, s)
#define	PUTC(c, s) _putc_unlocked(c, s)
#define	GETWC(s) getwc(s)
#define	PUTWC(c, s) putwc(c, s)

/*
 * Cheap check to tell if stdio needs to lock for MT progs.
 * Referenced directly in port/stdio/flush.c and FLOCKFILE and
 * FUNLOCKFILE macros.  __libc_threaded gets set to 1 when the first
 * thread (beyond the main thread) is created in _thrp_create().
 */
extern	int	__libc_threaded;

#define	FILELOCKING(iop)	(GET_IONOLOCK(iop) == 0)

#define	FLOCKFILE(lk, iop) \
	{ \
		if (__libc_threaded && FILELOCKING(iop)) \
			lk = _flockget((iop)); \
		else \
			lk = NULL; \
	}

#define	FUNLOCKFILE(lk) \
	{ \
		if (lk != NULL) \
			_flockrel(lk); \
	}

#define	FLOCKRETURN(iop, ret) \
	{	int r; \
		rmutex_t *lk; \
		FLOCKFILE(lk, iop); \
		r = (ret); \
		FUNLOCKFILE(lk); \
		return (r); \
	}

#ifdef	__cplusplus
}
#endif

#endif	/* _MTLIB_H */