Implement sem_open, sem_close, and sem_unlink
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / solaris2 / kopensolaris-gnu / pthreadP.h
1 /* Copyright (C) 2008 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by David Bartley <dtbartle@csclub.uwaterloo.ca>, 2008.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef _OPENSOLARIS_PTHREADP_H
21 #define _OPENSOLARIS_PTHREADP_H
22
23 /* rwlock macros.  */
24 #define _RWLOCK_WR_LOCK         0x80000000
25 #define _RWLOCK_RD_MASK         0x7FFFFFFF
26 #define _RWLOCK_RD_MAX      0x7FFFFFFF
27
28 #include <nptl/pthreadP.h>
29 #include <sys/synch.h>
30
31 /* Flags in mutex attr.  */
32 #undef PTHREAD_MUTEXATTR_PROTOCOL_SHIFT
33 #define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT        0
34 #undef PTHREAD_MUTEXATTR_PROTOCOL_MASK
35 #define PTHREAD_MUTEXATTR_PROTOCOL_MASK \
36   (PTHREAD_PRIO_INHERIT | PTHREAD_PRIO_PROTECT)
37 #undef PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT
38 #define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT    12
39 #undef PTHREAD_MUTEXATTR_PRIO_CEILING_MASK
40 #define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK     0x0ffff000
41 #undef PTHREAD_MUTEXATTR_FLAG_ROBUST
42 #define PTHREAD_MUTEXATTR_FLAG_ROBUST           LOCK_ROBUST
43 #undef PTHREAD_MUTEXATTR_FLAG_PSHARED
44 #define PTHREAD_MUTEXATTR_FLAG_PSHARED          LOCK_SHARED
45 #undef PTHREAD_MUTEXATTR_FLAG_BITS
46 #define PTHREAD_MUTEXATTR_FLAG_BITS \
47   (PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
48    | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
49
50 #define PTHREAD_RWLOCK_TYPE_MASK    0x00000006
51 #define PTHREAD_RWLOCK_TYPE_SHIFT   1
52 #undef PTHREAD_RWLOCK_PREFER_READER_P
53 #define PTHREAD_RWLOCK_PREFER_READER_P(rwlock) \
54     (((rwlock->type >> PTHREAD_RWLOCK_TYPE_SHIFT) & \
55     PTHREAD_RWLOCK_TYPE_MASK) != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
56
57 #define MUTEX_IS_OWNER(mutex) \
58        (mutex->mutex_lockbyte == LOCKBYTE_SET &&                        \
59      (((mutex)->mutex_type & LOCK_SHARED) == 0 ||                       \
60       (mutex)->mutex_ownerpid == THREAD_GETMEM (THREAD_SELF, pid)) &&   \
61      ((mutex)->mutex_owner == THREAD_GETMEM (THREAD_SELF, tid)))
62
63 #define MUTEX_NOT_OWNER(mutex)  (! MUTEX_IS_OWNER (mutex))
64
65 #include <time.h>
66
67 #define PAST_TIMESPEC(tv)       ((tv) && (tv)->tv_sec < 0)
68 #define INVALID_TIMESPEC(tv)    ((tv) && ((tv)->tv_nsec < 0 || \
69         (tv)->tv_nsec >= 1000000000))
70 #define COPY_TIMESPEC(tv)                       \
71         struct timespec *__##tv = NULL, _##tv;    \
72     if (tv)                                     \
73       {                                         \
74         _##tv = *tv;                            \
75         __##tv = &_##tv;                        \
76       }
77
78 #include <sys/types.h>
79 #include <sys/syscall.h>
80 #include <signal.h>
81 #include <unistd.h>
82 #include <errno.h>
83 #include <inline-syscall.h>
84 #include <synchP.h>
85 #include <synch.h>
86 #include <schedP.h>
87
88 /* These are the result of the macro expansion of INTERNAL_SYSCALL.  */
89
90 /* XXX: These are really gross and should die.  */
91
92 static inline int __internal_kill_1 (int *errval, int sig)
93 {
94   sysret_t ret;
95   *errval = __systemcall (&ret, SYS_kill, sig);
96   return ret.sys_rval1;
97 }
98
99 static inline pthread_t __internal_set_tid_address_1 (int *errval, pthread_t *tid)
100 {
101   sysret_t ret;
102   *errval = __systemcall (&ret, SYS_lwp_self);
103   return *tid = ret.sys_rval1;
104 }
105
106 static inline int __internal_rt_sigprocmask_4 (int *errval, int how,
107     const sigset_t *set, sigset_t *oldset, int setsize)
108 {
109   int saved_errno = errno;
110   int result = sigprocmask (how, set, oldset);
111   if (result != 0)
112     *errval = errno;
113   __set_errno (saved_errno);
114   return result;
115 }
116
117 static inline int __internal_write_3 (int *errval, int fd, const void *buf,
118     size_t count)
119 {
120   sysret_t ret;
121   *errval = __systemcall (&ret, SYS_write, fd, buf, count);
122   return ret.sys_rval1;
123 }
124
125 static inline int __internal_tkill_2 (int *errval, pthread_t tid, int sig)
126 {
127   sysret_t ret;
128   *errval = __systemcall (&ret, SYS_lwp_kill, tid, sig);
129   return ret.sys_rval1;
130 }
131
132 static inline int __internal_pause_1 (int *errval, int unused)
133 {
134   sysret_t ret;
135   *errval = __systemcall (&ret, SYS_pause);
136   return ret.sys_rval1;
137 }
138
139 static inline int __internal_nanosleep_2 (int *errval,
140     const struct timespec *req, struct timespec *rem)
141 {
142   sysret_t ret;
143   *errval = __systemcall (&ret, SYS_nanosleep, req, rem);
144   return ret.sys_rval1;
145 }
146
147 static inline int __internal_sched_get_priority_min_1 (int *errval, int policy)
148 {
149   int saved_errno = errno;
150   int result = sched_get_priority_min (policy);
151   if (result != 0)
152     *errval = errno;
153   __set_errno (saved_errno);
154   return result;
155 }
156
157 static inline int __internal_sched_get_priority_max_1 (int *errval, int policy)
158 {
159   int saved_errno = errno;
160   int result = sched_get_priority_max (policy);
161   if (result != 0)
162     *errval = errno;
163   __set_errno (saved_errno);
164   return result;
165 }
166
167 static inline int __internal_munmap_2 (int *errval, void *start, size_t length)
168 {
169   sysret_t ret;
170   *errval = __systemcall (&ret, SYS_munmap, start, length);
171   return ret.sys_rval1;
172 }
173
174 static inline int __internal_close_1 (int *errval, int fd)
175 {
176   sysret_t ret;
177   *errval = __systemcall (&ret, SYS_close, fd);
178   return ret.sys_rval1;
179 }
180
181 /* These are used by the "real" associated functions.  */
182
183 static inline int __pthread_setschedparam_internal (pthread_t threadid,
184     int policy, const struct sched_param *param)
185 {
186   return __sched_setscheduler_id (P_LWPID, threadid, policy,
187       param->__sched_priority);
188 }
189
190 static inline int __pthread_setschedprio_internal (pthread_t threadid,
191     int prio)
192 {
193   return __sched_setparam_id (P_LWPID, threadid, prio);
194 }
195
196 static inline int __pthread_getschedparam_internal (pthread_t threadid,
197     int *policy, struct sched_param *param)
198 {
199   return __sched_getscheduler_id (P_LWPID, threadid, policy,
200       &param->__sched_priority);
201 }
202
203 static inline int __cond_has_waiters (cond_t *cond)
204 {
205   return cond->cond_waiters_kernel;
206 }
207
208 /* These functions are used to implement the "real" associated functions.  */
209 extern int __cond_reltimedwait_internal (cond_t *cond, mutex_t *mutex,
210     struct timespec *reltime, int cancel);
211 extern int __mutex_reltimedlock (mutex_t *mutex,
212     const struct timespec *reltime);
213 extern int __mutex_timedlock (mutex_t *mutex, const struct timespec *abstime);
214 extern int __rw_timedrdlock (rwlock_t *rwlock, struct timespec *abstime);
215 extern int __rw_timedwrlock (rwlock_t *rwlock, struct timespec *abstime);
216 extern int __sema_timedwait (sema_t *sem, struct timespec *abstime);
217
218 #endif /* _OPENSOLARIS_PTHREADP_H */