]> git.saurik.com Git - apple/libpthread.git/blame - kern/synch_internal.h
libpthread-416.11.1.tar.gz
[apple/libpthread.git] / kern / synch_internal.h
CommitLineData
f1a1da6c
A
1/*
2 * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef __SYNCH_INTERNAL_H__
25#define __SYNCH_INTERNAL_H__
26
214d78a2
A
27// kwe_state
28enum {
29 KWE_THREAD_INWAIT = 1,
30 KWE_THREAD_PREPOST,
31 KWE_THREAD_BROADCAST,
32};
f1a1da6c
A
33
34#define _PTHREAD_MTX_OPT_PSHARED 0x010
35#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */
36#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */
37
38
39#define PTHRW_COUNT_SHIFT 8
40#define PTHRW_INC (1 << PTHRW_COUNT_SHIFT)
41#define PTHRW_BIT_MASK ((1 << PTHRW_COUNT_SHIFT) - 1)
42#define PTHRW_COUNT_MASK ((uint32_t)~PTHRW_BIT_MASK)
43#define PTHRW_MAX_READERS PTHRW_COUNT_MASK
44
45// L word
46#define PTH_RWL_KBIT 0x01 // cannot acquire in user mode
47#define PTH_RWL_EBIT 0x02 // exclusive lock in progress
48#define PTH_RWL_WBIT 0x04 // write waiters pending in kernel
49#define PTH_RWL_PBIT 0x04 // prepost (cv) pending in kernel
50
51#define PTH_RWL_MTX_WAIT 0x20 // in cvar in mutex wait
a0619f9c
A
52#define PTH_RWL_UBIT 0x40 // lock is unlocked (no readers or writers)
53#define PTH_RWL_MBIT 0x40 // overlapping grants from kernel (only in updateval)
f1a1da6c
A
54#define PTH_RWL_IBIT 0x80 // lock reset, held until first successful unlock
55
56#define PTHRW_RWL_INIT PTH_RWL_IBIT // reset on the lock bits (U)
a0619f9c 57#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_UBIT) // reset on the lock bits (U)
f1a1da6c
A
58
59// S word
60#define PTH_RWS_SBIT 0x01 // kernel transition seq not set yet
61#define PTH_RWS_IBIT 0x02 // Sequence is not set on return from kernel
62
63#define PTH_RWS_CV_CBIT PTH_RWS_SBIT // kernel has cleared all info w.r.s.t CV
64#define PTH_RWS_CV_PBIT PTH_RWS_IBIT // kernel has prepost/fake structs only,no waiters
65#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT)
66#define PTH_RWS_CV_MBIT PTH_RWL_MBIT // to indicate prepost return from kernel
67#define PTH_RWS_CV_RESET_PBIT ((uint32_t)~PTH_RWS_CV_PBIT)
68
69#define PTH_RWS_WSVBIT 0x04 // save W bit
70
71#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT) // save bits mask
72
73#define PTHRW_RWS_INIT PTH_RWS_SBIT // reset on the lock bits (U)
f1a1da6c
A
74
75// rw_flags
76#define PTHRW_KERN_PROCESS_SHARED 0x10
77#define PTHRW_KERN_PROCESS_PRIVATE 0x20
78
79#define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1
80
81// L word tests
f1a1da6c
A
82#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0)
83#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0)
84#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0)
85#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0)
86
87// S word tests
214d78a2
A
88#define is_rws_sbit_set(x) (((x) & PTH_RWS_SBIT) != 0)
89#define is_rws_unlockinit_set(x) (((x) & PTH_RWS_IBIT) != 0)
90#define is_rws_savemask_set(x) (((x) & PTHRW_RWS_SAVEMASK) != 0)
91#define is_rws_pbit_set(x) (((x) & PTH_RWS_CV_PBIT) != 0)
92
93// kwe_flags
94#define KWE_FLAG_LOCKPREPOST 0x1 // cvwait caused a lock prepost
f1a1da6c
A
95
96static inline int
97is_seqlower(uint32_t x, uint32_t y)
98{
99 x &= PTHRW_COUNT_MASK;
100 y &= PTHRW_COUNT_MASK;
101 if (x < y) {
102 return ((y - x) < (PTHRW_MAX_READERS / 2));
103 } else {
104 return ((x - y) > (PTHRW_MAX_READERS / 2));
105 }
106}
107
108static inline int
109is_seqlower_eq(uint32_t x, uint32_t y)
110{
111 if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
112 return 1;
113 } else {
114 return is_seqlower(x, y);
115 }
116}
117
118static inline int
119is_seqhigher(uint32_t x, uint32_t y)
120{
121 x &= PTHRW_COUNT_MASK;
122 y &= PTHRW_COUNT_MASK;
123 if (x > y) {
124 return ((x - y) < (PTHRW_MAX_READERS / 2));
125 } else {
126 return ((y - x) > (PTHRW_MAX_READERS / 2));
127 }
128}
129
130static inline int
131is_seqhigher_eq(uint32_t x, uint32_t y)
132{
133 if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
134 return 1;
135 } else {
136 return is_seqhigher(x,y);
137 }
138}
139
140static inline int
141diff_genseq(uint32_t x, uint32_t y)
142{
143 x &= PTHRW_COUNT_MASK;
144 y &= PTHRW_COUNT_MASK;
145 if (x == y) {
146 return 0;
147 } else if (x > y) {
148 return x - y;
149 } else {
150 return ((PTHRW_MAX_READERS - y) + x + PTHRW_INC);
151 }
152}
153
154static inline int
155find_diff(uint32_t upto, uint32_t lowest)
156{
157 uint32_t diff;
158
159 if (upto == lowest)
160 return(0);
161#if 0
162 diff = diff_genseq(upto, lowest);
163#else
164 if (is_seqlower(upto, lowest) != 0)
165 diff = diff_genseq(lowest, upto);
166 else
167 diff = diff_genseq(upto, lowest);
168#endif
169 diff = (diff >> PTHRW_COUNT_SHIFT);
170 return(diff);
171}
172
173#endif /* __SYNCH_INTERNAL_H__ */