source: rtems/cpukit/libcsupport/src/envlock.c @ 068a824

4.104.115
Last change on this file since 068a824 was 068a824, checked in by Sebastian Huber <sebastian.huber@…>, on 04/30/10 at 08:55:41

2010-04-30 Sebastian Huber <sebastian.huber@…>

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