source: rtems/cpukit/libcsupport/src/envlock.c @ f97536d

5
Last change on this file since f97536d was f97536d, checked in by Sebastian Huber <sebastian.huber@…>, on 10/16/15 at 06:21:48

basdefs.h: Add and use RTEMS_UNUSED

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Global Environment Lock Support
5 *  @ingroup libcsupport
6 */
7
8/*
9 *  Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002
10 */
11
12/* provide locking for the global environment 'environ' */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#if defined(HAVE_ENVLOCK_H) \
19  && defined(HAVE_DECL___ENV_LOCK) && defined(HAVE_DECL___ENV_UNLOCK)
20
21#include <envlock.h>
22
23#include <rtems.h>
24#include <sys/reent.h>
25
26#include <assert.h>
27
28/*
29 * NOTES:
30 *  - although it looks like a classical multiple-readers / single writer (MRSW)
31 *    locking problem, we still use a single lock for the following reasons:
32 *     1) newlib has no provision / hook for calling different locking routines
33 *        from setenv/putenv and getenv, respectively.
34 *     2) MRSW involves calling several semaphore-primitives, even in the most
35 *        likely case of a first-reader's access. This probably takes more CPU
36 *        time than just waiting until another reader is done; environment
37 *        access is fast.
38 *  - the lock implementation must allow nesting (same thread may call
39 *    lock-lock-unlock-unlock).
40 *  - NEWLIB-1.8.2 has an ugly BUG: if environ is NULL, _findenv_r() bails
41 *    out leaving the lock held :-(
42 *
43 *  Used by the following functions:
44 *    findenv_r(), setenv_r(), and unsetenv_r() which are called by
45 *    getenv(), getenv_r(), setenv(), and unsetenv().
46 *
47 */
48
49#if defined(ENVLOCK_DEDICATED_MUTEX)
50static rtems_id envLock=0;
51
52static void
53__rtems_envlock_init(void)
54{
55  extern char        **environ;
56  rtems_status_code    rc;
57
58  if (envLock) /* already initialized */
59    return;
60
61  assert(environ && "MUST have non-NULL 'environ' due to newlib bug");
62
63  rc = rtems_semaphore_create(
64      rtems_build_name('E','N','V','S'),
65      1,
66      RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
67      0,
68      &envLock);
69  if (RTEMS_SUCCESSFUL!=rc)
70    rtems_fatal_error_occurred(rc);
71}
72
73void
74__env_lock(struct _reent *r)
75{
76  /* Do lazy init */
77  if (!envLock)
78    __rtems_envlock_init();
79  /*
80   *  Must not use a semaphore before pre-tasking hook is called.
81   *  - it will corrupt memory :-(
82   */
83
84  if (_Thread_Executing)
85    rtems_semaphore_obtain(envLock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
86}
87
88void
89__env_unlock(struct _reent *r)
90{
91  /*
92   *  Must not use a semaphore before pre-tasking hook is called.
93   * - it will corrupt memory :-(
94   */
95  if (_Thread_Executing)
96    rtems_semaphore_release(envLock);
97}
98#else
99
100/*
101 *  Reuse the libio mutex -- it is always initialized before we
102 *  could possibly run.
103 */
104
105#include <rtems/libio_.h>
106
107void
108__env_lock(struct _reent *r RTEMS_UNUSED)
109{
110  rtems_libio_lock();
111}
112
113void
114__env_unlock(struct _reent *r RTEMS_UNUSED)
115{
116  rtems_libio_unlock();
117}
118#endif /* ENVLOCK_DEDICATED_MUTEX */
119
120#endif /* HAVE_ENVLOCK_H ... */
Note: See TracBrowser for help on using the repository browser.