// Copyright 2019 The Marl Authors.
//
// Licensed 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
//
//     https://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.

#ifndef marl_thread_h
#define marl_thread_h

#include "containers.h"
#include "export.h"

#include <functional>

namespace marl {

// Thread provides an OS abstraction for threads of execution.
class Thread {
 public:
  using Func = std::function<void()>;

  // Core identifies a logical processor unit.
  // How a core is identified varies by platform.
  struct Core {
    struct Windows {
      uint8_t group;  // Group number
      uint8_t index;  // Core within the processor group
    };
    struct Pthread {
      uint16_t index;  // Core number
    };
    union {
      Windows windows;
      Pthread pthread;
    };

    // Comparison functions
    MARL_NO_EXPORT inline bool operator==(const Core&) const;
    MARL_NO_EXPORT inline bool operator<(const Core&) const;
  };

  // Affinity holds the affinity mask for a thread - a description of what cores
  // the thread is allowed to run on.
  struct Affinity {
    // supported is true if marl supports controlling thread affinity for this
    // platform.
#if defined(_WIN32) || (defined(__linux__) && !defined(__ANDROID__)) || \
    defined(__FreeBSD__)
    static constexpr bool supported = true;
#else
    static constexpr bool supported = false;
#endif

    // Policy is an interface that provides a get() method for returning an
    // Affinity for the given thread by id.
    class Policy {
     public:
      virtual ~Policy() {}

      // anyOf() returns a Policy that returns an Affinity for a number of
      // available cores in affinity.
      //
      // Windows requires that each thread is only associated with a
      // single affinity group, so the Policy's returned affinity will contain
      // cores all from the same group.
      MARL_EXPORT static std::shared_ptr<Policy> anyOf(
          Affinity&& affinity,
          Allocator* allocator = Allocator::Default);

      // oneOf() returns a Policy that returns an affinity with a single enabled
      // core from affinity. The single enabled core in the Policy's returned
      // affinity is:
      //      affinity[threadId % affinity.count()]
      MARL_EXPORT static std::shared_ptr<Policy> oneOf(
          Affinity&& affinity,
          Allocator* allocator = Allocator::Default);

      // get() returns the thread Affinity for the given thread by id.
      MARL_EXPORT virtual Affinity get(uint32_t threadId,
                                       Allocator* allocator) const = 0;
    };

    MARL_EXPORT Affinity(Allocator*);

    MARL_EXPORT Affinity(Affinity&&);

    MARL_EXPORT Affinity(const Affinity&, Allocator* allocator);

    // all() returns an Affinity with all the cores available to the process.
    MARL_EXPORT static Affinity all(Allocator* allocator = Allocator::Default);

    MARL_EXPORT Affinity(std::initializer_list<Core>, Allocator* allocator);

    MARL_EXPORT Affinity(const containers::vector<Core, 32>&,
                         Allocator* allocator);

    // count() returns the number of enabled cores in the affinity.
    MARL_EXPORT size_t count() const;

    // operator[] returns the i'th enabled core from this affinity.
    MARL_EXPORT Core operator[](size_t index) const;

    // add() adds the cores from the given affinity to this affinity.
    // This affinity is returned to allow for fluent calls.
    MARL_EXPORT Affinity& add(const Affinity&);

    // remove() removes the cores from the given affinity from this affinity.
    // This affinity is returned to allow for fluent calls.
    MARL_EXPORT Affinity& remove(const Affinity&);

   private:
    Affinity(const Affinity&) = delete;

    containers::vector<Core, 32> cores;
  };

  MARL_EXPORT Thread() = default;

  MARL_EXPORT Thread(Thread&&);

  MARL_EXPORT Thread& operator=(Thread&&);

  // Start a new thread using the given affinity that calls func.
  MARL_EXPORT Thread(Affinity&& affinity, Func&& func);

  MARL_EXPORT ~Thread();

  // join() blocks until the thread completes.
  MARL_EXPORT void join();

  // setName() sets the name of the currently executing thread for displaying
  // in a debugger.
  MARL_EXPORT static void setName(const char* fmt, ...);

  // numLogicalCPUs() returns the number of available logical CPU cores for
  // the system.
  MARL_EXPORT static unsigned int numLogicalCPUs();

 private:
  Thread(const Thread&) = delete;
  Thread& operator=(const Thread&) = delete;

  class Impl;
  Impl* impl = nullptr;
};

////////////////////////////////////////////////////////////////////////////////
// Thread::Core
////////////////////////////////////////////////////////////////////////////////
// Comparison functions
bool Thread::Core::operator==(const Core& other) const {
  return pthread.index == other.pthread.index;
}

bool Thread::Core::operator<(const Core& other) const {
  return pthread.index < other.pthread.index;
}

}  // namespace marl

#endif  // marl_thread_h
