21 #ifndef P99_FUTEX_C11_H
22 #define P99_FUTEX_C11_H
47 #ifndef P99_FUTEX_INITIALIZER
48 # define P99_FUTEX_INITIALIZER(INITIAL) { .p99_cnt = (INITIAL), }
54 *p00_fut = (
p99_futex)P99_FUTEX_INITIALIZER(p00_ini);
56 cnd_init(&p00_fut->p99_cnd);
64 p00_fut->p99_cnt = UINT_MAX;
65 mtx_destroy(&p00_fut->p99_mut);
66 cnd_destroy(&p00_fut->p99_cnd);
74 p00_ret = p00_fut->p99_cnt;
83 unsigned p00_futex_wakeup(
p99_futex volatile* p00_fut,
84 unsigned p00_wmin,
unsigned p00_wmax) {
85 assert(p00_wmin <= p00_wmax);
86 if (p00_wmax && p00_fut->p99_waiting) {
87 if (p00_wmax > p00_fut->p99_waiting) p00_wmax = p00_fut->p99_waiting;
88 if (p00_wmax > 1u) cnd_broadcast((cnd_t*)&p00_fut->p99_cnd);
89 else cnd_signal((cnd_t*)&p00_fut->p99_cnd);
90 p00_fut->p99_waiting -= p00_wmax;
91 p00_fut->p99_awaking += p00_wmax;
98 #define P00_FUTEX_WAKEUP(FUT, WMIN, WMAX) \
100 unsigned p00Wok = p00_futex_wakeup((FUT), WMIN, WMAX); \
107 unsigned p00_wmin,
unsigned p00_wmax) {
108 if (p00_wmax < p00_wmin) p00_wmax = p00_wmin;
110 unsigned p00_wok = 0;
112 p00_wok = p00_futex_wakeup(p00_fut, p00_wmin, p00_wmax);
120 void p00_futex_wait(
p99_futex volatile* p00_fut) {
121 ++p00_fut->p99_waiting;
125 cnd_wait((cnd_t*)&p00_fut->p99_cnd, (mtx_t*)&p00_fut->p99_mut);
126 }
while (!p00_fut->p99_awaking);
127 --p00_fut->p99_awaking;
133 p00_futex_wait(p00_fut);
138 unsigned p00_cstart,
unsigned p00_clen,
139 unsigned p00_wmin,
unsigned p00_wmax) {
140 unsigned p00_ret = 0;
141 if (p00_wmax < p00_wmin) p00_wmax = p00_wmin;
143 p00_ret = p00_fut->p99_cnt;
144 register unsigned const p00_des = p00_ret + p00_hmuch;
145 p00_fut->p99_cnt = p00_des;
146 if (p00_clen &&
P99_IN_RANGE(p00_des, p00_cstart, p00_clen)) {
147 P00_FUTEX_WAKEUP(p00_fut, p00_wmin, p00_wmax);
160 unsigned p00_cstart,
unsigned p00_clen,
161 unsigned p00_wmin,
unsigned p00_wmax) {
162 volatile unsigned p00_act = 0;
163 if (p00_wmax < p00_wmin) p00_wmax = p00_wmin;
165 p00_act = p00_fut->p99_cnt;
166 p00_fut->p99_cnt = p00_desired;
167 if (p00_clen &&
P99_IN_RANGE(p00_desired, p00_cstart, p00_clen)) {
168 P00_FUTEX_WAKEUP(p00_fut, p00_wmin, p00_wmax);
179 #ifndef P99_FUTEX_COMPARE_EXCHANGE
181 # define P99_FUTEX_COMPARE_EXCHANGE(FUTEX, ACT, EXPECTED, DESIRED, WAKEMIN, WAKEMAX) \
183 p99_futex volatile*const p00Mfut = (FUTEX); \
184 unsigned volatile p00Mwmin = 0; \
185 unsigned volatile p00Mwmax = 0; \
186 P99_MUTUAL_EXCLUDE(*(mtx_t*)&p00Mfut->p99_mut) { \
188 register unsigned const ACT = p00Mfut->p99_cnt; \
190 if (P99_LIKELY(EXPECTED)) { \
191 p00Mfut->p99_cnt = (DESIRED); \
192 p00Mwmin = (WAKEMIN); \
193 p00Mwmax = (WAKEMAX); \
194 if (p00Mwmax < p00Mwmin) p00Mwmax = p00Mwmin; \
195 P00_FUTEX_WAKEUP(p00Mfut, p00Mwmin, p00Mwmax); \
198 p00_futex_wait(p00Mfut); \
203 if (p00Mwmin) p99_futex_wakeup(p00Mfut, p00Mwmin, p00Mwmax); \