OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libcsupport/] [src/] [envlock.c] - Rev 1026

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *  Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002
 * 
 *  envlock.c,v 1.2 2002/05/17 18:03:34 joel Exp
 */
 
/* provide locking for the global environment 'environ' */
 
#if HAVE_CONFIG_H
#include "config.h"
#endif
 
#include <rtems.h>
#include <sys/reent.h>
 
#include <assert.h>
 
/*
 * NOTES:
 *  - although it looks like a classical multiple-readers / single writer (MRSW)
 *    locking problem, we still use a single lock for the following reasons:
 *     1) newlib has no provision / hook for calling different locking routines
 *        from setenv/putenv and getenv, respectively.
 *     2) MRSW involves calling several semaphore-primitives, even in the most
 *        likely case of a first-reader's access. This probably takes more CPU
 *        time than just waiting until another reader is done; environment
 *        access is fast.
 *  - the lock implementation must allow nesting (same thread may call
 *    lock-lock-unlock-unlock).
 *  - NEWLIB-1.8.2 has an ugly BUG: if environ is NULL, _findenv_r() bails
 *    out leaving the lock held :-(
 *
 *  Used by the following functions:
 *    findenv_r(), setenv_r(), and unsetenv_r() which are called by
 *    getenv(), getenv_r(), setenv(), and unsetenv().
 *  
 */
 
#if defined(ENVLOCK_DEDIDCATED_MUTEX)
static rtems_id envLock=0;
 
static void
__rtems_envlock_init(void)
{
  extern char        **environ;
  rtems_status_code    rc;
 
  if (envLock) /* already initialized */
    return;
 
  assert(environ && "MUST have non-NULL 'environ' due to newlib bug");
 
  rc = rtems_semaphore_create(
      rtems_build_name('E','N','V','S'),
      1,
      RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
      0,
      &envLock);
  if (RTEMS_SUCCESSFUL!=rc)
    rtems_fatal_error_occurred(rc);
}
 
void
__env_lock(struct _reent *r)
{
  /* Do lazy init */
  if (!envLock)
    __rtems_envlock_init();
  /*
   *  Must not use a semaphore before pre-tasking hook is called.
   *  - it will corrupt memory :-(
   */
 
  if (_Thread_Executing)
    rtems_semaphore_obtain(envLock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
}
 
void
__env_unlock(struct _reent *r)
{
  /*
   *  Must not use a semaphore before pre-tasking hook is called.
   * - it will corrupt memory :-(
   */
  if (_Thread_Executing)
    rtems_semaphore_release(envLock);
}
#else
 
/*
 *  Reuse the libio mutex -- it is always initialized before we
 *  could possibly run.
 */
 
#include <rtems/libio_.h>
 
void
__env_lock(struct _reent *r)
{
  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
}
 
void
__env_unlock(struct _reent *r)
{
  rtems_semaphore_release( rtems_libio_semaphore );
}
#endif
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.