Beispiel #1
0
/* A busy mutex can't be destroyed */
static __attribute__((noinline)) int
mutex_ref(pthread_mutex_t *m )
{
    int r = 0;

    _spin_lite_lock(&mutex_global);
    if (!m || !*m)
    {
        _spin_lite_unlock(&mutex_global);
        return EINVAL;
    }
    if (STATIC_INITIALIZER(*m))
    {
        _spin_lite_unlock(&mutex_global);
        r = mutex_static_init(m);
        _spin_lite_lock(&mutex_global);
        if (r != 0 && r != EBUSY)
        {
            _spin_lite_unlock(&mutex_global);
            return r;
        }
    }
    r = 0;
    if (!m || !*m || ((mutex_t *)*m)->valid != LIFE_MUTEX) r = EINVAL;
    else {
        ((mutex_t *)*m)->busy ++;
    }

    _spin_lite_unlock(&mutex_global);

    return r;
}
Beispiel #2
0
static __attribute__((noinline)) int
mutex_static_init(pthread_mutex_t *m)
{
    static pthread_mutexattr_t mxattr_recursive = PTHREAD_MUTEX_RECURSIVE;
    static pthread_mutexattr_t mxattr_errorcheck = PTHREAD_MUTEX_ERRORCHECK;

    int r;

    _spin_lite_lock(&mutex_global_static);
    if (!STATIC_INITIALIZER(*m)) {
        /* Assume someone crept in between: */
        r = 0;
    }
    else
    {
        if (*m == PTHREAD_MUTEX_INITIALIZER)
            r = pthread_mutex_init (m, NULL);
        else if (*m == PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
            r = pthread_mutex_init (m, &mxattr_recursive);
        else if (*m == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
            r = pthread_mutex_init (m, &mxattr_errorcheck);
        else if (*m == NULL)
            r = EINVAL;
        else
            r = pthread_mutex_init(m, NULL);
    }
    _spin_lite_unlock(&mutex_global_static);
    return r;
}
Beispiel #3
0
/* A busy mutex can't be destroyed -> EBUSY */
static WINPTHREADS_ATTRIBUTE((noinline)) int
mutex_ref_destroy (pthread_mutex_t *m, pthread_mutex_t *mDestroy )
{
  int r = 0;

  *mDestroy = NULL;
  /* also considered as busy, any concurrent access prevents destruction: $$$$ */
  if (_spin_lite_trylock (&mutex_global) != 0)
    return EBUSY;
    
  if (!m || !*m)
    r = EINVAL;
  else
  {
    mutex_t *m_ = (mutex_t *)*m;
    if (STATIC_INITIALIZER(*m)) 
	  *m = NULL;
    else if (m_->valid != LIFE_MUTEX) 
	  r = EINVAL;
    else if (m_->busy || COND_LOCKED(m_)) 
	  r = EBUSY;
    else
    {
	  *mDestroy = *m;
	  *m = NULL;
    }
  }

  _spin_lite_unlock (&mutex_global);
  return r;
}
Beispiel #4
0
/* A busy mutex can't be destroyed -> EBUSY */
static WINPTHREADS_ATTRIBUTE((noinline)) int
mutex_ref_destroy (pthread_mutex_t *m, pthread_mutex_t *mDestroy)
{
  pthread_mutex_t mx;
  mutex_t *m_;
  int r = 0;

  if (!m || !*m)
    return EINVAL;

  *mDestroy = NULL;
  /* also considered as busy, any concurrent access prevents destruction: */
  mx = *m;
  r = pthread_mutex_trylock (&mx);
  if (r)
    return r;

  pthread_spin_lock (&mutex_global);

  if (!*m)
    r = EINVAL;
  else
  {
    m_ = (mutex_t *)*m;
    if (STATIC_INITIALIZER(*m))
      *m = NULL;
    else  if (m_->valid != LIFE_MUTEX)
      r = EINVAL;
    else if (m_->busy)
      r = 0xbeef;
    else
    {
      *mDestroy = *m;
      *m = NULL;
    }
  }

  if (r)
    {
      pthread_spin_unlock (&mutex_global);
      pthread_mutex_unlock (&mx);
    }
  return r;
}
Beispiel #5
0
/* An unlock can simply fail with EPERM instead of auto-init (can't be owned) */
static WINPTHREADS_ATTRIBUTE((noinline)) int
mutex_ref_unlock (pthread_mutex_t *m)
{
  int r = 0;
  mutex_t *m_ = (mutex_t *)*m;

  _spin_lite_lock (&mutex_global);

  if (!m || !*m || ((mutex_t *)*m)->valid != LIFE_MUTEX) 
    r = EINVAL;
  else if (STATIC_INITIALIZER(*m) || !COND_LOCKED(m_))
    r = EPERM;
  else
    ((mutex_t *)*m)->busy ++;

  _spin_lite_unlock (&mutex_global);

  return r;
}
Beispiel #6
0
/* An unlock can simply fail with EPERM instead of auto-init (can't be owned) */
static __attribute__((noinline)) int
mutex_ref_unlock(pthread_mutex_t *m)
{
    int r = 0;
    mutex_t *m_ = (mutex_t *)*m;

    _spin_lite_lock(&mutex_global);

    if (!m || !*m || ((mutex_t *)*m)->valid != LIFE_MUTEX) r = EINVAL;
    else if (STATIC_INITIALIZER(*m) || !COND_LOCKED(m_)) {
        r= EPERM;
    }
    else {
        ((mutex_t *)*m)->busy ++;
    }

    _spin_lite_unlock(&mutex_global);

    return r;
}
Beispiel #7
0
/* A busy mutex can't be destroyed */
static WINPTHREADS_ATTRIBUTE((noinline)) int
mutex_ref (pthread_mutex_t *m)
{
  int r = 0;

  pthread_spin_lock (&mutex_global);

  if (!m || !*m)
  {
    pthread_spin_unlock (&mutex_global);
    return EINVAL;
  }

  if (STATIC_INITIALIZER(*m))
  {
    pthread_spin_unlock (&mutex_global);
    r = mutex_static_init (m);
    pthread_spin_lock (&mutex_global);

    if (r != 0 && r != EBUSY)
    {
      pthread_spin_unlock (&mutex_global);
      return r;
    }
  }
  
  r = 0;
  
  if (!m || !*m || ((mutex_t *)*m)->valid != LIFE_MUTEX) 
    r = EINVAL;
  else
    ((mutex_t *)*m)->busy += 1;

  pthread_spin_unlock (&mutex_global);

  return r;
}