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 rwlock_static_init(pthread_rwlock_t *rw)
{
  int r;
  _spin_lite_lock(&cond_locked);
  if (*rw != PTHREAD_RWLOCK_INITIALIZER)
  {
    _spin_lite_unlock(&cond_locked);
    return EINVAL;
  }
  r = pthread_rwlock_init (rw, NULL);
  _spin_lite_unlock(&cond_locked);
  
  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
static WINPTHREADS_ATTRIBUTE((noinline)) void
barrier_ref_set (volatile pthread_barrier_t *barrier, void *v)
{
  _spin_lite_lock(&barrier_global);
  *barrier = v;
  _spin_lite_unlock(&barrier_global);
}
Beispiel #5
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 #6
0
static __attribute__ ((noinline)) int rwl_unref(volatile pthread_rwlock_t *rwl, int res)
{
    _spin_lite_lock(&rwl_global);
#ifdef WINPTHREAD_DBG
    assert((((rwlock_t *)*rwl)->valid == LIFE_RWLOCK) && (((rwlock_t *)*rwl)->busy > 0));
#endif
     ((rwlock_t *)*rwl)->busy--;
    _spin_lite_unlock(&rwl_global);
    return res;
}
Beispiel #7
0
static __attribute__((noinline)) int mutex_ref_init(pthread_mutex_t *m )
{
    int r = 0;

    _spin_lite_lock(&mutex_global);

    if (!m)  r = EINVAL;

    _spin_lite_unlock(&mutex_global);
    return r;
}
Beispiel #8
0
static WINPTHREADS_ATTRIBUTE((noinline)) int
barrier_unref(volatile pthread_barrier_t *barrier, int res)
{
    _spin_lite_lock(&barrier_global);
#ifdef WINPTHREAD_DBG
    assert((((barrier_t *)*barrier)->valid == LIFE_BARRIER) && (((barrier_t *)*barrier)->busy > 0));
#endif
     ((barrier_t *)*barrier)->busy--;
    _spin_lite_unlock(&barrier_global);
    return res;
}
Beispiel #9
0
static __attribute__((noinline)) int
mutex_unref(pthread_mutex_t *m, int r)
{
    mutex_t *m_ = (mutex_t *)*m;
    _spin_lite_lock(&mutex_global);
#ifdef WINPTHREAD_DBG
    assert((m_->valid == LIFE_MUTEX) && (m_->busy > 0));
#endif
    m_->busy --;
    _spin_lite_unlock(&mutex_global);
    return r;
}
Beispiel #10
0
static WINPTHREADS_ATTRIBUTE((noinline)) int
mutex_ref_init (pthread_mutex_t *m )
{
    int r = 0;

    _spin_lite_lock (&mutex_global);
    
    if (!m)  r = EINVAL;
 
    _spin_lite_unlock (&mutex_global);
    return r;
}
Beispiel #11
0
static WINPTHREADS_ATTRIBUTE((noinline)) int barrier_ref(volatile pthread_barrier_t *barrier)
{
    int r = 0;
    _spin_lite_lock(&barrier_global);

    if (!barrier || !*barrier || ((barrier_t *)*barrier)->valid != LIFE_BARRIER) r = EINVAL;
    else {
        ((barrier_t *)*barrier)->busy ++;
    }

    _spin_lite_unlock(&barrier_global);

    return r;
}
Beispiel #12
0
static __attribute__((noinline)) int rwl_ref(pthread_rwlock_t *rwl, int f )
{
    int r = 0;
    INIT_RWLOCK(rwl);
    _spin_lite_lock(&rwl_global);

    if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
    else {
        ((rwlock_t *)*rwl)->busy ++;
    }

    _spin_lite_unlock(&rwl_global);

    return r;
}
Beispiel #13
0
int pthread_spin_destroy(pthread_spinlock_t *l)
{
  spin_t *_l;
  if (!l || !*l) return EINVAL;
  _spin_lite_lock(&spin_locked);
  if (*l == PTHREAD_SPINLOCK_INITIALIZER)
  {
    *l = NULL;
    _spin_lite_unlock(&spin_locked);
    return 0;
  }
  _spin_lite_unlock(&spin_locked);
  _l = (spin_t *)*l;
  if (((spin_t *)(*l))->valid != (unsigned int)LIFE_SPINLOCK)
    return EINVAL;
  
  if (_l->l != 0)
    return EBUSY;
  *l= NULL; /* dereference first, free later */
  _l->valid  = DEAD_SPINLOCK;
  _l->l = 0;
  free(_l);
  return 0;
}
Beispiel #14
0
static __attribute__((noinline)) int rwl_ref_unlock(pthread_rwlock_t *rwl )
{
    int r = 0;

    _spin_lite_lock(&rwl_global);

    if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
    else if (STATIC_RWL_INITIALIZER(*rwl)) r= EPERM;
    else {
        ((rwlock_t *)*rwl)->busy ++;
    }

    _spin_lite_unlock(&rwl_global);

    return r;
}
Beispiel #15
0
static inline int
spinlock_static_init (pthread_spinlock_t *l)
{
  int ret;
  _spin_lite_lock(&spin_locked);
  if (PTHREAD_SPINLOCK_INITIALIZER != *l)
  {
    /* Check that somebody called destroy already.  Otherwise assume someone crept in between.  */
    ret = (*l == NULL ? EINVAL : 0);
  }
  else
  {
    ret = pthread_spin_init(l, PTHREAD_PROCESS_PRIVATE);
  }
  _spin_lite_unlock(&spin_locked);
  return ret;
}
Beispiel #16
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 #17
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 #18
0
int pthread_rwlock_destroy (pthread_rwlock_t *rwlock_)
{
    rwlock_t *rwlock;
    pthread_rwlock_t rDestroy;
    int r, r2;
    
    _spin_lite_lock(&cond_locked);
    r = rwl_ref_destroy(rwlock_,&rDestroy);
    _spin_lite_unlock(&cond_locked);
    
    if(r) return r;
    if(!rDestroy) return 0; /* destroyed a (still) static initialized rwl */

    rwlock = (rwlock_t *)rDestroy;
    r = rwlock_gain_both_locks (rwlock);
    if (r != 0)
    {
      *rwlock_ = rDestroy;
      return r;
    }
    if (rwlock->nsh_count > rwlock->ncomplete || rwlock->nex_count > 0)
    {
      *rwlock_ = rDestroy;
      r = rwlock_free_both_locks(rwlock, 1);
      if (!r)
        r = EBUSY;
      return r;
    }
    rwlock->valid  = DEAD_RWLOCK;
    r = rwlock_free_both_locks(rwlock, 0);
    if (r != 0) { *rwlock_ = rDestroy; return r; }

    r = pthread_cond_destroy(&rwlock->ccomplete);
    r2 = pthread_mutex_destroy(&rwlock->mex);
    if (!r) r = r2;
    r2 = pthread_mutex_destroy(&rwlock->mcomplete);
    if (!r) r = r2;
    rwlock->valid  = DEAD_RWLOCK;
    free(rDestroy);
    return 0;
} 
Beispiel #19
0
static WINPTHREADS_ATTRIBUTE((noinline))  int
barrier_ref_destroy(volatile pthread_barrier_t *barrier, pthread_barrier_t *bDestroy)
{
    int r = 0;

    *bDestroy = NULL;
    if (_spin_lite_trylock(&barrier_global)) return EBUSY;
    
    if (!barrier || !*barrier || ((barrier_t *)*barrier)->valid != LIFE_BARRIER) r = EINVAL;
    else {
        barrier_t *b_ = (barrier_t *)*barrier;
        if (b_->busy) r = EBUSY;
        else {
            *bDestroy = *barrier;
            *barrier = NULL;
        }
    }

    _spin_lite_unlock(&barrier_global);
    return r;
}
Beispiel #20
0
static __attribute__((noinline)) int rwl_ref_destroy(pthread_rwlock_t *rwl, pthread_rwlock_t *rDestroy )
{
    int r = 0;

    *rDestroy = NULL;
    if (_spin_lite_trylock(&rwl_global)) return EBUSY;
    
    if (!rwl || !*rwl) r = EINVAL;
    else {
        rwlock_t *r_ = (rwlock_t *)*rwl;
        if (STATIC_RWL_INITIALIZER(*rwl)) *rwl = NULL;
        else if (r_->valid != LIFE_RWLOCK) r = EINVAL;
        else if (r_->busy) r = EBUSY;
        else {
            *rDestroy = *rwl;
            *rwl = NULL;
        }
    }

    _spin_lite_unlock(&rwl_global);
    return r;
}