Blame libdjvu/atomic.cpp

Packit df99a1
/* -*- C -*-
Packit df99a1
// -------------------------------------------------------------------
Packit df99a1
// Atomic primitives
Packit df99a1
// Copyright (c) 2008  Leon Bottou. All rights reserved
Packit df99a1
//
Packit df99a1
// Permission is hereby granted, free of charge, to any person obtaining
Packit df99a1
// a copy of this software and associated documentation files (the
Packit df99a1
// "Software"), to deal in the Software without restriction, including
Packit df99a1
// without limitation the rights to use, copy, modify, merge, publish,
Packit df99a1
// distribute, sublicense, and/or sell copies of the Software, and to
Packit df99a1
// permit persons to whom the Software is furnished to do so, subject to
Packit df99a1
// the following conditions:
Packit df99a1
//
Packit df99a1
// The above copyright notice and this permission notice shall be
Packit df99a1
// included in all copies or substantial portions of the Software.
Packit df99a1
//
Packit df99a1
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit df99a1
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit df99a1
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Packit df99a1
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
Packit df99a1
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
Packit df99a1
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
Packit df99a1
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit df99a1
//
Packit df99a1
// ------------------------------------------------------------------- */
Packit df99a1
Packit df99a1
#include "atomic.h"
Packit df99a1
Packit df99a1
#ifndef ATOMIC_MACROS
Packit df99a1
Packit df99a1
#if HAVE_PTHREAD
Packit df99a1
# include <pthread.h>
Packit df99a1
#elif HAVE_QTHREAD  // never defined at the moment.
Packit df99a1
# include <QMutex>
Packit df99a1
# include <QWaitCondition>
Packit df99a1
#else
Packit df99a1
# include "GThreads.h"
Packit df99a1
#endif
Packit df99a1
Packit df99a1
/* Select synchronization primitives */
Packit df99a1
Packit df99a1
# if defined(_WIN32) || defined(_WIN64)
Packit df99a1
Packit df99a1
namespace {
Packit df99a1
  struct CS { 
Packit df99a1
    CRITICAL_SECTION cs; 
Packit df99a1
    CS() { InitializeCriticalSection(&cs); }
Packit df99a1
    ~CS() { DeleteCriticalSecton(&cs); } }; }
Packit df99a1
static CS globalCS;
Packit df99a1
# define MUTEX_LEAVE LeaveCriticalSection(&globalCS.cs)
Packit df99a1
# define MUTEX_ENTER EnterCriticalSection(&globalCS.cs);
Packit df99a1
Packit df99a1
# elif defined (PTHREAD_MUTEX_INITIALIZER)
Packit df99a1
Packit df99a1
static pthread_mutex_t ptm = PTHREAD_MUTEX_INITIALIZER;
Packit df99a1
# define MUTEX_ENTER  pthread_mutex_lock(&ptm)
Packit df99a1
# define MUTEX_LEAVE  pthread_mutex_unlock(&ptm)
Packit df99a1
Packit df99a1
# elif defined(__cplusplus) && defined(_GTHREADS_H_)
Packit df99a1
Packit df99a1
static GMonitor m;
Packit df99a1
# define MUTEX_ENTER  m.enter()
Packit df99a1
# define MUTEX_LEAVE  m.leave()
Packit df99a1
Packit df99a1
# elif defined(__cplusplus) && defined(QMUTEX_H)
Packit df99a1
Packit df99a1
static QMutex qtm;
Packit df99a1
# define MUTEX_ENTER  qtm.lock()
Packit df99a1
# define MUTEX_LEAVE  qtm.unlock()
Packit df99a1
Packit df99a1
# endif
Packit df99a1
Packit df99a1
Packit df99a1
/* atomic primitive emulation */
Packit df99a1
Packit df99a1
int
Packit df99a1
atomicIncrement(int volatile *var)
Packit df99a1
{
Packit df99a1
  int res;
Packit df99a1
  MUTEX_ENTER;
Packit df99a1
  res = ++(*var);
Packit df99a1
  MUTEX_LEAVE;
Packit df99a1
  return res;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
atomicDecrement(int volatile *var)
Packit df99a1
{
Packit df99a1
  int res;
Packit df99a1
  MUTEX_ENTER;
Packit df99a1
  res = --(*var);
Packit df99a1
  MUTEX_LEAVE;
Packit df99a1
  return res;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
atomicCompareAndSwap(int volatile *var, int oldval, int newval)
Packit df99a1
{
Packit df99a1
  int ret;
Packit df99a1
  MUTEX_ENTER;
Packit df99a1
  ret = *var;
Packit df99a1
  if (ret == oldval)
Packit df99a1
    *var = newval;
Packit df99a1
  MUTEX_LEAVE;
Packit df99a1
  return ret;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
atomicExchange(int volatile *var, int newval)
Packit df99a1
{
Packit df99a1
  int ret;
Packit df99a1
  MUTEX_ENTER;
Packit df99a1
  ret = *var;
Packit df99a1
  *var = newval;
Packit df99a1
  MUTEX_LEAVE;
Packit df99a1
  return ret;
Packit df99a1
}
Packit df99a1
Packit df99a1
void* 
Packit df99a1
atomicExchangePointer(void* volatile *var, void* newval)
Packit df99a1
{
Packit df99a1
  void *ret;
Packit df99a1
  MUTEX_ENTER;
Packit df99a1
  ret = *var;
Packit df99a1
  *var = newval;
Packit df99a1
  MUTEX_LEAVE;
Packit df99a1
  return ret;
Packit df99a1
}
Packit df99a1
Packit df99a1
#endif 
Packit df99a1
Packit df99a1