source: rtems-libbsd/rtemsbsd/rtems/rtems-bsd-sx.c @ e599318

4.115-freebsd-12freebsd-9.3
Last change on this file since e599318 was e599318, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 9, 2013 at 8:52:54 PM

Update files to match FreeBSD layout

Add compatibility with Newlib header files. Some FreeBSD header files
are mapped by the translation script:

o rtems/bsd/sys/_types.h
o rtems/bsd/sys/errno.h
o rtems/bsd/sys/lock.h
o rtems/bsd/sys/param.h
o rtems/bsd/sys/resource.h
o rtems/bsd/sys/time.h
o rtems/bsd/sys/timespec.h
o rtems/bsd/sys/types.h
o rtems/bsd/sys/unistd.h

It is now possible to include <sys/socket.h> directly for example.

Generate one Makefile which builds everything including tests.

  • Property mode set to 100644
File size: 8.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
42#include <rtems/score/objectimpl.h>
43#include <rtems/rtems/attrimpl.h>
44#include <rtems/rtems/semimpl.h>
45
46#include <rtems/bsd/sys/param.h>
47#include <rtems/bsd/sys/types.h>
48#include <sys/systm.h>
49#include <rtems/bsd/sys/lock.h>
50#include <sys/sx.h>
51
52#ifndef INVARIANTS
53#define _sx_assert(sx, what, file, line)
54#endif
55
56static void assert_sx(struct lock_object *lock, int what);
57static void lock_sx(struct lock_object *lock, int how);
58#ifdef KDTRACE_HOOKS
59static int  owner_sx(struct lock_object *lock, struct thread **owner);
60#endif
61static int  unlock_sx(struct lock_object *lock);
62
63struct lock_class lock_class_sx = {
64  .lc_name = "sx",
65  .lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE,
66  .lc_assert = assert_sx,
67#ifdef DDB
68  .lc_ddb_show = db_show_sx,
69#endif
70  .lc_lock = lock_sx,
71  .lc_unlock = unlock_sx,
72#ifdef KDTRACE_HOOKS
73  .lc_owner = owner_sx,
74#endif
75};
76
77RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_sx_chain);
78
79void
80assert_sx(struct lock_object *lock, int what)
81{
82  sx_assert((struct sx *)lock, what);
83}
84
85void
86lock_sx(struct lock_object *lock, int how)
87{
88  struct sx *sx;
89
90  sx = (struct sx *)lock;
91  if (how)
92    sx_xlock(sx);
93  else
94    sx_slock(sx);
95}
96
97int
98unlock_sx(struct lock_object *lock)
99{
100  struct sx *sx;
101
102  sx = (struct sx *)lock;
103  sx_assert(sx, SA_LOCKED | SA_NOTRECURSED);
104  if (sx_xlocked(sx)) {
105    sx_xunlock(sx);
106    return (1);
107  } else {
108    sx_sunlock(sx);
109    return (0);
110  }
111}
112
113#ifdef KDTRACE_HOOKS
114int
115owner_sx(struct lock_object *lock, struct thread **owner)
116{
117        struct sx *sx = (struct sx *)lock;
118  uintptr_t x = sx->sx_lock;
119
120        *owner = (struct thread *)SX_OWNER(x);
121        return ((x & SX_LOCK_SHARED) != 0 ? (SX_SHARERS(x) != 0) :
122      (*owner != NULL));
123}
124#endif
125
126void
127sx_sysinit(void *arg)
128{
129        struct sx_args *sargs = arg;
130
131        sx_init(sargs->sa_sx, sargs->sa_desc);
132}
133
134void
135sx_init_flags(struct sx *sx, const char *description, int opts)
136{
137  struct lock_class *class;
138  int i;
139        rtems_status_code sc = RTEMS_SUCCESSFUL;
140        rtems_id id = RTEMS_ID_NONE;
141        rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE;
142
143        if ((opts & SX_RECURSE) != 0) {
144                /* FIXME */
145        }
146
147  class = &lock_class_sx;
148
149  /* Check for double-init and zero object. */
150  KASSERT(!lock_initalized(&sx->lock_object), ("lock \"%s\" %p already initialized", name, sx->lock_object));
151
152  /* Look up lock class to find its index. */
153  for (i = 0; i < LOCK_CLASS_MAX; i++)
154  {
155    if (lock_classes[i] == class)
156    {
157      sx->lock_object.lo_flags = i << LO_CLASSSHIFT;
158      break;
159    }
160  }
161  KASSERT(i < LOCK_CLASS_MAX, ("unknown lock class %p", class));
162
163        sc = rtems_semaphore_create(
164                rtems_build_name( '_', 'S', 'X', ' '),
165                1,
166                attr,
167                0,
168                &id
169        );
170        BSD_ASSERT_SC(sc);
171
172        sx->lock_object.lo_name = description;
173  sx->lock_object.lo_flags |= LO_INITIALIZED;
174  sx->lock_object.lo_id = id;
175
176        rtems_chain_append(&rtems_bsd_sx_chain, &sx->lock_object.lo_node);
177}
178
179void
180sx_destroy(struct sx *sx)
181{
182        rtems_status_code sc = RTEMS_SUCCESSFUL;
183
184        sc = rtems_semaphore_delete( sx->lock_object.lo_id);
185        BSD_ASSERT_SC(sc);
186
187        rtems_chain_extract(&sx->lock_object.lo_node);
188
189  sx->lock_object.lo_id = 0;
190  sx->lock_object.lo_flags &= ~LO_INITIALIZED;
191}
192
193int
194_sx_xlock(struct sx *sx, int opts, const char *file, int line)
195{
196        rtems_status_code sc = RTEMS_SUCCESSFUL;
197
198        #warning "SX_INTERRUPTIBLE NOT SUPPORTED YET"
199        /* BSD_ASSERT((opts & SX_INTERRUPTIBLE) == 0); */
200        BSD_ASSERT(!rtems_interrupt_is_in_progress());
201       
202        sc = rtems_semaphore_obtain( sx->lock_object.lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
203        BSD_ASSERT_SC(sc);
204
205        return 0;
206}
207
208int
209_sx_try_xlock(struct sx *sx, const char *file, int line)
210{
211        rtems_status_code sc = RTEMS_SUCCESSFUL;
212
213        sc = rtems_semaphore_obtain( sx->lock_object.lo_id, RTEMS_NO_WAIT, 0);
214        if (sc == RTEMS_SUCCESSFUL) {
215                return 1;
216        } else if (sc == RTEMS_UNSATISFIED) {
217                return 0;
218        } else {
219                BSD_ASSERT_SC(sc);
220
221                return 0;
222        }
223}
224
225void
226_sx_xunlock(struct sx *sx, const char *file, int line)
227{
228        rtems_status_code sc = RTEMS_SUCCESSFUL;
229
230        sc = rtems_semaphore_release( sx->lock_object.lo_id);
231        BSD_ASSERT_SC(sc);
232}
233
234int
235_sx_try_upgrade(struct sx *sx, const char *file, int line)
236{
237        return 1;
238}
239
240void
241_sx_downgrade(struct sx *sx, const char *file, int line)
242{
243        /* Do nothing */
244}
245
246#ifdef INVARIANT_SUPPORT
247#ifndef INVARIANTS
248#undef  _sx_assert
249#endif
250
251/*
252 * In the non-WITNESS case, sx_assert() can only detect that at least
253 * *some* thread owns an slock, but it cannot guarantee that *this*
254 * thread owns an slock.
255 */
256void
257_sx_assert(struct sx *sx, int what, const char *file, int line)
258{
259#ifndef WITNESS
260  int slocked = 0;
261#endif
262
263  if (panicstr != NULL)
264    return;
265  switch (what) {
266  case SA_SLOCKED:
267  case SA_SLOCKED | SA_NOTRECURSED:
268  case SA_SLOCKED | SA_RECURSED:
269#ifndef WITNESS
270    slocked = 1;
271    /* FALLTHROUGH */
272#endif
273  case SA_LOCKED:
274  case SA_LOCKED | SA_NOTRECURSED:
275  case SA_LOCKED | SA_RECURSED:
276#ifdef WITNESS
277    witness_assert(&sx->lock_object, what, file, line);
278#else
279    /*
280     * If some other thread has an exclusive lock or we
281     * have one and are asserting a shared lock, fail.
282     * Also, if no one has a lock at all, fail.
283     */
284    if (sx->sx_lock == SX_LOCK_UNLOCKED ||
285        (!(sx->sx_lock & SX_LOCK_SHARED) && (slocked ||
286        sx_xholder(sx) != curthread)))
287      panic("Lock %s not %slocked @ %s:%d\n",
288          sx->lock_object.lo_name, slocked ? "share " : "",
289          file, line);
290
291    if (!(sx->sx_lock & SX_LOCK_SHARED)) {
292      if (sx_recursed(sx)) {
293        if (what & SA_NOTRECURSED)
294          panic("Lock %s recursed @ %s:%d\n",
295              sx->lock_object.lo_name, file,
296              line);
297      } else if (what & SA_RECURSED)
298        panic("Lock %s not recursed @ %s:%d\n",
299            sx->lock_object.lo_name, file, line);
300    }
301#endif
302    break;
303  case SA_XLOCKED:
304  case SA_XLOCKED | SA_NOTRECURSED:
305  case SA_XLOCKED | SA_RECURSED:
306    if (sx_xholder(sx) != curthread)
307      panic("Lock %s not exclusively locked @ %s:%d\n",
308          sx->lock_object.lo_name, file, line);
309    if (sx_recursed(sx)) {
310      if (what & SA_NOTRECURSED)
311        panic("Lock %s recursed @ %s:%d\n",
312            sx->lock_object.lo_name, file, line);
313    } else if (what & SA_RECURSED)
314      panic("Lock %s not recursed @ %s:%d\n",
315          sx->lock_object.lo_name, file, line);
316    break;
317  case SA_UNLOCKED:
318#ifdef WITNESS
319    witness_assert(&sx->lock_object, what, file, line);
320#else
321    /*
322     * If we hold an exclusve lock fail.  We can't
323     * reliably check to see if we hold a shared lock or
324     * not.
325     */
326    if (sx_xholder(sx) == curthread)
327      panic("Lock %s exclusively locked @ %s:%d\n",
328          sx->lock_object.lo_name, file, line);
329#endif
330    break;
331  default:
332    panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
333        line);
334  }
335}
336#endif  /* INVARIANT_SUPPORT */
337
338int
339sx_xlocked(struct sx *sx)
340{
341        Objects_Locations location;
342        Semaphore_Control *sema = _Semaphore_Get(sx->lock_object.lo_id, &location);
343
344        if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
345                int xlocked = sema->Core_control.mutex.holder_id == rtems_task_self();
346
347                _Thread_Enable_dispatch();
348
349                return xlocked;
350        } else {
351                _Thread_Enable_dispatch();
352
353                BSD_PANIC("unexpected semaphore location or attributes");
354        }
355}
Note: See TracBrowser for help on using the repository browser.