source: rtems-libbsd/rtemsbsd/rtems/rtems-kernel-rwlock.c @ 62c8ca0

55-freebsd-126-freebsd-12
Last change on this file since 62c8ca0 was 62c8ca0, checked in by Sebastian Huber <sebastian.huber@…>, on 05/18/17 at 07:35:46

Fix INVARIANTS support

  • Property mode set to 100644
File size: 6.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) rtems_bsd_mutex_owner(&(rw)->mutex)
83
84#define rw_recursed(rw) rtems_bsd_mutex_recursed(&(rw)->mutex)
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/*
211 * In the non-WITNESS case, rw_assert() can only detect that at least
212 * *some* thread owns an rlock, but it cannot guarantee that *this*
213 * thread owns an rlock.
214 */
215void
216_rw_assert(const struct rwlock *rw, int what, const char *file, int line)
217{
218        const char *name = rtems_bsd_mutex_name(&rw->mutex);
219
220        switch (what) {
221        case RA_LOCKED:
222        case RA_LOCKED | RA_RECURSED:
223        case RA_LOCKED | RA_NOTRECURSED:
224        case RA_RLOCKED:
225        case RA_RLOCKED | RA_RECURSED:
226        case RA_RLOCKED | RA_NOTRECURSED:
227        case RA_WLOCKED:
228        case RA_WLOCKED | RA_RECURSED:
229        case RA_WLOCKED | RA_NOTRECURSED:
230                if (rw_wowner(rw) != _Thread_Get_executing())
231                        panic("Lock %s not exclusively locked @ %s:%d\n",
232                            name, file, line);
233                if (rw_recursed(rw)) {
234                        if (what & RA_NOTRECURSED)
235                                panic("Lock %s recursed @ %s:%d\n", name, file,
236                                    line);
237                } else if (what & RA_RECURSED)
238                        panic("Lock %s not recursed @ %s:%d\n", name, file,
239                            line);
240                break;
241        case RA_UNLOCKED:
242#ifdef WITNESS
243                witness_assert(&rw->lock_object, what, file, line);
244#else
245                /*
246                 * If we hold a write lock fail.  We can't reliably check
247                 * to see if we hold a read lock or not.
248                 */
249                if (rw_wowner(rw) == _Thread_Get_executing())
250                        panic("Lock %s exclusively locked @ %s:%d\n", name,
251                            file, line);
252#endif
253                break;
254        default:
255                panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
256                    line);
257        }
258}
259#endif /* INVARIANT_SUPPORT */
Note: See TracBrowser for help on using the repository browser.