source: rtems-libbsd/rtemsbsd/rtems/rtems-kernel-rwlock.c @ 3c967ca

55-freebsd-126-freebsd-12
Last change on this file since 3c967ca was 3c967ca, checked in by Sebastian Huber <sebastian.huber@…>, on 06/08/17 at 11:15:12

Use <sys/lock.h> provided by Newlib

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_rtems
5 *
6 * @brief TODO.
7 */
8
9/*
10 * Copyright (c) 2011 OPTI Medical.  All rights reserved.
11 *
12 *  OPTI Medical
13 *  235 Hembree Park Drive
14 *  Roswell, GA 30076
15 *  USA
16 *  <kevin.kirspel@optimedical.com>
17 *
18 * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
19 *
20 *  embedded brains GmbH
21 *  Dornierstr. 4
22 *  82178 Puchheim
23 *  Germany
24 *  <rtems@embedded-brains.de>
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 *    notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 *    notice, this list of conditions and the following disclaimer in the
33 *    documentation and/or other materials provided with the distribution.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 */
47
48#include <machine/rtems-bsd-kernel-space.h>
49#include <machine/rtems-bsd-muteximpl.h>
50
51#include <sys/param.h>
52#include <sys/types.h>
53#include <sys/systm.h>
54#include <sys/lock.h>
55#include <sys/rwlock.h>
56
57#ifndef INVARIANTS
58#define _rw_assert(rw, what, file, line)
59#endif
60
61static void assert_rw(struct lock_object *lock, int what);
62static void lock_rw(struct lock_object *lock, int how);
63#ifdef KDTRACE_HOOKS
64static int  owner_rw(struct lock_object *lock, struct thread **owner);
65#endif
66static int  unlock_rw(struct lock_object *lock);
67
68struct lock_class lock_class_rw = {
69  .lc_name = "rw",
70  .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE | LC_UPGRADABLE,
71  .lc_assert = assert_rw,
72#ifdef DDB
73  .lc_ddb_show = db_show_rwlock,
74#endif
75  .lc_lock = lock_rw,
76  .lc_unlock = unlock_rw,
77#ifdef KDTRACE_HOOKS
78  .lc_owner = owner_rw,
79#endif
80};
81
82#define rw_wowner(rw) ((rw)->mutex.owner)
83
84#define rw_recursed(rw) ((rw)->mutex.nest_level != 0)
85
86void
87assert_rw(struct lock_object *lock, int what)
88{
89  rw_assert((struct rwlock *)lock, what);
90}
91
92void
93lock_rw(struct lock_object *lock, int how)
94{
95  rw_wlock((struct rwlock *)lock);
96}
97
98int
99unlock_rw(struct lock_object *lock)
100{
101  rw_unlock((struct rwlock *)lock);
102
103  return (0);
104}
105
106#ifdef KDTRACE_HOOKS
107int
108owner_rw(struct lock_object *lock, struct thread **owner)
109{
110  struct rwlock *rw = (struct rwlock *)lock;
111  uintptr_t x = rw->rw_lock;
112
113  *owner = rw_wowner(rw);
114  return ((x & RW_LOCK_READ) != 0 ?  (RW_READERS(x) != 0) :
115      (*owner != NULL));
116}
117#endif
118
119void
120rw_init_flags(struct rwlock *rw, const char *name, int opts)
121{
122        int flags;
123
124        flags = LO_UPGRADABLE;
125        if (opts & RW_RECURSE)
126                flags |= LO_RECURSABLE;
127
128        rtems_bsd_mutex_init(&rw->lock_object, &rw->mutex, &lock_class_rw,
129            name, NULL, flags);
130}
131
132void
133rw_destroy(struct rwlock *rw)
134{
135
136        rtems_bsd_mutex_destroy(&rw->lock_object, &rw->mutex);
137}
138
139void
140rw_sysinit(void *arg)
141{
142  struct rw_args *args = arg;
143
144  rw_init(args->ra_rw, args->ra_desc);
145}
146
147void
148rw_sysinit_flags(void *arg)
149{
150  struct rw_args_flags *args = arg;
151
152  rw_init_flags(args->ra_rw, args->ra_desc, args->ra_flags);
153}
154
155int
156rw_wowned(struct rwlock *rw)
157{
158        return (rtems_bsd_mutex_owned(&rw->mutex));
159}
160
161void
162_rw_wlock(struct rwlock *rw, const char *file, int line)
163{
164        rtems_bsd_mutex_lock(&rw->lock_object, &rw->mutex);
165}
166
167int
168_rw_try_wlock(struct rwlock *rw, const char *file, int line)
169{
170        return (rtems_bsd_mutex_trylock(&rw->lock_object, &rw->mutex));
171}
172
173void
174_rw_wunlock(struct rwlock *rw, const char *file, int line)
175{
176        rtems_bsd_mutex_unlock(&rw->mutex);
177}
178
179void
180_rw_rlock(struct rwlock *rw, const char *file, int line)
181{
182        rtems_bsd_mutex_lock(&rw->lock_object, &rw->mutex);
183}
184
185int
186_rw_try_rlock(struct rwlock *rw, const char *file, int line)
187{
188        return (rtems_bsd_mutex_trylock(&rw->lock_object, &rw->mutex));
189}
190
191void
192_rw_runlock(struct rwlock *rw, const char *file, int line)
193{
194        rtems_bsd_mutex_unlock(&rw->mutex);
195}
196
197int
198_rw_try_upgrade(struct rwlock *rw, const char *file, int line)
199{
200        return (1);
201}
202
203void
204_rw_downgrade(struct rwlock *rw, const char *file, int line)
205{
206        /* Nothing to do */
207}
208
209#ifdef INVARIANT_SUPPORT
210#ifndef INVARIANTS
211#undef _rw_assert
212#endif
213
214/*
215 * In the non-WITNESS case, rw_assert() can only detect that at least
216 * *some* thread owns an rlock, but it cannot guarantee that *this*
217 * thread owns an rlock.
218 */
219void
220_rw_assert(struct rwlock *rw, int what, const char *file, int line)
221{
222
223  if (panicstr != NULL)
224    return;
225  switch (what) {
226  case RA_LOCKED:
227  case RA_LOCKED | RA_RECURSED:
228  case RA_LOCKED | RA_NOTRECURSED:
229  case RA_RLOCKED:
230#ifndef __rtems__
231#ifdef WITNESS
232    witness_assert(&rw->lock_object, what, file, line);
233#else
234    /*
235     * If some other thread has a write lock or we have one
236     * and are asserting a read lock, fail.  Also, if no one
237     * has a lock at all, fail.
238     */
239    if (rw->rw_lock == RW_UNLOCKED ||
240        (!(rw->rw_lock & RW_LOCK_READ) && (what == RA_RLOCKED ||
241        rw_wowner(rw) != curthread)))
242      panic("Lock %s not %slocked @ %s:%d\n",
243          rw->lock_object.lo_name, (what == RA_RLOCKED) ?
244          "read " : "", file, line);
245
246    if (!(rw->rw_lock & RW_LOCK_READ)) {
247      if (rw_recursed(rw)) {
248        if (what & RA_NOTRECURSED)
249          panic("Lock %s recursed @ %s:%d\n",
250              rw->lock_object.lo_name, file,
251              line);
252      } else if (what & RA_RECURSED)
253        panic("Lock %s not recursed @ %s:%d\n",
254            rw->lock_object.lo_name, file, line);
255    }
256#endif
257    break;
258#else /* __rtems__ */
259    /* FALLTHROUGH */
260#endif /* __rtems__ */
261  case RA_WLOCKED:
262  case RA_WLOCKED | RA_RECURSED:
263  case RA_WLOCKED | RA_NOTRECURSED:
264    if (rw_wowner(rw) != _Thread_Get_executing())
265      panic("Lock %s not exclusively locked @ %s:%d\n",
266          rw->lock_object.lo_name, file, line);
267    if (rw_recursed(rw)) {
268      if (what & RA_NOTRECURSED)
269        panic("Lock %s recursed @ %s:%d\n",
270            rw->lock_object.lo_name, file, line);
271    } else if (what & RA_RECURSED)
272      panic("Lock %s not recursed @ %s:%d\n",
273          rw->lock_object.lo_name, file, line);
274    break;
275  case RA_UNLOCKED:
276#ifdef WITNESS
277    witness_assert(&rw->lock_object, what, file, line);
278#else
279    /*
280     * If we hold a write lock fail.  We can't reliably check
281     * to see if we hold a read lock or not.
282     */
283    if (rw_wowner(rw) == _Thread_Get_executing())
284      panic("Lock %s exclusively locked @ %s:%d\n",
285          rw->lock_object.lo_name, file, line);
286#endif
287    break;
288  default:
289    panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
290        line);
291  }
292}
293#endif /* INVARIANT_SUPPORT */
Note: See TracBrowser for help on using the repository browser.