//! \~\file piintrospection_threads.h
//! \~\ingroup Introspection
//! \~\brief
//! \~english Thread introspection helpers
//! \~russian Вспомогательные средства интроспекции потоков
/*
    PIP - Platform Independent Primitives
    Introspection module - interface for threads
    Ivan Pelipenko peri4ko@yandex.ru

    This program 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 3 of the License, or
    (at your option) any later version.

    This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PIINTROSPECTION_THREADS_H
#define PIINTROSPECTION_THREADS_H

#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)

#  include "piintrospection_base.h"

class PIIntrospectionThreads;

#  define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())

#  ifdef DOXYGEN

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Registers creation of thread object `t`.
//! \~russian Регистрирует создание объекта потока `t`.
#	define PIINTROSPECTION_THREAD_NEW(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Registers destruction of thread object `t`.
//! \~russian Регистрирует уничтожение объекта потока `t`.
#	define PIINTROSPECTION_THREAD_DELETE(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Marks thread `t` as starting.
//! \~russian Помечает поток `t` как запускающийся.
#	define PIINTROSPECTION_THREAD_START(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Marks thread `t` as running.
//! \~russian Помечает поток `t` как выполняющийся.
#	define PIINTROSPECTION_THREAD_RUN(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Marks thread `t` as waiting.
//! \~russian Помечает поток `t` как ожидающий.
#	define PIINTROSPECTION_THREAD_WAIT(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Marks thread `t` as stopped.
//! \~russian Помечает поток `t` как остановленный.
#	define PIINTROSPECTION_THREAD_STOP(t)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionThreadsInterface
//! \~\brief
//! \~english Reports completed run of thread `t` that took `us` microseconds.
//! \~russian Сообщает о завершенном проходе потока `t`, занявшем `us` микросекунд.
#	define PIINTROSPECTION_THREAD_RUN_DONE(t, us)

#  else

#	define PIINTROSPECTION_THREAD_NEW(t)          PIINTROSPECTION_THREADS->threadNew(t);
#	define PIINTROSPECTION_THREAD_DELETE(t)       PIINTROSPECTION_THREADS->threadDelete(t);
#	define PIINTROSPECTION_THREAD_START(t)        PIINTROSPECTION_THREADS->threadStart(t);
#	define PIINTROSPECTION_THREAD_RUN(t)          PIINTROSPECTION_THREADS->threadRun(t);
#	define PIINTROSPECTION_THREAD_WAIT(t)         PIINTROSPECTION_THREADS->threadWait(t);
#	define PIINTROSPECTION_THREAD_STOP(t)         PIINTROSPECTION_THREADS->threadStop(t);
#	define PIINTROSPECTION_THREAD_RUN_DONE(t, us) PIINTROSPECTION_THREADS->threadRunDone(t, us);

#  endif

//! \~\ingroup Introspection
//! \~\brief
//! \~english Entry point for collecting state and timing statistics of \a PIThread objects.
//! \~russian Точка входа для сбора статистики состояний и времени выполнения объектов \a PIThread.
class PIP_EXPORT PIIntrospectionThreadsInterface {
	friend class PIIntrospection;

public:
	__PIINTROSPECTION_SINGLETON_H__(Threads)

	//! \~english Registers creation of thread object `t`.
	//! \~russian Регистрирует создание объекта потока `t`.
	void threadNew(PIThread * t);

	//! \~english Registers destruction of thread object `t`.
	//! \~russian Регистрирует уничтожение объекта потока `t`.
	void threadDelete(PIThread * t);

	//! \~english Updates statistics for thread `t` when it starts.
	//! \~russian Обновляет статистику потока `t` при его запуске.
	void threadStart(PIThread * t);

	//! \~english Updates statistics for thread `t` when its run handler begins.
	//! \~russian Обновляет статистику потока `t`, когда начинается его рабочий проход.
	void threadRun(PIThread * t);

	//! \~english Marks thread `t` as waiting for the next run.
	//! \~russian Помечает поток `t` как ожидающий следующего прохода.
	void threadWait(PIThread * t);

	//! \~english Marks thread `t` as stopped.
	//! \~russian Помечает поток `t` как остановленный.
	void threadStop(PIThread * t);

	//! \~english Updates averaged run time of thread `t` in microseconds.
	//! \~russian Обновляет усредненное время выполнения потока `t` в микросекундах.
	void threadRunDone(PIThread * t, ullong us);

private:
	PIIntrospectionThreadsInterface();
	~PIIntrospectionThreadsInterface();

	PIIntrospectionThreads * p;
};

#else
#  define PIINTROSPECTION_THREAD_NEW(t)
#  define PIINTROSPECTION_THREAD_DELETE(t)
#  define PIINTROSPECTION_THREAD_START(t)
#  define PIINTROSPECTION_THREAD_RUN(t)
#  define PIINTROSPECTION_THREAD_WAIT(t)
#  define PIINTROSPECTION_THREAD_STOP(t)
#  define PIINTROSPECTION_THREAD_RUN_DONE(t, us)
#endif

#endif // PIINTROSPECTION_THREADS_H
