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

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f9c2714 was f9c2714, checked in by Sebastian Huber <sebastian.huber@…>, on 10/23/13 at 07:47:09

SLEEP(8): New implementation

  • 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
43#include <rtems/score/objectimpl.h>
44#include <rtems/rtems/attrimpl.h>
45#include <rtems/rtems/semimpl.h>
46
47#include <rtems/bsd/sys/param.h>
48#include <rtems/bsd/sys/types.h>
49#include <sys/systm.h>
50#include <rtems/bsd/sys/lock.h>
51#include <sys/mutex.h>
52#include <sys/proc.h>
53
54static void assert_mtx(struct lock_object *lock, int what);
55static void lock_mtx(struct lock_object *lock, int how);
56#ifdef KDTRACE_HOOKS
57static int  owner_mtx(struct lock_object *lock, struct thread **owner);
58#endif
59static int  unlock_mtx(struct lock_object *lock);
60
61RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_mtx_chain);
62
63/*
64 * Lock classes for sleep and spin mutexes.
65 */
66struct lock_class lock_class_mtx_sleep = {
67  .lc_name = "sleep mutex",
68  .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
69  .lc_assert = assert_mtx,
70#ifdef DDB
71  .lc_ddb_show = db_show_mtx,
72#endif
73  .lc_lock = lock_mtx,
74  .lc_unlock = unlock_mtx,
75#ifdef KDTRACE_HOOKS
76  .lc_owner = owner_mtx,
77#endif
78};
79
80struct lock_class lock_class_mtx_spin = {
81  .lc_name = "spin mutex",
82  .lc_flags = LC_SPINLOCK | LC_RECURSABLE,
83  .lc_assert = assert_mtx,
84#ifdef DDB
85  .lc_ddb_show = db_show_mtx,
86#endif
87  .lc_lock = lock_mtx,
88  .lc_unlock = unlock_mtx,
89#ifdef KDTRACE_HOOKS
90  .lc_owner = owner_mtx,
91#endif
92};
93
94struct mtx Giant;
95
96void
97assert_mtx(struct lock_object *lock, int what)
98{
99  mtx_assert((struct mtx *)lock, what);
100}
101
102void
103lock_mtx(struct lock_object *lock, int how)
104{
105
106  mtx_lock((struct mtx *)lock);
107}
108
109int
110unlock_mtx(struct lock_object *lock)
111{
112  struct mtx *m;
113
114  m = (struct mtx *)lock;
115  mtx_assert(m, MA_OWNED | MA_NOTRECURSED);
116  mtx_unlock(m);
117  return (0);
118}
119
120
121#ifdef KDTRACE_HOOKS
122int
123owner_mtx(struct lock_object *lock, struct thread **owner)
124{
125  struct mtx *m = (struct mtx *)lock;
126
127  *owner = mtx_owner(m);
128  return (mtx_unowned(m) == 0);
129}
130#endif
131
132void
133mtx_init(struct mtx *m, const char *name, const char *type, int opts)
134{
135  struct lock_class *class;
136  int i;
137        rtems_status_code sc = RTEMS_SUCCESSFUL;
138        rtems_id id = RTEMS_ID_NONE;
139        /* rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING; */
140  rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE;
141
142  if ((opts & MTX_RECURSE) != 0 )
143  {
144    /*FIXME*/
145  }
146
147  /* Determine lock class and lock flags. */
148  if (opts & MTX_SPIN)
149    class = &lock_class_mtx_spin;
150  else
151    class = &lock_class_mtx_sleep;
152
153  /* Check for double-init and zero object. */
154  KASSERT(!lock_initalized(&m->lock_object), ("lock \"%s\" %p already initialized", name, m->lock_object));
155
156  /* Look up lock class to find its index. */
157  for (i = 0; i < LOCK_CLASS_MAX; i++)
158  {
159    if (lock_classes[i] == class)
160    {
161      m->lock_object.lo_flags = i << LO_CLASSSHIFT;
162      break;
163    }
164  }
165  KASSERT(i < LOCK_CLASS_MAX, ("unknown lock class %p", class));
166
167        sc = rtems_semaphore_create(
168                rtems_build_name('_', 'M', 'T', 'X'),
169                1,
170                attr,
171                BSD_TASK_PRIORITY_RESOURCE_OWNER,
172                &id
173        );
174        BSD_ASSERT_SC(sc);
175
176        m->lock_object.lo_name = name;
177  m->lock_object.lo_flags |= LO_INITIALIZED;
178  m->lock_object.lo_id = id;
179
180        rtems_chain_append(&rtems_bsd_mtx_chain, &m->lock_object.lo_node);
181}
182
183void
184_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
185{
186        rtems_status_code sc = RTEMS_SUCCESSFUL;
187
188        sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
189        BSD_ASSERT_SC(sc);
190}
191
192int
193_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
194{
195        rtems_status_code sc = RTEMS_SUCCESSFUL;
196
197        sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_NO_WAIT, 0);
198        if (sc == RTEMS_SUCCESSFUL) {
199                return 1;
200        } else if (sc == RTEMS_UNSATISFIED) {
201                return 0;
202        } else {
203                BSD_ASSERT_SC(sc);
204
205                return 0;
206        }
207}
208
209void
210_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
211{
212        rtems_status_code sc = RTEMS_SUCCESSFUL;
213
214        sc = rtems_semaphore_release(m->lock_object.lo_id);
215        BSD_ASSERT_SC(sc);
216}
217
218/*
219 * The backing function for the INVARIANTS-enabled mtx_assert()
220 */
221#ifdef INVARIANT_SUPPORT
222void
223_mtx_assert(struct mtx *m, int what, const char *file, int line)
224{
225
226  if (panicstr != NULL || dumping)
227    return;
228  switch (what) {
229  case MA_OWNED:
230  case MA_OWNED | MA_RECURSED:
231  case MA_OWNED | MA_NOTRECURSED:
232    if (!mtx_owned(m))
233      panic("mutex %s not owned at %s:%d",
234          m->lock_object.lo_name, file, line);
235    if (mtx_recursed(m)) {
236      if ((what & MA_NOTRECURSED) != 0)
237        panic("mutex %s recursed at %s:%d",
238            m->lock_object.lo_name, file, line);
239    } else if ((what & MA_RECURSED) != 0) {
240      panic("mutex %s unrecursed at %s:%d",
241          m->lock_object.lo_name, file, line);
242    }
243    break;
244  case MA_NOTOWNED:
245    if (mtx_owned(m))
246      panic("mutex %s owned at %s:%d",
247          m->lock_object.lo_name, file, line);
248    break;
249  default:
250    panic("unknown mtx_assert at %s:%d", file, line);
251  }
252}
253#endif
254
255int mtx_owned(struct mtx *m)
256{
257        Objects_Locations location;
258        Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
259
260        if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
261                int owned = sema->Core_control.mutex.holder_id == rtems_task_self();
262
263                _Thread_Enable_dispatch();
264
265                return owned;
266        } else {
267                _Thread_Enable_dispatch();
268
269                BSD_PANIC("unexpected semaphore location or attributes");
270        }
271}
272
273int mtx_recursed(struct mtx *m)
274{
275        Objects_Locations location;
276        Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
277
278        if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
279                int recursed = sema->Core_control.mutex.nest_count != 0;
280
281                _Thread_Enable_dispatch();
282
283                return recursed;
284        } else {
285                _Thread_Enable_dispatch();
286
287                BSD_PANIC("unexpected semaphore location or attributes");
288        }
289}
290
291void
292mtx_sysinit(void *arg)
293{
294        struct mtx_args *margs = arg;
295
296        mtx_init(margs->ma_mtx, margs->ma_desc, NULL, margs->ma_opts);
297}
298
299void
300mtx_destroy(struct mtx *m)
301{
302        rtems_status_code sc = RTEMS_SUCCESSFUL;
303
304        sc = rtems_semaphore_delete(m->lock_object.lo_id);
305        BSD_ASSERT_SC(sc);
306
307        rtems_chain_extract(&m->lock_object.lo_node);
308
309  m->lock_object.lo_id = 0;
310  m->lock_object.lo_flags &= ~LO_INITIALIZED;
311}
312
313void
314mutex_init(void)
315{
316        mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
317}
Note: See TracBrowser for help on using the repository browser.