ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/lib/libthr/thread/thr_umtx.c
(Generate patch)

Comparing trunk/lib/libthr/thread/thr_umtx.c (file contents):
Revision 10632 by laffer1, Sat Mar 19 00:04:17 2016 UTC vs.
Revision 10633 by laffer1, Sat Jun 9 16:42:31 2018 UTC

# Line 1 | Line 1
1 + /* $MidnightBSD$ */
2   /*
3   * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
4   * All rights reserved.
# Line 23 | Line 24
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27 < * $FreeBSD$
27 > * $FreeBSD: stable/10/lib/libthr/thread/thr_umtx.c 294639 2016-01-23 20:49:52Z vangyzen $
28   *
29   */
30  
# Line 51 | Line 52 | void
52   _thr_urwlock_init(struct urwlock *rwl)
53   {
54          static const struct urwlock default_rwl = DEFAULT_URWLOCK;
55 +
56          *rwl = default_rwl;
57   }
58  
# Line 109 | Line 111 | __thr_umutex_lock_spin(struct umutex *mtx, uint32_t id
111  
112   int
113   __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
114 <        const struct timespec *ets)
114 >        const struct timespec *abstime)
115   {
116 <        struct timespec timo, cts;
116 >        struct _umtx_time *tm_p, timeout;
117 >        size_t tm_size;
118          uint32_t owner;
119          int ret;
120  
121 <        clock_gettime(CLOCK_REALTIME, &cts);
122 <        TIMESPEC_SUB(&timo, ets, &cts);
121 >        if (abstime == NULL) {
122 >                tm_p = NULL;
123 >                tm_size = 0;
124 >        } else {
125 >                timeout._clockid = CLOCK_REALTIME;
126 >                timeout._flags = UMTX_ABSTIME;
127 >                timeout._timeout = *abstime;
128 >                tm_p = &timeout;
129 >                tm_size = sizeof(timeout);
130 >        }
131  
121        if (timo.tv_sec < 0)
122                return (ETIMEDOUT);
123
132          for (;;) {
133                  if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
134  
135                          /* wait in kernel */
136 <                        ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0, 0, &timo);
136 >                        ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0,
137 >                                 (void *)tm_size, __DECONST(void *, tm_p));
138  
139                          /* now try to lock it */
140                          owner = mtx->m_owner;
# Line 133 | Line 142 | __thr_umutex_timedlock(struct umutex *mtx, uint32_t id
142                               atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
143                                  return (0);
144                  } else {
145 <                        ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, &timo);
145 >                        ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0,
146 >                                 (void *)tm_size, __DECONST(void *, tm_p));
147                          if (ret == 0)
148                                  break;
149                  }
150                  if (ret == ETIMEDOUT)
151                          break;
142                clock_gettime(CLOCK_REALTIME, &cts);
143                TIMESPEC_SUB(&timo, ets, &cts);
144                if (timo.tv_sec < 0 || (timo.tv_sec == 0 && timo.tv_nsec == 0)) {
145                        ret = ETIMEDOUT;
146                        break;
147                }
152          }
153          return (ret);
154   }
# Line 152 | Line 156 | __thr_umutex_timedlock(struct umutex *mtx, uint32_t id
156   int
157   __thr_umutex_unlock(struct umutex *mtx, uint32_t id)
158   {
155        static int wake2_avail = 0;
156
157        if (__predict_false(wake2_avail == 0)) {
158                struct umutex test = DEFAULT_UMUTEX;
159
160                if (_umtx_op(&test, UMTX_OP_MUTEX_WAKE2, test.m_flags, 0, 0) == -1)
161                        wake2_avail = -1;
162                else
163                        wake2_avail = 1;
164        }
165
166        if (wake2_avail != 1)
167                goto unlock;
168
169        uint32_t flags = mtx->m_flags;
170
171        if ((flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
172                uint32_t owner;
173                do {
174                        owner = mtx->m_owner;
175                        if (__predict_false((owner & ~UMUTEX_CONTESTED) != id))
176                                return (EPERM);
177                } while (__predict_false(!atomic_cmpset_rel_32(&mtx->m_owner,
178                                         owner, UMUTEX_UNOWNED)));
179                if ((owner & UMUTEX_CONTESTED))
180                        (void)_umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE2, flags, 0, 0);
181                return (0);
182        }
183 unlock:
159          return _umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0);
160   }
161  
# Line 222 | Line 197 | int
197   _thr_umtx_timedwait_uint(volatile u_int *mtx, u_int id, int clockid,
198          const struct timespec *abstime, int shared)
199   {
200 <        struct timespec ts, ts2, *tsp;
200 >        struct _umtx_time *tm_p, timeout;
201 >        size_t tm_size;
202  
203 <        if (abstime != NULL) {
204 <                clock_gettime(clockid, &ts);
205 <                TIMESPEC_SUB(&ts2, abstime, &ts);
230 <                if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
231 <                        return (ETIMEDOUT);
232 <                tsp = &ts2;
203 >        if (abstime == NULL) {
204 >                tm_p = NULL;
205 >                tm_size = 0;
206          } else {
207 <                tsp = NULL;
207 >                timeout._clockid = clockid;
208 >                timeout._flags = UMTX_ABSTIME;
209 >                timeout._timeout = *abstime;
210 >                tm_p = &timeout;
211 >                tm_size = sizeof(timeout);
212          }
213 +
214          return _umtx_op_err(__DEVOLATILE(void *, mtx),
215 <                shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, NULL,
216 <                        tsp);
215 >                shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id,
216 >                (void *)tm_size, __DECONST(void *, tm_p));
217   }
218  
219   int
# Line 282 | Line 260 | _thr_ucond_broadcast(struct ucond *cv)
260   }
261  
262   int
263 < __thr_rwlock_rdlock(struct urwlock *rwlock, int flags, struct timespec *tsp)
263 > __thr_rwlock_rdlock(struct urwlock *rwlock, int flags,
264 >        const struct timespec *tsp)
265   {
266 <        return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, NULL, tsp);
266 >        struct _umtx_time timeout, *tm_p;
267 >        size_t tm_size;
268 >
269 >        if (tsp == NULL) {
270 >                tm_p = NULL;
271 >                tm_size = 0;
272 >        } else {
273 >                timeout._timeout = *tsp;
274 >                timeout._flags = UMTX_ABSTIME;
275 >                timeout._clockid = CLOCK_REALTIME;
276 >                tm_p = &timeout;
277 >                tm_size = sizeof(timeout);
278 >        }
279 >        return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, (void *)tm_size, tm_p);
280   }
281  
282   int
283 < __thr_rwlock_wrlock(struct urwlock *rwlock, struct timespec *tsp)
283 > __thr_rwlock_wrlock(struct urwlock *rwlock, const struct timespec *tsp)
284   {
285 <        return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, NULL, tsp);
285 >        struct _umtx_time timeout, *tm_p;
286 >        size_t tm_size;
287 >
288 >        if (tsp == NULL) {
289 >                tm_p = NULL;
290 >                tm_size = 0;
291 >        } else {
292 >                timeout._timeout = *tsp;
293 >                timeout._flags = UMTX_ABSTIME;
294 >                timeout._clockid = CLOCK_REALTIME;
295 >                tm_p = &timeout;
296 >                tm_size = sizeof(timeout);
297 >        }
298 >        return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, (void *)tm_size, tm_p);
299   }
300  
301   int

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines