source: rtems-libbsd/rtemsbsd/rtems/rtems-bsd-mutex.c @ 150d4d6

4.115-freebsd-12freebsd-9.3
Last change on this file since 150d4d6 was 150d4d6, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 24, 2013 at 9:11:32 AM

Move content to new <machine/rtems-bsd-support.h>

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_rtems
5 *
6 * @brief TODO.
7 */
8
9/*
10 * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40#include <machine/rtems-bsd-config.h>
41#include <machine/rtems-bsd-thread.h>
42#include <machine/rtems-bsd-support.h>
43
44#include <rtems/score/objectimpl.h>
45#include <rtems/rtems/attrimpl.h>
46#include <rtems/rtems/semimpl.h>
47
48#include <rtems/bsd/sys/param.h>
49#include <rtems/bsd/sys/types.h>
50#include <sys/systm.h>
51#include <rtems/bsd/sys/lock.h>
52#include <sys/mutex.h>
53#include <sys/proc.h>
54
55static void assert_mtx(struct lock_object *lock, int what);
56static void lock_mtx(struct lock_object *lock, int how);
57#ifdef KDTRACE_HOOKS
58static int  owner_mtx(struct lock_object *lock, struct thread **owner);
59#endif
60static int  unlock_mtx(struct lock_object *lock);
61
62RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_mtx_chain);
63
64/*
65 * Lock classes for sleep and spin mutexes.
66 */
67struct lock_class lock_class_mtx_sleep = {
68  .lc_name = "sleep mutex",
69  .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
70  .lc_assert = assert_mtx,
71#ifdef DDB
72  .lc_ddb_show = db_show_mtx,
73#endif
74  .lc_lock = lock_mtx,
75  .lc_unlock = unlock_mtx,
76#ifdef KDTRACE_HOOKS
77  .lc_owner = owner_mtx,
78#endif
79};
80
81struct lock_class lock_class_mtx_spin = {
82  .lc_name = "spin mutex",
83  .lc_flags = LC_SPINLOCK | LC_RECURSABLE,
84  .lc_assert = assert_mtx,
85#ifdef DDB
86  .lc_ddb_show = db_show_mtx,
87#endif
88  .lc_lock = lock_mtx,
89  .lc_unlock = unlock_mtx,
90#ifdef KDTRACE_HOOKS
91  .lc_owner = owner_mtx,
92#endif
93};
94
95struct mtx Giant;
96
97void
98assert_mtx(struct lock_object *lock, int what)
99{
100  mtx_assert((struct mtx *)lock, what);
101}
102
103void
104lock_mtx(struct lock_object *lock, int how)
105{
106
107  mtx_lock((struct mtx *)lock);
108}
109
110int
111unlock_mtx(struct lock_object *lock)
112{
113  struct mtx *m;
114
115  m = (struct mtx *)lock;
116  mtx_assert(m, MA_OWNED | MA_NOTRECURSED);
117  mtx_unlock(m);
118  return (0);
119}
120
121
122#ifdef KDTRACE_HOOKS
123int
124owner_mtx(struct lock_object *lock, struct thread **owner)
125{
126  struct mtx *m = (struct mtx *)lock;
127
128  *owner = mtx_owner(m);
129  return (mtx_unowned(m) == 0);
130}
131#endif
132
133void
134mtx_init(struct mtx *m, const char *name, const char *type, int opts)
135{
136  struct lock_class *class;
137  int i;
138        rtems_status_code sc = RTEMS_SUCCESSFUL;
139        rtems_id id = RTEMS_ID_NONE;
140        /* rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING; */
141  rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE;
142
143  if ((opts & MTX_RECURSE) != 0 )
144  {
145    /*FIXME*/
146  }
147
148  /* Determine lock class and lock flags. */
149  if (opts & MTX_SPIN)
150    class = &lock_class_mtx_spin;
151  else
152    class = &lock_class_mtx_sleep;
153
154  /* Check for double-init and zero object. */
155  KASSERT(!lock_initalized(&m->lock_object), ("lock \"%s\" %p already initialized", name, m->lock_object));
156
157  /* Look up lock class to find its index. */
158  for (i = 0; i < LOCK_CLASS_MAX; i++)
159  {
160    if (lock_classes[i] == class)
161    {
162      m->lock_object.lo_flags = i << LO_CLASSSHIFT;
163      break;
164    }
165  }
166  KASSERT(i < LOCK_CLASS_MAX, ("unknown lock class %p", class));
167
168        sc = rtems_semaphore_create(
169                rtems_build_name('_', 'M', 'T', 'X'),
170                1,
171                attr,
172                BSD_TASK_PRIORITY_RESOURCE_OWNER,
173                &id
174        );
175        BSD_ASSERT_SC(sc);
176
177        m->lock_object.lo_name = name;
178  m->lock_object.lo_flags |= LO_INITIALIZED;
179  m->lock_object.lo_id = id;
180
181        rtems_chain_append(&rtems_bsd_mtx_chain, &m->lock_object.lo_node);
182}
183
184void
185_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
186{
187        rtems_status_code sc = RTEMS_SUCCESSFUL;
188
189        sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
190        BSD_ASSERT_SC(sc);
191}
192
193int
194_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
195{
196        rtems_status_code sc = RTEMS_SUCCESSFUL;
197
198        sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_NO_WAIT, 0);
199        if (sc == RTEMS_SUCCESSFUL) {
200                return 1;
201        } else if (sc == RTEMS_UNSATISFIED) {
202                return 0;
203        } else {
204                BSD_ASSERT_SC(sc);
205
206                return 0;
207        }
208}
209
210void
211_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
212{
213        rtems_status_code sc = RTEMS_SUCCESSFUL;
214
215        sc = rtems_semaphore_release(m->lock_object.lo_id);
216        BSD_ASSERT_SC(sc);
217}
218
219/*
220 * The backing function for the INVARIANTS-enabled mtx_assert()
221 */
222#ifdef INVARIANT_SUPPORT
223void
224_mtx_assert(struct mtx *m, int what, const char *file, int line)
225{
226
227  if (panicstr != NULL || dumping)
228    return;
229  switch (what) {
230  case MA_OWNED:
231  case MA_OWNED | MA_RECURSED:
232  case MA_OWNED | MA_NOTRECURSED:
233    if (!mtx_owned(m))
234      panic("mutex %s not owned at %s:%d",
235          m->lock_object.lo_name, file, line);
236    if (mtx_recursed(m)) {
237      if ((what & MA_NOTRECURSED) != 0)
238        panic("mutex %s recursed at %s:%d",
239            m->lock_object.lo_name, file, line);
240    } else if ((what & MA_RECURSED) != 0) {
241      panic("mutex %s unrecursed at %s:%d",
242          m->lock_object.lo_name, file, line);
243    }
244    break;
245  case MA_NOTOWNED:
246    if (mtx_owned(m))
247      panic("mutex %s owned at %s:%d",
248          m->lock_object.lo_name, file, line);
249    break;
250  default:
251    panic("unknown mtx_assert at %s:%d", file, line);
252  }
253}
254#endif
255
256int mtx_owned(struct mtx *m)
257{
258        Objects_Locations location;
259        Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
260
261        if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
262                int owned = sema->Core_control.mutex.holder_id == rtems_task_self();
263
264                _Thread_Enable_dispatch();
265
266                return owned;
267        } else {
268                _Thread_Enable_dispatch();
269
270                BSD_PANIC("unexpected semaphore location or attributes");
271        }
272}
273
274int mtx_recursed(struct mtx *m)
275{
276        Objects_Locations location;
277        Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
278
279        if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
280                int recursed = sema->Core_control.mutex.nest_count != 0;
281
282                _Thread_Enable_dispatch();
283
284                return recursed;
285        } else {
286                _Thread_Enable_dispatch();
287
288                BSD_PANIC("unexpected semaphore location or attributes");
289        }
290}
291
292void
293mtx_sysinit(void *arg)
294{
295        struct mtx_args *margs = arg;
296
297        mtx_init(margs->ma_mtx, margs->ma_desc, NULL, margs->ma_opts);
298}
299
300void
301mtx_destroy(struct mtx *m)
302{
303        rtems_status_code sc = RTEMS_SUCCESSFUL;
304
305        sc = rtems_semaphore_delete(m->lock_object.lo_id);
306        BSD_ASSERT_SC(sc);
307
308        rtems_chain_extract(&m->lock_object.lo_node);
309
310  m->lock_object.lo_id = 0;
311  m->lock_object.lo_flags &= ~LO_INITIALIZED;
312}
313
314void
315mutex_init(void)
316{
317        mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
318}
Note: See TracBrowser for help on using the repository browser.