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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
/* Copyright (C) 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Bartley <dtbartle@csclub.uwaterloo.ca>, 2008.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _OPENSOLARIS_PTHREADP_H
#define _OPENSOLARIS_PTHREADP_H
/* rwlock macros. */
#define _RWLOCK_WR_LOCK 0x80000000
#define _RWLOCK_RD_MASK 0x7FFFFFFF
#define _RWLOCK_RD_MAX 0x7FFFFFFF
#include <nptl/pthreadP.h>
#include <sys/synch.h>
/* Flags in mutex attr. */
#undef PTHREAD_MUTEXATTR_PROTOCOL_SHIFT
#define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT 0
#undef PTHREAD_MUTEXATTR_PROTOCOL_MASK
#define PTHREAD_MUTEXATTR_PROTOCOL_MASK \
(PTHREAD_PRIO_INHERIT | PTHREAD_PRIO_PROTECT)
#undef PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT
#define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT 12
#undef PTHREAD_MUTEXATTR_PRIO_CEILING_MASK
#define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK 0x0ffff000
#undef PTHREAD_MUTEXATTR_FLAG_ROBUST
#define PTHREAD_MUTEXATTR_FLAG_ROBUST LOCK_ROBUST
#undef PTHREAD_MUTEXATTR_FLAG_PSHARED
#define PTHREAD_MUTEXATTR_FLAG_PSHARED LOCK_SHARED
#undef PTHREAD_MUTEXATTR_FLAG_BITS
#define PTHREAD_MUTEXATTR_FLAG_BITS \
(PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
| PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
#define PTHREAD_RWLOCK_TYPE_MASK 0x00000006
#define PTHREAD_RWLOCK_TYPE_SHIFT 1
#undef PTHREAD_RWLOCK_PREFER_READER_P
#define PTHREAD_RWLOCK_PREFER_READER_P(rwlock) \
(((rwlock->type >> PTHREAD_RWLOCK_TYPE_SHIFT) & \
PTHREAD_RWLOCK_TYPE_MASK) != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
#define MUTEX_IS_OWNER(mutex) \
(mutex->mutex_lockbyte == LOCKBYTE_SET && \
(((mutex)->mutex_type & LOCK_SHARED) == 0 || \
(mutex)->mutex_ownerpid == THREAD_GETMEM (THREAD_SELF, pid)) && \
((mutex)->mutex_owner == THREAD_GETMEM (THREAD_SELF, tid)))
#define MUTEX_NOT_OWNER(mutex) (! MUTEX_IS_OWNER (mutex))
#include <time.h>
#define PAST_TIMESPEC(tv) ((tv) && (tv)->tv_sec < 0)
#define INVALID_TIMESPEC(tv) ((tv) && ((tv)->tv_nsec < 0 || \
(tv)->tv_nsec >= 1000000000))
#define COPY_TIMESPEC(tv) \
struct timespec *__##tv = NULL, _##tv; \
if (tv) \
{ \
_##tv = *tv; \
__##tv = &_##tv; \
}
#include <sys/types.h>
#include <sys/syscall.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <inline-syscall.h>
#include <synchP.h>
#include <synch.h>
#include <schedP.h>
/* These are the result of the macro expansion of INTERNAL_SYSCALL. */
/* XXX: These are really gross and should die. */
static inline int __internal_kill_1 (int *errval, int sig)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_kill, sig);
return ret.sys_rval1;
}
static inline int __internal_tdetach_1 (int *errval, pthread_t tid)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_lwp_detach, tid);
return ret.sys_rval1;
}
static inline pthread_t __internal_set_tid_address_1 (int *errval, pthread_t *tid)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_lwp_self);
return *tid = ret.sys_rval1;
}
static inline int __internal_rt_sigprocmask_4 (int *errval, int how,
const sigset_t *set, sigset_t *oldset, int setsize)
{
int saved_errno = errno;
int result = sigprocmask (how, set, oldset);
if (result != 0)
*errval = errno;
__set_errno (saved_errno);
return result;
}
static inline int __internal_write_3 (int *errval, int fd, const void *buf,
size_t count)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_write, fd, buf, count);
return ret.sys_rval1;
}
static inline int __internal_tkill_2 (int *errval, pthread_t tid, int sig)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_lwp_kill, tid, sig);
return ret.sys_rval1;
}
static inline int __internal_pause_1 (int *errval, int unused)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_pause);
return ret.sys_rval1;
}
static inline int __internal_nanosleep_2 (int *errval,
const struct timespec *req, struct timespec *rem)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_nanosleep, req, rem);
return ret.sys_rval1;
}
static inline int __internal_sched_get_priority_min_1 (int *errval, int policy)
{
int saved_errno = errno;
int result = sched_get_priority_min (policy);
if (result != 0)
*errval = errno;
__set_errno (saved_errno);
return result;
}
static inline int __internal_sched_get_priority_max_1 (int *errval, int policy)
{
int saved_errno = errno;
int result = sched_get_priority_max (policy);
if (result != 0)
*errval = errno;
__set_errno (saved_errno);
return result;
}
static inline int __internal_munmap_2 (int *errval, void *start, size_t length)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_munmap, start, length);
return ret.sys_rval1;
}
static inline int __internal_close_1 (int *errval, int fd)
{
sysret_t ret;
*errval = __systemcall (&ret, SYS_close, fd);
return ret.sys_rval1;
}
/* These are used by the "real" associated functions. */
static inline int __pthread_setschedparam_internal (pthread_t threadid,
int policy, const struct sched_param *param)
{
return __sched_setscheduler_id (P_LWPID, threadid, policy,
param->__sched_priority);
}
static inline int __pthread_setschedprio_internal (pthread_t threadid,
int prio)
{
return __sched_setparam_id (P_LWPID, threadid, prio);
}
static inline int __pthread_getschedparam_internal (pthread_t threadid,
int *policy, struct sched_param *param)
{
return __sched_getscheduler_id (P_LWPID, threadid, policy,
¶m->__sched_priority);
}
static inline int __cond_has_waiters (cond_t *cond)
{
return cond->cond_waiters_kernel;
}
/* These functions are used to implement the "real" associated functions. */
extern int __cond_reltimedwait_internal (cond_t *cond, mutex_t *mutex,
struct timespec *reltime, int cancel);
extern int __mutex_reltimedlock (mutex_t *mutex,
const struct timespec *reltime);
extern int __mutex_timedlock (mutex_t *mutex, const struct timespec *abstime);
extern int __rw_timedrdlock (rwlock_t *rwlock, struct timespec *abstime);
extern int __rw_timedwrlock (rwlock_t *rwlock, struct timespec *abstime);
extern int __sema_timedwait (sema_t *sem, struct timespec *abstime);
#endif /* _OPENSOLARIS_PTHREADP_H */
|