/*
 * atomic.h: Atomic operations
 *
 * See the main source file 'xineliboutput.c' for copyright information and
 * how to reach the author.
 *
 * $Id$
 *
 */

#ifndef _XINELIBOUTPUT_ATOMIC_H_
#define _XINELIBOUTPUT_ATOMIC_H_

#ifndef XINELIBOUTPUT_FEATURES_H
# error features.h must be included first
#endif

#ifdef HAVE_STDATOMIC_H
# include <stdatomic.h>
#else
# include <pthread.h>
#endif

typedef struct {
  int             value;
#ifndef HAVE_STDATOMIC_H
  pthread_mutex_t lock;
#endif
} xl_atomic_int;

static inline int _xl_atomic_load(xl_atomic_int *a)
{
#ifdef HAVE_STDATOMIC_H
  return atomic_load(&a->value);
#else
  int result;
  pthread_mutex_lock(&a->lock);
  result = a->value;
  pthread_mutex_unlock(&a->lock);
  return result;
#endif
}

static inline void _xl_atomic_store(xl_atomic_int *a, int value)
{
#ifdef HAVE_STDATOMIC_H
  atomic_store(&a->value, value);
#else
  pthread_mutex_lock(&a->lock);
  a->value = value;
  pthread_mutex_unlock(&a->lock);
#endif
}

static inline void _xl_atomic_init(xl_atomic_int *a, int value)
{
#ifdef HAVE_STDATOMIC_H
  atomic_init(&a->value, value);
#else
  pthread_mutex_init (&a->lock, NULL);
  _xl_atomic_store(a, value);
#endif
}

static inline void _xl_atomic_destroy(xl_atomic_int *a)
{
#ifdef HAVE_STDATOMIC_H
  (void)a;
#else
  pthread_mutex_destroy(&a->lock);
#endif
}

#endif /* _XINELIBOUTPUT_ATOMIC_H_ */
