// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// 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
//
//     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.

#include "starboard/shared/pthread/thread_sampler_internal.h"

#if SB_API_VERSION >= 11

#include <semaphore.h>
#include <signal.h>

#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/shared/pthread/thread_context_internal.h"
#include "starboard/thread.h"

namespace {

class SignalHandler {
 public:
  static void AddSampler() {
    starboard::ScopedLock lock(GetMutex());
    if (++sampler_count_ == 1) {
      Install();
    }
  }

  static void RemoveSampler() {
    starboard::ScopedLock lock(GetMutex());
    if (--sampler_count_ == 0) {
      Restore();
    }
  }

  static SbThreadContext Freeze(SbThreadSampler sampler);
  static bool Thaw(SbThreadSampler sampler);

 private:
  // Getter with static local to lazily initialize the mutex once.
  static const starboard::Mutex& GetMutex() {
    static starboard::Mutex mutex;
    return mutex;
  }

  static void Install() {
    sem_init(&freeze_semaphore_, 0, 0);
    sem_init(&thaw_semaphore_, 0, 0);
    struct sigaction sa;
    sa.sa_sigaction = &HandleProfilerSignal;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_SIGINFO;
    signal_handler_installed_ =
        (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
  }

  static void Restore() {
    if (signal_handler_installed_) {
      sigaction(SIGPROF, &old_signal_handler_, 0);
      signal_handler_installed_ = false;
    }
    sem_destroy(&freeze_semaphore_);
    sem_destroy(&thaw_semaphore_);
  }

  static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);

  static int sampler_count_;
  static bool signal_handler_installed_;
  static struct sigaction old_signal_handler_;
  static SbThreadContextPrivate sb_context_;
  static SbThreadSampler frozen_sampler_;
  // POSIX semaphore can be used in signal handler. Other synchronization,
  // including mutex, condition variable and Starboard's semaphore can't.
  static sem_t freeze_semaphore_;
  static sem_t thaw_semaphore_;
};

int SignalHandler::sampler_count_ = 0;
bool SignalHandler::signal_handler_installed_ = false;
struct sigaction SignalHandler::old_signal_handler_;
SbThreadContextPrivate SignalHandler::sb_context_;
SbThreadSampler SignalHandler::frozen_sampler_ = kSbThreadSamplerInvalid;
sem_t SignalHandler::freeze_semaphore_;
sem_t SignalHandler::thaw_semaphore_;

SbThreadContext SignalHandler::Freeze(SbThreadSampler sampler) {
  starboard::ScopedLock lock(GetMutex());
  SB_DCHECK(frozen_sampler_ != sampler) << "SbThreadSampler frozen twice.";
  if (!signal_handler_installed_ || SbThreadSamplerIsValid(frozen_sampler_)) {
    return kSbThreadContextInvalid;
  }
  frozen_sampler_ = sampler;
  pthread_kill(sampler->thread(), SIGPROF);
  sem_wait(&freeze_semaphore_);
  return &sb_context_;
}

bool SignalHandler::Thaw(SbThreadSampler sampler) {
  starboard::ScopedLock lock(GetMutex());
  SB_DCHECK(frozen_sampler_ == sampler) << "SbThreadSampler didn't freeze.";
  if (frozen_sampler_ != sampler) return false;
  sb_context_.ucontext = nullptr;
  sem_post(&thaw_semaphore_);
  frozen_sampler_ = kSbThreadSamplerInvalid;
  return true;
}

void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
                                         void* context) {
  SB_UNREFERENCED_PARAMETER(info);
  if (signal != SIGPROF) return;
  sb_context_.ucontext = reinterpret_cast<ucontext_t*>(context);
  // |Freeze| can return the context now.
  sem_post(&freeze_semaphore_);
  // Keep this thread frozen until |Thaw| is called.
  sem_wait(&thaw_semaphore_);
}

}  // namespace

SbThreadSamplerPrivate::SbThreadSamplerPrivate(SbThread thread)
    : thread_(thread) {
  SignalHandler::AddSampler();
}

SbThreadSamplerPrivate::~SbThreadSamplerPrivate() {
  SignalHandler::RemoveSampler();
}

SbThreadContext SbThreadSamplerPrivate::Freeze() {
  return SignalHandler::Freeze(this);
}

bool SbThreadSamplerPrivate::Thaw() { return SignalHandler::Thaw(this); }

#endif  // SB_API_VERSION >= 11
