/***************************************************************************
**
**  This file is part of QGpCoreTools.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file is distributed in the hope that it will be useful, but WITHOUT
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
**  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2007-12-26
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef THREAD_H
#define THREAD_H

#include "Trace.h"
#include "TraceBug.h"
#include "TraceLog.h"
#include "Mutex.h"
#include "QGpCoreToolsDLLExport.h"

namespace QGpCoreTools {

class QGPCORETOOLS_EXPORT Thread : public QThread
{
  Q_OBJECT
public:
  Thread(QObject * parent=nullptr);
  ~Thread();

  static QStringList threadNames();
  static void lockThreads() {_threadsMutex.MUTEX_LOCK;}
  static void unlockThreads() {_threadsMutex.unlock();}
  
  static Thread * currentThread() {return static_cast<Thread *>(QThread::currentThread());}
  void start(QThread::Priority priority=QThread::InheritPriority);
  static void sleep(unsigned long secs);
  static void msleep(unsigned long msecs);
  static void usleep(unsigned long usecs);
  void setSleeping(bool s) {_sleeping.fetchAndStoreOrdered(s);}
  bool sleeping() {return _sleeping.testAndSetOrdered(true, true);}

  static void initCPUAffinityList();
  static int idealThreadCount();
  static const QVector<int>& cpuAffinities() {return _cpuAffinities;}

  static QList< QStack<TraceBug *> * > bugStacks();
  QStack<TraceBug  *> * bugStack() {return &_bugStack;}
  static QList< QVector<TraceLog *> * > logVectors();
  QVector<TraceLog  *> * logVector() {return &_logVector;}
#ifdef TRACE_ENABLED
  static QList< QStack<const TraceStamp *> * > stacks();
  QStack<const TraceStamp *> * stack() {return &_stack;}
#endif
private:
  static Mutex _threadsMutex;
  static QList<Thread *> _threads;
  static QSet<Thread *> _runningThreads;
  QAtomicInt _sleeping;
  static QVector<int> _cpuAffinities;

  QStack<TraceBug *> _bugStack;
  QVector<TraceLog *> _logVector;
#ifdef TRACE_ENABLED
  QStack<const TraceStamp *> _stack;
#endif
};

} // namespace QGpCoreTools

#endif // THREAD_H
