/** @file

  Thread

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

  @section details Details

  Thread class provides the basic functionality for threads. Typically,
  there will be additional derived classes. Having a common base class
  for all threads is useful in many cases. I discuss below the use of
  Threads in the context of Event Subsystem. Hopefully this would be
  typical of other situations.

  EventProcessor needs to create a bunch of threads. It declares a
  class called EThread, derived from Thread. It is the responsibility of
  the EventProcessor to create and manage all the threads needed in the
  Event Subsystem (Note: we have removed the original ThreadManager class
  which used to create and manage *all* the threads in the system). By
  monitoring, we mean checking the heartbeat of each thread and the
  number of threads in the system etc.

  A derived class should either provide the function (and arguments)
  needed by the Thread class (see start()), or should define the virtual
  function execute().

  The Thread class maintains a thread_key which registers *all*
  the threads in the system (that have been created using Thread or
  a derived class), using thread specific data calls.  Whenever, you
  call this_thread() you get a pointer to the Thread that is currently
  executing you.  Additionally, the EThread class (derived from Thread)
  maintains its own independent key. All (and only) the threads created
  in the Event Subsystem are registered with this key. Thus, whenever you
  call this_ethread() you get a pointer to EThread. If you happen to call
  this_ethread() from inside a thread which is not an EThread, you will
  get a nullptr value (since that thread will not be  registered with the
  EThread key). This will hopefully make the use of this_ethread() safer.
  Note that an event created with EThread can also call this_thread(),
  in which case, it will get a pointer to Thread (rather than to EThread).

 */

#pragma once

#if !defined(_I_EventSystem_h) && !defined(_P_EventSystem_h)
#error "include I_EventSystem.h or P_EventSystem.h"
#endif

#include <functional>

#include "tscore/ink_platform.h"
#include "tscore/ink_thread.h"
#include "I_ProxyAllocator.h"

class ProxyMutex;

constexpr int MAX_THREAD_NAME_LENGTH = 16;

/// The signature of a function to be called by a thread.
using ThreadFunction = std::function<void()>;

/**
  Base class for the threads in the Event System. Thread is the base
  class for all the thread classes in the Event System. Objects of the
  Thread class represent spawned or running threads and provide minimal
  information for its derived classes. Thread objects have a reference
  to a ProxyMutex, that is used for atomic operations internally, and
  an ink_thread member that is used to identify the thread in the system.

  You should not create an object of the Thread class, they are typically
  instantiated after some thread startup mechanism exposed by a processor,
  but even then you would probably deal with processor functions and
  not the Thread object itself.

*/
class Thread
{
public:
  /**
    System-wide thread identifier. The thread identifier is represented
    by the platform independent type ink_thread and it is the system-wide
    value assigned to each thread. It is exposed as a convenience for
    processors and you should not modify it directly.

  */
  // NOLINTNEXTLINE(modernize-use-nullptr)
  ink_thread tid = 0;

  /**
    Thread lock to ensure atomic operations. The thread lock available
    to derived classes to ensure atomic operations and protect critical
    regions. Do not modify this member directly.

  */
  Ptr<ProxyMutex> mutex;

  void set_specific();

  inkcoreapi static ink_thread_key thread_data_key;

  // For THREAD_ALLOC
  ProxyAllocator eventAllocator;
  ProxyAllocator netVCAllocator;
  ProxyAllocator sslNetVCAllocator;
  ProxyAllocator quicNetVCAllocator;
  ProxyAllocator http1ClientSessionAllocator;
  ProxyAllocator http2ClientSessionAllocator;
  ProxyAllocator http2StreamAllocator;
  ProxyAllocator quicClientSessionAllocator;
  ProxyAllocator quicBidiStreamAllocator;
  ProxyAllocator quicSendStreamAllocator;
  ProxyAllocator quicReceiveStreamAllocator;
  ProxyAllocator httpServerSessionAllocator;
  ProxyAllocator hdrHeapAllocator;
  ProxyAllocator strHeapAllocator;
  ProxyAllocator cacheVConnectionAllocator;
  ProxyAllocator openDirEntryAllocator;
  ProxyAllocator ramCacheCLFUSEntryAllocator;
  ProxyAllocator ramCacheLRUEntryAllocator;
  ProxyAllocator evacuationBlockAllocator;
  ProxyAllocator ioDataAllocator;
  ProxyAllocator ioAllocator;
  ProxyAllocator ioBlockAllocator;

  /** Start the underlying thread.

      The thread name is set to @a name. The stack for the thread is either @a stack or, if that is
      @c nullptr a stack of size @a stacksize is allocated and used. If @a f is present and valid it
      is called in the thread context. Otherwise the method @c execute is invoked.
  */
  void start(const char *name, void *stack, size_t stacksize, ThreadFunction const &f = ThreadFunction());

  virtual void execute() = 0;

  /** Get the current ATS high resolution time.
      This gets a cached copy of the time so it is very fast and reasonably accurate.
      The cached time is updated every time the actual operating system time is fetched which is
      at least every 10ms and generally more frequently.
      @note The cached copy shared among threads which means the cached copy is updated
      for all threads if any thread updates it.
  */
  static ink_hrtime get_hrtime();

  /** Get the operating system high resolution time.

      Get the current time at high resolution from the operating system.  This is more expensive
      than @c get_hrtime and should be used only where very precise timing is required.

      @note This also updates the cached time.
  */
  static ink_hrtime get_hrtime_updated();

  Thread(const Thread &) = delete;
  Thread &operator=(const Thread &) = delete;
  virtual ~Thread();

protected:
  Thread();

  static ink_hrtime cur_time;
};

extern Thread *this_thread();

TS_INLINE ink_hrtime
Thread::get_hrtime()
{
  return cur_time;
}

TS_INLINE ink_hrtime
Thread::get_hrtime_updated()
{
  return cur_time = ink_get_hrtime_internal();
}
